From feef3bda0e5f140ceab7f0fbdde63046a044b89d Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Mon, 16 Dec 2024 13:58:24 -0700 Subject: [PATCH 001/168] Implemented CdotGisConnector --- .../library/helpers/CdotGisConnector.java | 48 +++++++++++ .../library/helpers/CdotGisConnectorTest.java | 81 +++++++++++++++++++ 2 files changed, 129 insertions(+) create mode 100644 cv-data-service-library/src/main/java/com/trihydro/library/helpers/CdotGisConnector.java create mode 100644 cv-data-service-library/src/test/java/com/trihydro/library/helpers/CdotGisConnectorTest.java diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CdotGisConnector.java b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CdotGisConnector.java new file mode 100644 index 000000000..1950426eb --- /dev/null +++ b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CdotGisConnector.java @@ -0,0 +1,48 @@ +package com.trihydro.library.helpers; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; + +import com.trihydro.library.service.RestTemplateProvider; +import org.springframework.stereotype.Component; + +@Component +public class CdotGisConnector { + private final String baseUrl = "https://dtdapps.coloradodot.info/arcgis/rest/services/LRS/Routes/MapServer/exts/CdotLrsAccessRounded"; + + private RestTemplateProvider restTemplateProvider; + + @Autowired + public void InjectDependencies(RestTemplateProvider _restTemplateProvider) { + this.restTemplateProvider = _restTemplateProvider; + } + + public String getBaseUrl() { + return baseUrl; + } + + public RestTemplateProvider getRestTemplateProvider() { + return restTemplateProvider; + } + + public ResponseEntity getAllRoutes() { + String targetUrl = baseUrl + "/Routes"; + String params = "?f=json"; + HttpHeaders headers = new HttpHeaders(); + headers.set("Accept", "application/json"); + HttpEntity entity = new HttpEntity<>(headers); + return restTemplateProvider.GetRestTemplate().exchange(targetUrl + params, HttpMethod.GET, entity, String.class); + } + + public ResponseEntity getRouteById(String routeId) { + String targetUrl = baseUrl + "/Route"; + String params = "?routeId=" + routeId + "&outSR=4326&f=json"; + HttpHeaders headers = new HttpHeaders(); + headers.set("Accept", "application/json"); + HttpEntity entity = new HttpEntity<>(headers); + return restTemplateProvider.GetRestTemplate().exchange(targetUrl + params, HttpMethod.GET, entity, String.class); + } +} diff --git a/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CdotGisConnectorTest.java b/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CdotGisConnectorTest.java new file mode 100644 index 000000000..e02e9e288 --- /dev/null +++ b/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CdotGisConnectorTest.java @@ -0,0 +1,81 @@ +package com.trihydro.library.helpers; + +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; + +import com.trihydro.library.service.BaseServiceTest; + +class CdotGisConnectorTest extends BaseServiceTest { + + @InjectMocks + private CdotGisConnector uut; + + private final String expectedBaseUrl = "https://dtdapps.coloradodot.info/arcgis/rest/services/LRS/Routes/MapServer/exts/CdotLrsAccessRounded"; + + @Test + void testInitialization() { + Assertions.assertNotNull(uut); + Assertions.assertEquals(expectedBaseUrl, uut.getBaseUrl()); + Assertions.assertNotNull(uut.getRestTemplateProvider()); + } + + @Test + void testGetBaseUrl() { + Assertions.assertEquals("https://dtdapps.coloradodot.info/arcgis/rest/services/LRS/Routes/MapServer/exts/CdotLrsAccessRounded", uut.getBaseUrl()); + } + + @Test + void testGetAllRoutes() { + // prepare + String expectedTargetUrl = expectedBaseUrl + "/Routes"; + String f = "json"; + String expectedParams = "?f=" + f; + HttpHeaders mockHeaders = new HttpHeaders(); + mockHeaders.set("Accept", "application/json"); + HttpEntity mockEntity = new HttpEntity<>(mockHeaders); + String mockResponseString = "mockResponseString"; + ResponseEntity mockResponse = ResponseEntity.ok(mockResponseString); + when(mockRestTemplate.exchange(expectedTargetUrl + expectedParams, HttpMethod.GET, mockEntity, String.class)).thenReturn(mockResponse); + + // execute + ResponseEntity response = uut.getAllRoutes(); + + // verify + Assertions.assertEquals(mockResponse.getStatusCode(), response.getStatusCode()); + Assertions.assertEquals(mockResponseString, response.getBody()); + verify(mockRestTemplate).exchange(expectedTargetUrl + expectedParams, HttpMethod.GET, mockEntity, String.class); + } + + @Test + void testGetRouteById() { + // prepare + String expectedTargetUrl = expectedBaseUrl + "/Route"; + String routeId = "025A"; + int outSR = 4326; + String f = "json"; + String expectedParams = "?routeId=" + routeId + "&outSR=" + outSR + "&f=" + f; + HttpHeaders mockHeaders = new HttpHeaders(); + mockHeaders.set("Accept", "application/json"); + HttpEntity mockEntity = new HttpEntity<>(mockHeaders); + String mockResponseString = "mockResponseString"; + ResponseEntity mockResponse = ResponseEntity.ok(mockResponseString); + when(mockRestTemplate.exchange(expectedTargetUrl + expectedParams, HttpMethod.GET, mockEntity, String.class)).thenReturn(mockResponse); + + // execute + ResponseEntity response = uut.getRouteById(routeId); + + // verify + Assertions.assertEquals(mockResponse.getStatusCode(), response.getStatusCode()); + Assertions.assertEquals(mockResponseString, response.getBody()); + verify(mockRestTemplate).exchange(expectedTargetUrl + expectedParams, HttpMethod.GET, mockEntity, String.class); + } + +} \ No newline at end of file From 58668ce0b5d3807717c7d16a17a0359759affd40 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Mon, 16 Dec 2024 13:58:43 -0700 Subject: [PATCH 002/168] Implemented CdotUpstreamPathController --- .../CdotUpstreamPathController.java | 216 +++++++++++++ .../model/DataControllerConfigProperties.java | 13 +- .../CdotUpstreamPathControllerTest.java | 296 ++++++++++++++++++ ...tRouteResponseForI25_First30Mileposts.json | 90 ++++++ 4 files changed, 610 insertions(+), 5 deletions(-) create mode 100644 cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java create mode 100644 cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathControllerTest.java create mode 100644 cv-data-controller/src/test/resources/com/trihydro/cvdatacontroller/controller/cdotRouteResponseForI25_First30Mileposts.json diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java new file mode 100644 index 000000000..769a4c70d --- /dev/null +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java @@ -0,0 +1,216 @@ +package com.trihydro.cvdatacontroller.controller; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +import com.trihydro.library.helpers.CdotGisConnector; +import com.trihydro.library.helpers.Utility; +import com.trihydro.library.model.Milepost; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +import springfox.documentation.annotations.ApiIgnore; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +@CrossOrigin +@RestController +@ApiIgnore +@RequestMapping("cdot-upstream-path") +public class CdotUpstreamPathController extends BaseController { + private CdotGisConnector cdotGisService; + private Utility utility; + + @Autowired + public void InjectDependencies(CdotGisConnector cdotGisService, Utility utility) { + this.cdotGisService = cdotGisService; + this.utility = utility; + } + + @RequestMapping(value = "/get-buffer-for-path/{routeId}/{desiredDistanceInMiles:.+}", method = RequestMethod.POST) + public ResponseEntity> getBufferForPath(@RequestBody List pathMileposts, @PathVariable String routeId, @PathVariable double desiredDistanceInMiles) throws JsonMappingException, JsonProcessingException { + utility.logWithDate("Number of mileposts in path in request body: " + pathMileposts.size(), this.getClass()); + for (Milepost milepost : pathMileposts) { + utility.logWithDate("Milepost in path: " + milepost.getLatitude() + ", " + milepost.getLongitude(), this.getClass()); + } + List allMileposts = getMilepostsForRoute(routeId); + if (allMileposts == null || allMileposts.isEmpty()) { + utility.logWithDate("No mileposts found for route", this.getClass()); + return ResponseEntity.badRequest().body(null); + } + utility.logWithDate("Number of mileposts in route: " + allMileposts.size(), this.getClass()); + PathDirection direction = getPathDirection(pathMileposts, allMileposts); + if (direction == null) { + utility.logWithDate("Invalid path direction", this.getClass()); + return ResponseEntity.badRequest().body(null); + } + Milepost firstMilepostInPath = pathMileposts.get(0); + int startIndex = getIndexOfMilepost(allMileposts, firstMilepostInPath); + + List buffer = new ArrayList(); + double distanceInMiles = 0; + if (direction == PathDirection.ASCENDING) { + utility.logWithDate("Path direction is ascending. Start index: " + startIndex, this.getClass()); + buffer.add(allMileposts.get(startIndex)); + // add mileposts in descending order + for (int i = startIndex - 1; i >= 0; i--) { + distanceInMiles = DistanceCalculator.calculateDistanceInMiles(buffer); + if (distanceInMiles >= desiredDistanceInMiles) { + break; + } + buffer.add(allMileposts.get(i)); + } + } else { + utility.logWithDate("Path direction is descending. Start index: " + startIndex, this.getClass()); + // add mileposts in ascending order + for (int i = startIndex + 1; i < allMileposts.size(); i++) { + distanceInMiles = DistanceCalculator.calculateDistanceInMiles(buffer); + if (distanceInMiles >= desiredDistanceInMiles) { + break; + } + buffer.add(allMileposts.get(i)); + } + } + if (buffer.size() < 2) { + // at least 2 mileposts are needed to create a valid buffer path + utility.logWithDate("Buffer path has less than 2 mileposts", this.getClass()); + return ResponseEntity.badRequest().body(null); + } + if (distanceInMiles < desiredDistanceInMiles) { + utility.logWithDate("Buffer path has less distance than desired distance", this.getClass()); + return ResponseEntity.badRequest().body(null); + } + utility.logWithDate("Distance of buffer path: " + distanceInMiles + " miles", this.getClass()); + String geojsonString = convertMilepostsToGeojsonString(buffer); + utility.logWithDate("Geojson string for buffer: " + geojsonString, this.getClass()); + return ResponseEntity.ok(buffer); + } + + @SuppressWarnings("deprecation") + public List getMilepostsForRoute(String routeId) throws JsonMappingException, JsonProcessingException { + ResponseEntity response = cdotGisService.getRouteById(routeId); + String routeJsonString = response.getBody(); + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode rootNode = objectMapper.readTree(routeJsonString); + JsonNode pathNode = rootNode.path("features").get(0).path("geometry").path("paths").get(0); + List mileposts = new ArrayList(); + for (JsonNode node : pathNode) { + Milepost milepost = new Milepost(); + milepost.setCommonName(routeId); + BigDecimal latitude = new BigDecimal(node.get(1).asText()).setScale(14, BigDecimal.ROUND_HALF_UP); + BigDecimal longitude = new BigDecimal(node.get(0).asText()).setScale(14, BigDecimal.ROUND_HALF_UP); + milepost.setLatitude(latitude); + milepost.setLongitude(longitude); + mileposts.add(milepost); + } + return mileposts; + } + + public PathDirection getPathDirection(List pathMileposts, List allMileposts) { + if (pathMileposts.size() < 2) { + utility.logWithDate("Path has less than 2 mileposts", this.getClass()); + return null; + } + Milepost firstMilepostInPath = pathMileposts.get(0); + Milepost secondMilepostInPath = pathMileposts.get(1); + int firstMilepostInPathIndex = getIndexOfMilepost(allMileposts, firstMilepostInPath); + if (firstMilepostInPathIndex == -1) { + utility.logWithDate("First milepost not found in route", this.getClass()); + return null; + } + int secondMilepostInPathIndex = getIndexOfMilepost(allMileposts, secondMilepostInPath); + if (secondMilepostInPathIndex == -1) { + utility.logWithDate("Second milepost not found in route", this.getClass()); + return null; + } + if (firstMilepostInPathIndex < secondMilepostInPathIndex) { + return PathDirection.ASCENDING; + } else { + return PathDirection.DESCENDING; + } + } + + private int getIndexOfMilepost(List mileposts, Milepost milepost) { + if (milepost.getLatitude() == null || milepost.getLongitude() == null) { + utility.logWithDate("Milepost has null latitude or longitude", this.getClass()); + return -1; + } + BigDecimal latitude = milepost.getLatitude().setScale(14, BigDecimal.ROUND_HALF_UP); + BigDecimal longitude = milepost.getLongitude().setScale(14, BigDecimal.ROUND_HALF_UP); + for (int i = 0; i < mileposts.size(); i++) { + Milepost currentMilepost = mileposts.get(i); + BigDecimal currentLatitude = currentMilepost.getLatitude().setScale(14, BigDecimal.ROUND_HALF_UP); + BigDecimal currentLongitude = currentMilepost.getLongitude().setScale(14, BigDecimal.ROUND_HALF_UP); + if (latitude.equals(currentLatitude) && longitude.equals(currentLongitude)) { + return i; + } + } + return -1; + } + + private String convertMilepostsToGeojsonString(List mileposts) { + StringBuilder geojsonStringBuilder = new StringBuilder(); + geojsonStringBuilder.append("{ \"type\": \"FeatureCollection\", \"features\": [{ \"type\": \"Feature\", \"geometry\": { \"type\": \"LineString\", \"coordinates\": ["); + for (int i = 0; i < mileposts.size(); i++) { + Milepost milepost = mileposts.get(i); + geojsonStringBuilder.append("["); + geojsonStringBuilder.append(milepost.getLongitude().toString()); + geojsonStringBuilder.append(", "); + geojsonStringBuilder.append(milepost.getLatitude().toString()); + geojsonStringBuilder.append("]"); + if (i < mileposts.size() - 1) { + geojsonStringBuilder.append(", "); + } + } + geojsonStringBuilder.append("] }, \"properties\": { \"commonName\": \""); + geojsonStringBuilder.append(mileposts.get(0).getCommonName()); + geojsonStringBuilder.append("\" } }] }"); + return geojsonStringBuilder.toString(); + } + + // define path direction enum (ASCENDING, DESCENDING) + public enum PathDirection { + ASCENDING, + DESCENDING + } + + /** + * Helper class to calculate distance between two points and total distance of a buffer path + */ + public static class DistanceCalculator { + public static double calculateDistanceInMiles(List buffer) { + double distanceInMiles = 0; + for (int i = 0; i < buffer.size() - 1; i++) { + Milepost mp1 = buffer.get(i); + Milepost mp2 = buffer.get(i + 1); + double distanceInMeters = DistanceCalculator.calculateDistanceInMetersBetweenTwoPoints(mp1.getLatitude().doubleValue(), + mp1.getLongitude().doubleValue(), mp2.getLatitude().doubleValue(), mp2.getLongitude().doubleValue()); + distanceInMiles += distanceInMeters / 1609.34; + } + return distanceInMiles; + } + + public static double calculateDistanceInMetersBetweenTwoPoints(double lat1, double lon1, double lat2, double lon2) { + final int R = 6371000; // Radius of the earth in meters + double latDistance = Math.toRadians(lat2 - lat1); + double lonDistance = Math.toRadians(lon2 - lon1); + double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2) + + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) + * Math.sin(lonDistance / 2) * Math.sin(lonDistance / 2); + double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); + return R * c; // Distance in meters + } + } + +} \ No newline at end of file diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/model/DataControllerConfigProperties.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/model/DataControllerConfigProperties.java index 10eca26b1..7dbc5278a 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/model/DataControllerConfigProperties.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/model/DataControllerConfigProperties.java @@ -1,9 +1,6 @@ package com.trihydro.cvdatacontroller.model; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Import; -import org.springframework.stereotype.Component; - +import com.trihydro.library.helpers.CdotGisConnector; import com.trihydro.library.helpers.DbInteractions; import com.trihydro.library.helpers.EmailHelper; import com.trihydro.library.helpers.JavaMailSenderImplProvider; @@ -11,13 +8,19 @@ import com.trihydro.library.helpers.Utility; import com.trihydro.library.model.DbInteractionsProps; import com.trihydro.library.model.EmailProps; +import com.trihydro.library.service.RestTemplateProvider; import com.trihydro.library.tables.LoggingTables; import com.trihydro.library.tables.TimDbTables; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Import; +import org.springframework.stereotype.Component; + @Component @ConfigurationProperties("config") @Import({ TimDbTables.class, SQLNullHandler.class, Utility.class, EmailHelper.class, - JavaMailSenderImplProvider.class, LoggingTables.class, DbInteractions.class }) + JavaMailSenderImplProvider.class, LoggingTables.class, DbInteractions.class, + CdotGisConnector.class, RestTemplateProvider.class }) public class DataControllerConfigProperties implements DbInteractionsProps, EmailProps { private String dbUrl; private String dbUsername; diff --git a/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathControllerTest.java b/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathControllerTest.java new file mode 100644 index 000000000..9c366ff1b --- /dev/null +++ b/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathControllerTest.java @@ -0,0 +1,296 @@ +package com.trihydro.cvdatacontroller.controller; + +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.math.BigDecimal; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.trihydro.cvdatacontroller.controller.CdotUpstreamPathController.DistanceCalculator; +import com.trihydro.cvdatacontroller.controller.CdotUpstreamPathController.PathDirection; +import com.trihydro.library.helpers.CdotGisConnector; +import com.trihydro.library.helpers.Utility; +import com.trihydro.library.model.Milepost; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +class CdotUpstreamPathControllerTest extends TestBase { + private final String ROUTE_ID = "025A"; // I-25 + private final String PATH_TO_ROUTE_JSON_TEST_DATA = "src/test/resources/com/trihydro/cvdatacontroller/controller/cdotRouteResponseForI25_First30Mileposts.json"; + + @Mock + CdotGisConnector cdotGisService; + + @Mock + Utility utility; + + @SuppressWarnings("deprecation") + List getMockMileposts() throws IOException { + String routeJsonString = new String(Files.readAllBytes(Paths.get(PATH_TO_ROUTE_JSON_TEST_DATA))); + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode rootNode = objectMapper.readTree(routeJsonString); + JsonNode pathNode = rootNode.path("features").get(0).path("geometry").path("paths").get(0); + List mileposts = new ArrayList(); + for (JsonNode node : pathNode) { + Milepost milepost = new Milepost(); + milepost.setCommonName(ROUTE_ID); + BigDecimal latitude = new BigDecimal(node.get(1).asText()).setScale(14, BigDecimal.ROUND_HALF_UP); + BigDecimal longitude = new BigDecimal(node.get(0).asText()).setScale(14, BigDecimal.ROUND_HALF_UP); + milepost.setLatitude(latitude); + milepost.setLongitude(longitude); + mileposts.add(milepost); + } + return mileposts; + } + + @BeforeEach + void setUp() { + uut = new CdotUpstreamPathController(); + uut.InjectDependencies(cdotGisService, utility); + } + + @Test + void testInitialization() { + Assertions.assertNotNull(uut); + } + + @Test + void testGetMilepostsForRoute() throws IOException { + // prepare + String routeJsonString = new String(Files.readAllBytes(Paths.get(PATH_TO_ROUTE_JSON_TEST_DATA))); + ResponseEntity mockResponse = new ResponseEntity(routeJsonString, HttpStatus.OK); + when(cdotGisService.getRouteById(ROUTE_ID)).thenReturn(mockResponse); + List expectedMileposts = getMockMileposts(); + + // execute + List mileposts = uut.getMilepostsForRoute(ROUTE_ID); + + // verify + verify(cdotGisService).getRouteById(ROUTE_ID); + Assertions.assertEquals(expectedMileposts.size(), mileposts.size()); + for (int i = 0; i < expectedMileposts.size(); i++) { + Milepost expected = expectedMileposts.get(i); + Milepost actual = mileposts.get(i); + Assertions.assertEquals(expected.getCommonName(), actual.getCommonName()); + Assertions.assertNull(actual.getMilepost()); + Assertions.assertNull(actual.getDirection()); + Assertions.assertEquals(expected.getLatitude(), actual.getLatitude()); + Assertions.assertEquals(expected.getLongitude(), actual.getLongitude()); + } + } + + @Test + void testGetPathDirection_ASCENDING() throws IOException { + // prepare + List allMileposts = getMockMileposts(); + Milepost mp1 = allMileposts.get(0); + Milepost mp2 = allMileposts.get(1); + List pathMileposts = List.of(mp1, mp2); + + // execute + PathDirection direction = uut.getPathDirection(pathMileposts, allMileposts); + + // verify + Assertions.assertEquals(PathDirection.ASCENDING, direction); + } + + @Test + void testGetPathDirection_DESCENDING() throws IOException { + // prepare + List allMileposts = getMockMileposts(); + Milepost mp1 = allMileposts.get(1); + Milepost mp2 = allMileposts.get(0); + List pathMileposts = List.of(mp1, mp2); + + // execute + PathDirection direction = uut.getPathDirection(pathMileposts, allMileposts); + + // verify + Assertions.assertEquals(PathDirection.DESCENDING, direction); + } + + @Test + void testGetPathDirection_NOT_ENOUGH_MILEPOSTS() throws IOException { + // prepare + List allMileposts = getMockMileposts(); + Milepost mp1 = allMileposts.get(0); + List pathMileposts = List.of(mp1); + + // execute + PathDirection direction = uut.getPathDirection(pathMileposts, allMileposts); + + // verify + Assertions.assertNull(direction); + } + + @SuppressWarnings("deprecation") + @Test + void testGetPathDirection_FirstMilepostOfPathNotInAllMileposts() throws IOException { + // prepare + List allMileposts = getMockMileposts(); + Milepost mp1 = new Milepost(); + mp1.setCommonName(ROUTE_ID); + mp1.setLatitude(new BigDecimal("30.12").setScale(14, BigDecimal.ROUND_HALF_UP)); + mp1.setLongitude(new BigDecimal("-100.34").setScale(14, BigDecimal.ROUND_HALF_UP)); + Milepost mp2 = allMileposts.get(1); + List pathMileposts = List.of(mp1, mp2); + + // execute + PathDirection direction = uut.getPathDirection(pathMileposts, allMileposts); + + // verify + Assertions.assertNull(direction); + } + + @SuppressWarnings("deprecation") + @Test + void testGetPathDirection_SecondMilepostOfPathNotInAllMileposts() throws IOException { + // prepare + List allMileposts = getMockMileposts(); + Milepost mp1 = allMileposts.get(0); + Milepost mp2 = new Milepost(); + mp2.setCommonName(ROUTE_ID); + mp1.setLatitude(new BigDecimal("30.12").setScale(14, BigDecimal.ROUND_HALF_UP)); + mp1.setLongitude(new BigDecimal("-100.34").setScale(14, BigDecimal.ROUND_HALF_UP)); + List pathMileposts = List.of(mp1, mp2); + + // execute + PathDirection direction = uut.getPathDirection(pathMileposts, allMileposts); + + // verify + Assertions.assertNull(direction); + } + + @Test + void testGetBufferForPath_Ascending_Success() throws IOException { + // prepare + String routeJsonString = new String(Files.readAllBytes(Paths.get(PATH_TO_ROUTE_JSON_TEST_DATA))); + ResponseEntity mockResponse = new ResponseEntity(routeJsonString, HttpStatus.OK); + when(cdotGisService.getRouteById(ROUTE_ID)).thenReturn(mockResponse); + + List allMileposts = getMockMileposts(); + Milepost mp1 = allMileposts.get(20); + Milepost mp2 = allMileposts.get(21); + List pathMileposts = List.of(mp1, mp2); + + double desiredDistanceInMiles = 0.5; + + // execute + ResponseEntity> response = uut.getBufferForPath(pathMileposts, ROUTE_ID, desiredDistanceInMiles); + + // verify + List buffer = response.getBody(); + assert buffer != null; + Assertions.assertFalse(buffer.isEmpty()); + double distanceInMiles = getDistanceInMiles(buffer); + Assertions.assertTrue(distanceInMiles >= desiredDistanceInMiles); // buffer should be at least as long as desired distance + Assertions.assertTrue(distanceInMiles <= desiredDistanceInMiles + 1); // buffer should not be much longer than desired distance + } + + @Test + void testGetBufferForPath_Ascending_Failure_EndOfAllMilepostsReached() throws IOException { + // prepare + String routeJsonString = new String(Files.readAllBytes(Paths.get(PATH_TO_ROUTE_JSON_TEST_DATA))); + ResponseEntity mockResponse = new ResponseEntity(routeJsonString, HttpStatus.OK); + when(cdotGisService.getRouteById(ROUTE_ID)).thenReturn(mockResponse); + + List allMileposts = getMockMileposts(); + Milepost mp1 = allMileposts.get(1); + Milepost mp2 = allMileposts.get(2); + List pathMileposts = List.of(mp1, mp2); + + double desiredDistanceInMiles = 5.0; + + // execute + ResponseEntity> response = uut.getBufferForPath(pathMileposts, ROUTE_ID, desiredDistanceInMiles); + + // verify + List buffer = response.getBody(); + Assertions.assertNull(buffer); + } + + @Test + void testGetBufferForPath_Descending_Success() throws IOException { + // prepare + String routeJsonString = new String(Files.readAllBytes(Paths.get(PATH_TO_ROUTE_JSON_TEST_DATA))); + ResponseEntity mockResponse = new ResponseEntity(routeJsonString, HttpStatus.OK); + when(cdotGisService.getRouteById(ROUTE_ID)).thenReturn(mockResponse); + + List allMileposts = getMockMileposts(); + Milepost mp1 = allMileposts.get(1); + Milepost mp2 = allMileposts.get(0); + List pathMileposts = List.of(mp1, mp2); + + double desiredDistanceInMiles = 0.5; + + // execute + ResponseEntity> response = uut.getBufferForPath(pathMileposts, ROUTE_ID, desiredDistanceInMiles); + + // verify + List buffer = response.getBody(); + assert buffer != null; + Assertions.assertFalse(buffer.isEmpty()); + double distanceInMiles = getDistanceInMiles(buffer); + Assertions.assertTrue(distanceInMiles >= desiredDistanceInMiles); // buffer should be at least as long as desired distance + Assertions.assertTrue(distanceInMiles <= desiredDistanceInMiles + 1); // buffer should not be much longer than desired distance + } + + @Test + void testGetBufferForPath_Descending_Failure_EndOfAllMilepostsReached() throws IOException { + // prepare + String routeJsonString = new String(Files.readAllBytes(Paths.get(PATH_TO_ROUTE_JSON_TEST_DATA))); + ResponseEntity mockResponse = new ResponseEntity(routeJsonString, HttpStatus.OK); + when(cdotGisService.getRouteById(ROUTE_ID)).thenReturn(mockResponse); + + List allMileposts = getMockMileposts(); + Milepost mp1 = allMileposts.get(28); + Milepost mp2 = allMileposts.get(27); + List pathMileposts = List.of(mp1, mp2); + + double desiredDistanceInMiles = 5.0; + + // execute + ResponseEntity> response = uut.getBufferForPath(pathMileposts, ROUTE_ID, desiredDistanceInMiles); + + // verify + List buffer = response.getBody(); + Assertions.assertNull(buffer); + } + + @Test + void testGetBufferForPath_PathDirectionIsNull() throws IOException { + // prepare + String routeJsonString = new String(Files.readAllBytes(Paths.get(PATH_TO_ROUTE_JSON_TEST_DATA))); + ResponseEntity mockResponse = new ResponseEntity(routeJsonString, HttpStatus.OK); + when(cdotGisService.getRouteById(ROUTE_ID)).thenReturn(mockResponse); + + List allMileposts = getMockMileposts(); + Milepost mp1 = allMileposts.get(0); + List pathMileposts = List.of(mp1); + + int desiredDistanceInMiles = 5; + + // execute + ResponseEntity> response = uut.getBufferForPath(pathMileposts, ROUTE_ID, desiredDistanceInMiles); + + // verify + List buffer = response.getBody(); + Assertions.assertNull(buffer); + } + + private double getDistanceInMiles(List buffer) { + return DistanceCalculator.calculateDistanceInMiles(buffer); + } + +} \ No newline at end of file diff --git a/cv-data-controller/src/test/resources/com/trihydro/cvdatacontroller/controller/cdotRouteResponseForI25_First30Mileposts.json b/cv-data-controller/src/test/resources/com/trihydro/cvdatacontroller/controller/cdotRouteResponseForI25_First30Mileposts.json new file mode 100644 index 000000000..e8b2167b6 --- /dev/null +++ b/cv-data-controller/src/test/resources/com/trihydro/cvdatacontroller/controller/cdotRouteResponseForI25_First30Mileposts.json @@ -0,0 +1,90 @@ +{ + "displayFieldName": "", + "fieldAliases": { + "OBJECTID": "OBJECTID", + "Route": "Route", + "MMin": "MMin", + "MMax": "MMax", + "SHAPE_Length": "SHAPE_Length" + }, + "geometryType": "esriGeometryPolyline", + "spatialReference": { + "wkid": 4326, + "latestWkid": 4326 + }, + "fields": [ + { + "name": "OBJECTID", + "type": "esriFieldTypeOID", + "alias": "OBJECTID" + }, + { + "name": "Route", + "type": "esriFieldTypeString", + "alias": "Route", + "length": 90 + }, + { + "name": "MMin", + "type": "esriFieldTypeDouble", + "alias": "MMin" + }, + { + "name": "MMax", + "type": "esriFieldTypeDouble", + "alias": "MMax" + }, + { + "name": "SHAPE_Length", + "type": "esriFieldTypeDouble", + "alias": "SHAPE_Length" + } + ], + "features": [ + { + "attributes": { + "OBJECTID": 1, + "Route": "025A", + "MMin": -0, + "MMax": 298.87900000000002, + "SHAPE_Length": 4.4977027447245632 + }, + "geometry": { + "paths": [ + [ + [-104.48045588599996, 36.993878229000074], + [-104.48050318099996, 36.994486231000053], + [-104.48065092399997, 36.995038290000025], + [-104.48070509599995, 36.99524070700005], + [-104.48080757599996, 36.995446935000075], + [-104.48084011699996, 36.995512422000047], + [-104.48109407099997, 36.995913712000061], + [-104.48129848899998, 36.996175908000055], + [-104.48187755499998, 36.996844846000045], + [-104.48219789199999, 36.99729805000004], + [-104.48243650499995, 36.997797080000055], + [-104.48248663299995, 36.997977548000051], + [-104.48255274399997, 36.998345181000047], + [-104.48256583399996, 36.998729556000058], + [-104.48252486699994, 36.999069289000033], + [-104.48251842099995, 36.999122742000054], + [-104.48241381599996, 36.999516043000028], + [-104.48041568299999, 37.005994416000078], + [-104.48016812399999, 37.006796975000043], + [-104.48006938599997, 37.007213984000032], + [-104.48000987099999, 37.007636323000042], + [-104.48000904399998, 37.007642192000048], + [-104.47999405199994, 37.00807076600006], + [-104.48002256199999, 37.008504324000057], + [-104.48009628499995, 37.008939769000051], + [-104.48021678199996, 37.00937487300007], + [-104.48030103699995, 37.009608998000033], + [-104.48237161199995, 37.015362141000026], + [-104.48260622599997, 37.01598049200004], + [-104.48277556599999, 37.016368184000044] + ] + ] + } + } + ] +} From 5eed5024fa93c71c7e9b6ea8cc5cb89efbf5acca Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Mon, 16 Dec 2024 13:59:44 -0700 Subject: [PATCH 003/168] Added new method to MilepostService for retrieving a buffer of mileposts from the CDOT upstream service --- .../library/service/MilepostService.java | 20 ++++++ .../library/service/MilepostServiceTest.java | 65 ++++++++++++++++++- 2 files changed, 84 insertions(+), 1 deletion(-) diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/service/MilepostService.java b/cv-data-service-library/src/main/java/com/trihydro/library/service/MilepostService.java index 15de8a472..cfe70cbdb 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/service/MilepostService.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/service/MilepostService.java @@ -40,4 +40,24 @@ public List getMilepostsByPointWithBuffer(MilepostBuffer milepostBuffe entity, responseType); return response.getBody(); } + + /** + * Retrieves a buffer of mileposts for a given path from the CDOT upstream service. + * + * @param routeId the ID of the route for which the buffer is to be retrieved + * @param desiredDistanceInMiles the desired distance in miles for the buffer + * @param pathMileposts the list of mileposts representing the path + * @return a list of mileposts representing the buffer for the given path + */ + public List getBufferForPath(String routeId, double desiredDistanceInMiles, List pathMileposts) { + String url = String.format("%s/cdot-upstream-path/get-buffer-for-path/%s/%s", config.getCvRestService(), routeId, desiredDistanceInMiles); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + HttpEntity> entity = new HttpEntity<>(pathMileposts, headers); + ParameterizedTypeReference> responseType = new ParameterizedTypeReference>() { + }; + ResponseEntity> response = restTemplateProvider.GetRestTemplate().exchange(url, HttpMethod.POST, + entity, responseType); + return response.getBody(); + } } diff --git a/cv-data-service-library/src/test/java/com/trihydro/library/service/MilepostServiceTest.java b/cv-data-service-library/src/test/java/com/trihydro/library/service/MilepostServiceTest.java index a668e816e..aed55ab2a 100644 --- a/cv-data-service-library/src/test/java/com/trihydro/library/service/MilepostServiceTest.java +++ b/cv-data-service-library/src/test/java/com/trihydro/library/service/MilepostServiceTest.java @@ -19,7 +19,9 @@ import org.mockito.Mock; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; public class MilepostServiceTest extends BaseServiceTest { @@ -89,4 +91,65 @@ public void getMilepostsByPointWithBuffer() { Assertions.assertEquals(1, data.size()); Assertions.assertEquals(milepost, data.get(0)); } -} \ No newline at end of file + + @Test + public void getBufferForPath_Success() { + // prepare + String routeId = "routeId"; + double desiredDistanceInMiles = 10.0; + Milepost milepost1 = new Milepost(); + Milepost milepost2 = new Milepost(); + List pathMileposts = new ArrayList<>(); + pathMileposts.add(milepost1); + pathMileposts.add(milepost2); + Milepost bufferMilepost1 = new Milepost(); + Milepost bufferMilepost2 = new Milepost(); + List bufferMileposts = new ArrayList<>(); + bufferMileposts.add(bufferMilepost1); + bufferMileposts.add(bufferMilepost2); + when(mockRespMilepostList.getBody()).thenReturn(bufferMileposts); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + HttpEntity> entity = new HttpEntity<>(pathMileposts, headers); + String url = String.format("%s/cdot-upstream-path/get-buffer-for-path/%s/%s", baseUrl, routeId, desiredDistanceInMiles); + ParameterizedTypeReference> responseType = new ParameterizedTypeReference>() { + }; + when(mockRestTemplate.exchange(url, HttpMethod.POST, entity, responseType)).thenReturn(mockRespMilepostList); + + // execute + List data = uut.getBufferForPath(routeId, desiredDistanceInMiles, pathMileposts); + + // verify + verify(mockRestTemplate).exchange(url, HttpMethod.POST, entity, responseType); + Assertions.assertEquals(2, data.size()); + Assertions.assertEquals(bufferMilepost1, data.get(0)); + Assertions.assertEquals(bufferMilepost2, data.get(1)); + } + + @Test + public void getBufferForPath_Failure_ResponseBodyNull() { + // prepare + String routeId = "routeId"; + double desiredDistanceInMiles = 10.0; + Milepost milepost1 = new Milepost(); + Milepost milepost2 = new Milepost(); + List pathMileposts = new ArrayList<>(); + pathMileposts.add(milepost1); + pathMileposts.add(milepost2); + when(mockRespMilepostList.getBody()).thenReturn(null); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + HttpEntity> entity = new HttpEntity<>(pathMileposts, headers); + String url = String.format("%s/cdot-upstream-path/get-buffer-for-path/%s/%s", baseUrl, routeId, desiredDistanceInMiles); + ParameterizedTypeReference> responseType = new ParameterizedTypeReference>() { + }; + when(mockRestTemplate.exchange(url, HttpMethod.POST, entity, responseType)).thenReturn(mockRespMilepostList); + + // execute + List data = uut.getBufferForPath(routeId, desiredDistanceInMiles, pathMileposts); + + // verify + verify(mockRestTemplate).exchange(url, HttpMethod.POST, entity, responseType); + Assertions.assertNull(data); + } +} From 9e474d955c25bbc0ee28a99765070422c9ba085e Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Mon, 16 Dec 2024 14:23:09 -0700 Subject: [PATCH 004/168] Modified CdotUpstreamPathController to use standardized logger instead of utility class --- .../CdotUpstreamPathController.java | 38 ++++++++++--------- .../src/main/resources/application.properties | 4 +- .../CdotUpstreamPathControllerTest.java | 2 +- docker-compose.yml | 1 + local-deployment/docker-compose.yml | 1 + sample.env | 1 + 6 files changed, 27 insertions(+), 20 deletions(-) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java index 769a4c70d..bb7147430 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java @@ -8,6 +8,8 @@ import com.trihydro.library.helpers.Utility; import com.trihydro.library.model.Milepost; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.CrossOrigin; @@ -30,29 +32,29 @@ @RequestMapping("cdot-upstream-path") public class CdotUpstreamPathController extends BaseController { private CdotGisConnector cdotGisService; - private Utility utility; + + private final Logger logger = LoggerFactory.getLogger(CdotUpstreamPathController.class); @Autowired - public void InjectDependencies(CdotGisConnector cdotGisService, Utility utility) { + public void InjectDependencies(CdotGisConnector cdotGisService) { this.cdotGisService = cdotGisService; - this.utility = utility; } @RequestMapping(value = "/get-buffer-for-path/{routeId}/{desiredDistanceInMiles:.+}", method = RequestMethod.POST) public ResponseEntity> getBufferForPath(@RequestBody List pathMileposts, @PathVariable String routeId, @PathVariable double desiredDistanceInMiles) throws JsonMappingException, JsonProcessingException { - utility.logWithDate("Number of mileposts in path in request body: " + pathMileposts.size(), this.getClass()); + logger.info("Number of mileposts in path in request body: {}", pathMileposts.size()); for (Milepost milepost : pathMileposts) { - utility.logWithDate("Milepost in path: " + milepost.getLatitude() + ", " + milepost.getLongitude(), this.getClass()); + logger.debug("Milepost in path: {}, {}", milepost.getLatitude(), milepost.getLongitude()); } List allMileposts = getMilepostsForRoute(routeId); if (allMileposts == null || allMileposts.isEmpty()) { - utility.logWithDate("No mileposts found for route", this.getClass()); + logger.warn("No mileposts found for route"); return ResponseEntity.badRequest().body(null); } - utility.logWithDate("Number of mileposts in route: " + allMileposts.size(), this.getClass()); + logger.info("Number of mileposts in route: {}", allMileposts.size()); PathDirection direction = getPathDirection(pathMileposts, allMileposts); if (direction == null) { - utility.logWithDate("Invalid path direction", this.getClass()); + logger.warn("Invalid path direction"); return ResponseEntity.badRequest().body(null); } Milepost firstMilepostInPath = pathMileposts.get(0); @@ -61,7 +63,7 @@ public ResponseEntity> getBufferForPath(@RequestBody List buffer = new ArrayList(); double distanceInMiles = 0; if (direction == PathDirection.ASCENDING) { - utility.logWithDate("Path direction is ascending. Start index: " + startIndex, this.getClass()); + logger.info("Path direction is ascending. Start index: {}", startIndex); buffer.add(allMileposts.get(startIndex)); // add mileposts in descending order for (int i = startIndex - 1; i >= 0; i--) { @@ -72,7 +74,7 @@ public ResponseEntity> getBufferForPath(@RequestBody List> getBufferForPath(@RequestBody List getMilepostsForRoute(String routeId) throws JsonMappingExc public PathDirection getPathDirection(List pathMileposts, List allMileposts) { if (pathMileposts.size() < 2) { - utility.logWithDate("Path has less than 2 mileposts", this.getClass()); + logger.warn("Path has less than 2 mileposts"); return null; } Milepost firstMilepostInPath = pathMileposts.get(0); Milepost secondMilepostInPath = pathMileposts.get(1); int firstMilepostInPathIndex = getIndexOfMilepost(allMileposts, firstMilepostInPath); if (firstMilepostInPathIndex == -1) { - utility.logWithDate("First milepost not found in route", this.getClass()); + logger.warn("First milepost not found in route"); return null; } int secondMilepostInPathIndex = getIndexOfMilepost(allMileposts, secondMilepostInPath); if (secondMilepostInPathIndex == -1) { - utility.logWithDate("Second milepost not found in route", this.getClass()); + logger.warn("Second milepost not found in route"); return null; } if (firstMilepostInPathIndex < secondMilepostInPathIndex) { @@ -143,7 +145,7 @@ public PathDirection getPathDirection(List pathMileposts, List mileposts, Milepost milepost) { if (milepost.getLatitude() == null || milepost.getLongitude() == null) { - utility.logWithDate("Milepost has null latitude or longitude", this.getClass()); + logger.warn("Milepost has null latitude or longitude"); return -1; } BigDecimal latitude = milepost.getLatitude().setScale(14, BigDecimal.ROUND_HALF_UP); diff --git a/cv-data-controller/src/main/resources/application.properties b/cv-data-controller/src/main/resources/application.properties index fe2e64b06..7230c04a7 100644 --- a/cv-data-controller/src/main/resources/application.properties +++ b/cv-data-controller/src/main/resources/application.properties @@ -20,4 +20,6 @@ spring.data.neo4j.uri=bolt://host.docker.internal:6687 # server.ssl.key-store: classpath:keystore.jks # server.ssl.key-store-password: store-password # server.ssl.keyStoreType: JKS -# server.ssl.keyAlias: some-alias \ No newline at end of file +# server.ssl.keyAlias: some-alias + +logging.level.root=INFO \ No newline at end of file diff --git a/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathControllerTest.java b/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathControllerTest.java index 9c366ff1b..20dbfbd27 100644 --- a/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathControllerTest.java +++ b/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathControllerTest.java @@ -57,7 +57,7 @@ List getMockMileposts() throws IOException { @BeforeEach void setUp() { uut = new CdotUpstreamPathController(); - uut.InjectDependencies(cdotGisService, utility); + uut.InjectDependencies(cdotGisService); } @Test diff --git a/docker-compose.yml b/docker-compose.yml index af0a6d10d..1fd5de794 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -136,6 +136,7 @@ services: SERVER_SSL_KEY_STORE_PASSWORD: ${CONTROLLER_SERVER_SSL_KEY_STORE_PASSWORD} SERVER_SSL_KEY_STORE_TYPE: ${CONTROLLER_SERVER_SSL_KEY_STORE_TYPE} SERVER_SSL_KEY_ALIAS: ${CONTROLLER_SERVER_SSL_KEY_ALIAS} + LOGGING_LEVEL_ROOT: ${CONTROLLER_LOGGING_LEVEL_ROOT} volumes: - /home/wyocvadmin/wyocv/cv-data-controller:/keystore logging: diff --git a/local-deployment/docker-compose.yml b/local-deployment/docker-compose.yml index 9ff1b78a0..3a3712188 100644 --- a/local-deployment/docker-compose.yml +++ b/local-deployment/docker-compose.yml @@ -196,6 +196,7 @@ services: CONFIG_ENVIRONMENT_NAME: local CONFIG_MAIL_HOST: 172.0.0.1 CONFIG_MAIL_PORT: 123 + LOGGING_LEVEL_ROOT: DEBUG logging: options: max-size: "20m" diff --git a/sample.env b/sample.env index 936596b87..bfa46f4e2 100644 --- a/sample.env +++ b/sample.env @@ -51,6 +51,7 @@ CONTROLLER_SERVER_SSL_KEY_STORE=classpath:keystore.jks CONTROLLER_SERVER_SSL_KEY_STORE_PASSWORD= CONTROLLER_SERVER_SSL_KEY_STORE_TYPE=JKS CONTROLLER_SERVER_SSL_KEY_ALIAS=key-alias +CONTROLLER_LOGGING_LEVEL_ROOT=INFO # Data Logger LOGGER_KAFKA_HOST_SERVER=ode-url From 528e30e7bfa4a38e081d48bc94e2d307f059e17e Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Mon, 16 Dec 2024 15:04:31 -0700 Subject: [PATCH 005/168] Added standardized logging & exception handling to CdotGisConnector --- .../CdotUpstreamPathController.java | 4 +++ .../library/helpers/CdotGisConnector.java | 30 +++++++++++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java index bb7147430..3869af1e1 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java @@ -102,6 +102,10 @@ public ResponseEntity> getBufferForPath(@RequestBody List getMilepostsForRoute(String routeId) throws JsonMappingException, JsonProcessingException { ResponseEntity response = cdotGisService.getRouteById(routeId); + if (response == null || response.getBody() == null) { + logger.warn("Response from CDOT GIS service is null"); + return new ArrayList<>(); + } String routeJsonString = response.getBody(); ObjectMapper objectMapper = new ObjectMapper(); JsonNode rootNode = objectMapper.readTree(routeJsonString); diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CdotGisConnector.java b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CdotGisConnector.java index 1950426eb..f65fb6c45 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CdotGisConnector.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CdotGisConnector.java @@ -1,5 +1,7 @@ package com.trihydro.library.helpers; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; @@ -15,6 +17,8 @@ public class CdotGisConnector { private RestTemplateProvider restTemplateProvider; + private final Logger logger = LoggerFactory.getLogger(CdotGisConnector.class); + @Autowired public void InjectDependencies(RestTemplateProvider _restTemplateProvider) { this.restTemplateProvider = _restTemplateProvider; @@ -30,19 +34,41 @@ public RestTemplateProvider getRestTemplateProvider() { public ResponseEntity getAllRoutes() { String targetUrl = baseUrl + "/Routes"; + logger.info("Getting all routes from CDOT GIS service at: {}", targetUrl); String params = "?f=json"; HttpHeaders headers = new HttpHeaders(); headers.set("Accept", "application/json"); HttpEntity entity = new HttpEntity<>(headers); - return restTemplateProvider.GetRestTemplate().exchange(targetUrl + params, HttpMethod.GET, entity, String.class); + ResponseEntity response; + try { + response = restTemplateProvider.GetRestTemplate().exchange(targetUrl + params, HttpMethod.GET, entity, String.class); + } catch (Exception e) { + logger.error("Error getting all routes from CDOT GIS service: {}", e.getMessage(), e); + return null; + } + if (response.getBody() != null) { + logger.info("Received response from CDOT GIS service: {}", response.getBody()); + } + return response; } public ResponseEntity getRouteById(String routeId) { String targetUrl = baseUrl + "/Route"; + logger.info("Getting route with ID {} from CDOT GIS service at: {}", routeId, targetUrl); String params = "?routeId=" + routeId + "&outSR=4326&f=json"; HttpHeaders headers = new HttpHeaders(); headers.set("Accept", "application/json"); HttpEntity entity = new HttpEntity<>(headers); - return restTemplateProvider.GetRestTemplate().exchange(targetUrl + params, HttpMethod.GET, entity, String.class); + ResponseEntity response; + try { + response = restTemplateProvider.GetRestTemplate().exchange(targetUrl + params, HttpMethod.GET, entity, String.class); + } catch (Exception e) { + logger.error("Error getting route with ID {} from CDOT GIS service: {}", routeId, e.getMessage(), e); + return null; + } + if (response.getBody() != null) { + logger.info("Received response from CDOT GIS service: {}", response.getBody()); + } + return response; } } From 90bb038d6d5e882c15048fcb057b482da4e8bcc3 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Mon, 16 Dec 2024 15:07:40 -0700 Subject: [PATCH 006/168] Updated logging upon receiving null body from CDOT GIS service --- .../com/trihydro/library/helpers/CdotGisConnector.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CdotGisConnector.java b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CdotGisConnector.java index f65fb6c45..972927dc8 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CdotGisConnector.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CdotGisConnector.java @@ -46,8 +46,8 @@ public ResponseEntity getAllRoutes() { logger.error("Error getting all routes from CDOT GIS service: {}", e.getMessage(), e); return null; } - if (response.getBody() != null) { - logger.info("Received response from CDOT GIS service: {}", response.getBody()); + if (response.getBody() == null) { + logger.warn("Received null response body from CDOT GIS service"); } return response; } @@ -66,8 +66,8 @@ public ResponseEntity getRouteById(String routeId) { logger.error("Error getting route with ID {} from CDOT GIS service: {}", routeId, e.getMessage(), e); return null; } - if (response.getBody() != null) { - logger.info("Received response from CDOT GIS service: {}", response.getBody()); + if (response.getBody() == null) { + logger.warn("Received null response body from CDOT GIS service"); } return response; } From d09843a8bfeeb555539a5d352e5e1cb6ab1ae648 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Mon, 16 Dec 2024 15:24:14 -0700 Subject: [PATCH 007/168] Changed cv-data-controller root log level to INFO in local deployment compose file --- local-deployment/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/local-deployment/docker-compose.yml b/local-deployment/docker-compose.yml index 3a3712188..1ff5039bd 100644 --- a/local-deployment/docker-compose.yml +++ b/local-deployment/docker-compose.yml @@ -196,7 +196,7 @@ services: CONFIG_ENVIRONMENT_NAME: local CONFIG_MAIL_HOST: 172.0.0.1 CONFIG_MAIL_PORT: 123 - LOGGING_LEVEL_ROOT: DEBUG + LOGGING_LEVEL_ROOT: INFO logging: options: max-size: "20m" From 160ce31960a9085a7420b96461f1f250745035c1 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Mon, 16 Dec 2024 21:46:29 -0700 Subject: [PATCH 008/168] Removed `@ApiIgnore` annotation from CdotUpstreamPathController --- .../cvdatacontroller/controller/CdotUpstreamPathController.java | 1 - 1 file changed, 1 deletion(-) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java index 3869af1e1..8af5e95ab 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java @@ -28,7 +28,6 @@ @CrossOrigin @RestController -@ApiIgnore @RequestMapping("cdot-upstream-path") public class CdotUpstreamPathController extends BaseController { private CdotGisConnector cdotGisService; From 6b7272381dac40284fa3468515be92ac4281c45b Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Mon, 16 Dec 2024 22:08:08 -0700 Subject: [PATCH 009/168] Switched over to using constructors instead of `InjectDependencies()` in CdotGisConnector and CdotUpstreamPathController classes --- .../controller/CdotUpstreamPathController.java | 7 ++----- .../CdotUpstreamPathControllerTest.java | 16 ++++++++-------- .../library/helpers/CdotGisConnector.java | 4 ++-- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java index 8af5e95ab..8b27ce9f9 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java @@ -5,7 +5,6 @@ import java.util.List; import com.trihydro.library.helpers.CdotGisConnector; -import com.trihydro.library.helpers.Utility; import com.trihydro.library.model.Milepost; import org.slf4j.Logger; @@ -19,8 +18,6 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; -import springfox.documentation.annotations.ApiIgnore; - import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonNode; @@ -30,12 +27,12 @@ @RestController @RequestMapping("cdot-upstream-path") public class CdotUpstreamPathController extends BaseController { - private CdotGisConnector cdotGisService; + private final CdotGisConnector cdotGisService; private final Logger logger = LoggerFactory.getLogger(CdotUpstreamPathController.class); @Autowired - public void InjectDependencies(CdotGisConnector cdotGisService) { + public CdotUpstreamPathController(CdotGisConnector cdotGisService) { this.cdotGisService = cdotGisService; } diff --git a/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathControllerTest.java b/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathControllerTest.java index 20dbfbd27..fd3c17199 100644 --- a/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathControllerTest.java +++ b/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathControllerTest.java @@ -15,25 +15,26 @@ import com.trihydro.cvdatacontroller.controller.CdotUpstreamPathController.DistanceCalculator; import com.trihydro.cvdatacontroller.controller.CdotUpstreamPathController.PathDirection; import com.trihydro.library.helpers.CdotGisConnector; -import com.trihydro.library.helpers.Utility; import com.trihydro.library.model.Milepost; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; import org.mockito.Mock; +import org.mockito.Mockito; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -class CdotUpstreamPathControllerTest extends TestBase { +class CdotUpstreamPathControllerTest { private final String ROUTE_ID = "025A"; // I-25 private final String PATH_TO_ROUTE_JSON_TEST_DATA = "src/test/resources/com/trihydro/cvdatacontroller/controller/cdotRouteResponseForI25_First30Mileposts.json"; @Mock - CdotGisConnector cdotGisService; + CdotGisConnector cdotGisService = Mockito.mock(CdotGisConnector.class); - @Mock - Utility utility; + @InjectMocks + CdotUpstreamPathController uut; @SuppressWarnings("deprecation") List getMockMileposts() throws IOException { @@ -41,7 +42,7 @@ List getMockMileposts() throws IOException { ObjectMapper objectMapper = new ObjectMapper(); JsonNode rootNode = objectMapper.readTree(routeJsonString); JsonNode pathNode = rootNode.path("features").get(0).path("geometry").path("paths").get(0); - List mileposts = new ArrayList(); + List mileposts = new ArrayList<>(); for (JsonNode node : pathNode) { Milepost milepost = new Milepost(); milepost.setCommonName(ROUTE_ID); @@ -56,8 +57,7 @@ List getMockMileposts() throws IOException { @BeforeEach void setUp() { - uut = new CdotUpstreamPathController(); - uut.InjectDependencies(cdotGisService); + uut = new CdotUpstreamPathController(cdotGisService); } @Test diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CdotGisConnector.java b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CdotGisConnector.java index 972927dc8..788f6aa5a 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CdotGisConnector.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CdotGisConnector.java @@ -15,12 +15,12 @@ public class CdotGisConnector { private final String baseUrl = "https://dtdapps.coloradodot.info/arcgis/rest/services/LRS/Routes/MapServer/exts/CdotLrsAccessRounded"; - private RestTemplateProvider restTemplateProvider; + private final RestTemplateProvider restTemplateProvider; private final Logger logger = LoggerFactory.getLogger(CdotGisConnector.class); @Autowired - public void InjectDependencies(RestTemplateProvider _restTemplateProvider) { + public CdotGisConnector(RestTemplateProvider _restTemplateProvider) { this.restTemplateProvider = _restTemplateProvider; } From 5084a579b020ff2c7504b6c05388c2f3d8338f56 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Mon, 16 Dec 2024 22:12:41 -0700 Subject: [PATCH 010/168] Removed unnecessary exception throw in CdotUpstreamPathController.getMilepostsForRoute() --- .../cvdatacontroller/controller/CdotUpstreamPathController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java index 8b27ce9f9..ae0fdac80 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java @@ -96,7 +96,7 @@ public ResponseEntity> getBufferForPath(@RequestBody List getMilepostsForRoute(String routeId) throws JsonMappingException, JsonProcessingException { + public List getMilepostsForRoute(String routeId) throws JsonProcessingException { ResponseEntity response = cdotGisService.getRouteById(routeId); if (response == null || response.getBody() == null) { logger.warn("Response from CDOT GIS service is null"); From 4b93c09b80fd5b79c5e477203a3f373793200a9d Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Tue, 17 Dec 2024 13:38:41 -0700 Subject: [PATCH 011/168] Updated CdotUpstreamPathController to use `@PostMapping` annotation --- .../controller/CdotUpstreamPathController.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java index ae0fdac80..efada71e8 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java @@ -13,6 +13,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @@ -36,7 +37,7 @@ public CdotUpstreamPathController(CdotGisConnector cdotGisService) { this.cdotGisService = cdotGisService; } - @RequestMapping(value = "/get-buffer-for-path/{routeId}/{desiredDistanceInMiles:.+}", method = RequestMethod.POST) + @PostMapping(value = "/get-buffer-for-path/{routeId}/{desiredDistanceInMiles:.+}") public ResponseEntity> getBufferForPath(@RequestBody List pathMileposts, @PathVariable String routeId, @PathVariable double desiredDistanceInMiles) throws JsonMappingException, JsonProcessingException { logger.info("Number of mileposts in path in request body: {}", pathMileposts.size()); for (Milepost milepost : pathMileposts) { From 44c43b2148fc134e23bac2164683b0347422d873 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Tue, 17 Dec 2024 13:38:50 -0700 Subject: [PATCH 012/168] Removed unused import --- .../cvdatacontroller/controller/CdotUpstreamPathController.java | 1 - 1 file changed, 1 deletion(-) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java index efada71e8..6397e7e5d 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java @@ -16,7 +16,6 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import com.fasterxml.jackson.core.JsonProcessingException; From ef31eadd675574aca139d3ea75836af64e6fc99c Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Tue, 17 Dec 2024 15:20:44 -0700 Subject: [PATCH 013/168] Switched over to using `RoundingMode.HALF_UP` in CdotUpstreamPathController and removed deprecation suppression annotations --- .../CdotUpstreamPathController.java | 6 ++--- .../CdotUpstreamPathControllerTest.java | 24 +++++++++---------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java index 6397e7e5d..2258979e2 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java @@ -1,6 +1,7 @@ package com.trihydro.cvdatacontroller.controller; import java.math.BigDecimal; +import java.math.RoundingMode; import java.util.ArrayList; import java.util.List; @@ -95,7 +96,6 @@ public ResponseEntity> getBufferForPath(@RequestBody List getMilepostsForRoute(String routeId) throws JsonProcessingException { ResponseEntity response = cdotGisService.getRouteById(routeId); if (response == null || response.getBody() == null) { @@ -110,8 +110,8 @@ public List getMilepostsForRoute(String routeId) throws JsonProcessing for (JsonNode node : pathNode) { Milepost milepost = new Milepost(); milepost.setCommonName(routeId); - BigDecimal latitude = new BigDecimal(node.get(1).asText()).setScale(14, BigDecimal.ROUND_HALF_UP); - BigDecimal longitude = new BigDecimal(node.get(0).asText()).setScale(14, BigDecimal.ROUND_HALF_UP); + BigDecimal latitude = new BigDecimal(node.get(1).asText()).setScale(14, RoundingMode.HALF_UP); + BigDecimal longitude = new BigDecimal(node.get(0).asText()).setScale(14, RoundingMode.HALF_UP); milepost.setLatitude(latitude); milepost.setLongitude(longitude); mileposts.add(milepost); diff --git a/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathControllerTest.java b/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathControllerTest.java index fd3c17199..1fa87969c 100644 --- a/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathControllerTest.java +++ b/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathControllerTest.java @@ -5,6 +5,7 @@ import java.io.IOException; import java.math.BigDecimal; +import java.math.RoundingMode; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; @@ -36,7 +37,6 @@ class CdotUpstreamPathControllerTest { @InjectMocks CdotUpstreamPathController uut; - @SuppressWarnings("deprecation") List getMockMileposts() throws IOException { String routeJsonString = new String(Files.readAllBytes(Paths.get(PATH_TO_ROUTE_JSON_TEST_DATA))); ObjectMapper objectMapper = new ObjectMapper(); @@ -46,8 +46,8 @@ List getMockMileposts() throws IOException { for (JsonNode node : pathNode) { Milepost milepost = new Milepost(); milepost.setCommonName(ROUTE_ID); - BigDecimal latitude = new BigDecimal(node.get(1).asText()).setScale(14, BigDecimal.ROUND_HALF_UP); - BigDecimal longitude = new BigDecimal(node.get(0).asText()).setScale(14, BigDecimal.ROUND_HALF_UP); + BigDecimal latitude = new BigDecimal(node.get(1).asText()).setScale(14, RoundingMode.HALF_UP); + BigDecimal longitude = new BigDecimal(node.get(0).asText()).setScale(14, RoundingMode.HALF_UP); milepost.setLatitude(latitude); milepost.setLongitude(longitude); mileposts.add(milepost); @@ -134,15 +134,14 @@ void testGetPathDirection_NOT_ENOUGH_MILEPOSTS() throws IOException { Assertions.assertNull(direction); } - @SuppressWarnings("deprecation") @Test void testGetPathDirection_FirstMilepostOfPathNotInAllMileposts() throws IOException { // prepare List allMileposts = getMockMileposts(); Milepost mp1 = new Milepost(); mp1.setCommonName(ROUTE_ID); - mp1.setLatitude(new BigDecimal("30.12").setScale(14, BigDecimal.ROUND_HALF_UP)); - mp1.setLongitude(new BigDecimal("-100.34").setScale(14, BigDecimal.ROUND_HALF_UP)); + mp1.setLatitude(new BigDecimal("30.12").setScale(14, RoundingMode.HALF_UP)); + mp1.setLongitude(new BigDecimal("-100.34").setScale(14, RoundingMode.HALF_UP)); Milepost mp2 = allMileposts.get(1); List pathMileposts = List.of(mp1, mp2); @@ -153,7 +152,6 @@ void testGetPathDirection_FirstMilepostOfPathNotInAllMileposts() throws IOExcept Assertions.assertNull(direction); } - @SuppressWarnings("deprecation") @Test void testGetPathDirection_SecondMilepostOfPathNotInAllMileposts() throws IOException { // prepare @@ -161,8 +159,8 @@ void testGetPathDirection_SecondMilepostOfPathNotInAllMileposts() throws IOExcep Milepost mp1 = allMileposts.get(0); Milepost mp2 = new Milepost(); mp2.setCommonName(ROUTE_ID); - mp1.setLatitude(new BigDecimal("30.12").setScale(14, BigDecimal.ROUND_HALF_UP)); - mp1.setLongitude(new BigDecimal("-100.34").setScale(14, BigDecimal.ROUND_HALF_UP)); + mp1.setLatitude(new BigDecimal("30.12").setScale(14, RoundingMode.HALF_UP)); + mp1.setLongitude(new BigDecimal("-100.34").setScale(14, RoundingMode.HALF_UP)); List pathMileposts = List.of(mp1, mp2); // execute @@ -176,7 +174,7 @@ void testGetPathDirection_SecondMilepostOfPathNotInAllMileposts() throws IOExcep void testGetBufferForPath_Ascending_Success() throws IOException { // prepare String routeJsonString = new String(Files.readAllBytes(Paths.get(PATH_TO_ROUTE_JSON_TEST_DATA))); - ResponseEntity mockResponse = new ResponseEntity(routeJsonString, HttpStatus.OK); + ResponseEntity mockResponse = new ResponseEntity<>(routeJsonString, HttpStatus.OK); when(cdotGisService.getRouteById(ROUTE_ID)).thenReturn(mockResponse); List allMileposts = getMockMileposts(); @@ -202,7 +200,7 @@ void testGetBufferForPath_Ascending_Success() throws IOException { void testGetBufferForPath_Ascending_Failure_EndOfAllMilepostsReached() throws IOException { // prepare String routeJsonString = new String(Files.readAllBytes(Paths.get(PATH_TO_ROUTE_JSON_TEST_DATA))); - ResponseEntity mockResponse = new ResponseEntity(routeJsonString, HttpStatus.OK); + ResponseEntity mockResponse = new ResponseEntity<>(routeJsonString, HttpStatus.OK); when(cdotGisService.getRouteById(ROUTE_ID)).thenReturn(mockResponse); List allMileposts = getMockMileposts(); @@ -250,7 +248,7 @@ void testGetBufferForPath_Descending_Success() throws IOException { void testGetBufferForPath_Descending_Failure_EndOfAllMilepostsReached() throws IOException { // prepare String routeJsonString = new String(Files.readAllBytes(Paths.get(PATH_TO_ROUTE_JSON_TEST_DATA))); - ResponseEntity mockResponse = new ResponseEntity(routeJsonString, HttpStatus.OK); + ResponseEntity mockResponse = new ResponseEntity<>(routeJsonString, HttpStatus.OK); when(cdotGisService.getRouteById(ROUTE_ID)).thenReturn(mockResponse); List allMileposts = getMockMileposts(); @@ -272,7 +270,7 @@ void testGetBufferForPath_Descending_Failure_EndOfAllMilepostsReached() throws I void testGetBufferForPath_PathDirectionIsNull() throws IOException { // prepare String routeJsonString = new String(Files.readAllBytes(Paths.get(PATH_TO_ROUTE_JSON_TEST_DATA))); - ResponseEntity mockResponse = new ResponseEntity(routeJsonString, HttpStatus.OK); + ResponseEntity mockResponse = new ResponseEntity<>(routeJsonString, HttpStatus.OK); when(cdotGisService.getRouteById(ROUTE_ID)).thenReturn(mockResponse); List allMileposts = getMockMileposts(); From dc98fa3c5f509cbc1ccb910e466bd7237ecd90f6 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Tue, 17 Dec 2024 15:23:50 -0700 Subject: [PATCH 014/168] Removed unnecessary initialization test in CdotUpstreamPathControllerTest --- .../controller/CdotUpstreamPathControllerTest.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathControllerTest.java b/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathControllerTest.java index 1fa87969c..2e3562a8b 100644 --- a/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathControllerTest.java +++ b/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathControllerTest.java @@ -60,11 +60,6 @@ void setUp() { uut = new CdotUpstreamPathController(cdotGisService); } - @Test - void testInitialization() { - Assertions.assertNotNull(uut); - } - @Test void testGetMilepostsForRoute() throws IOException { // prepare From 5de1c19cbbe1974c649b7e1e517aacdd15c7b0fe Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Tue, 17 Dec 2024 15:29:08 -0700 Subject: [PATCH 015/168] Removed unused `getAllRoutes()` method in CdotGisConnector & corresponding unit test --- .../library/helpers/CdotGisConnector.java | 20 ----------------- .../library/helpers/CdotGisConnectorTest.java | 22 ------------------- 2 files changed, 42 deletions(-) diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CdotGisConnector.java b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CdotGisConnector.java index 788f6aa5a..85d6931c0 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CdotGisConnector.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CdotGisConnector.java @@ -32,26 +32,6 @@ public RestTemplateProvider getRestTemplateProvider() { return restTemplateProvider; } - public ResponseEntity getAllRoutes() { - String targetUrl = baseUrl + "/Routes"; - logger.info("Getting all routes from CDOT GIS service at: {}", targetUrl); - String params = "?f=json"; - HttpHeaders headers = new HttpHeaders(); - headers.set("Accept", "application/json"); - HttpEntity entity = new HttpEntity<>(headers); - ResponseEntity response; - try { - response = restTemplateProvider.GetRestTemplate().exchange(targetUrl + params, HttpMethod.GET, entity, String.class); - } catch (Exception e) { - logger.error("Error getting all routes from CDOT GIS service: {}", e.getMessage(), e); - return null; - } - if (response.getBody() == null) { - logger.warn("Received null response body from CDOT GIS service"); - } - return response; - } - public ResponseEntity getRouteById(String routeId) { String targetUrl = baseUrl + "/Route"; logger.info("Getting route with ID {} from CDOT GIS service at: {}", routeId, targetUrl); diff --git a/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CdotGisConnectorTest.java b/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CdotGisConnectorTest.java index e02e9e288..ec399a427 100644 --- a/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CdotGisConnectorTest.java +++ b/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CdotGisConnectorTest.java @@ -32,28 +32,6 @@ void testGetBaseUrl() { Assertions.assertEquals("https://dtdapps.coloradodot.info/arcgis/rest/services/LRS/Routes/MapServer/exts/CdotLrsAccessRounded", uut.getBaseUrl()); } - @Test - void testGetAllRoutes() { - // prepare - String expectedTargetUrl = expectedBaseUrl + "/Routes"; - String f = "json"; - String expectedParams = "?f=" + f; - HttpHeaders mockHeaders = new HttpHeaders(); - mockHeaders.set("Accept", "application/json"); - HttpEntity mockEntity = new HttpEntity<>(mockHeaders); - String mockResponseString = "mockResponseString"; - ResponseEntity mockResponse = ResponseEntity.ok(mockResponseString); - when(mockRestTemplate.exchange(expectedTargetUrl + expectedParams, HttpMethod.GET, mockEntity, String.class)).thenReturn(mockResponse); - - // execute - ResponseEntity response = uut.getAllRoutes(); - - // verify - Assertions.assertEquals(mockResponse.getStatusCode(), response.getStatusCode()); - Assertions.assertEquals(mockResponseString, response.getBody()); - verify(mockRestTemplate).exchange(expectedTargetUrl + expectedParams, HttpMethod.GET, mockEntity, String.class); - } - @Test void testGetRouteById() { // prepare From 15fec298132f4b2dcf5444f27c27457016060a05 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Tue, 17 Dec 2024 15:49:27 -0700 Subject: [PATCH 016/168] Switched over to using `RoundingMode.HALF_UP` in CdotUpstreamPathController.getIndexOfMilepost() --- .../controller/CdotUpstreamPathController.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java index 2258979e2..93878ec25 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java @@ -57,7 +57,7 @@ public ResponseEntity> getBufferForPath(@RequestBody List buffer = new ArrayList(); + List buffer = new ArrayList<>(); double distanceInMiles = 0; if (direction == PathDirection.ASCENDING) { logger.info("Path direction is ascending. Start index: {}", startIndex); @@ -106,7 +106,7 @@ public List getMilepostsForRoute(String routeId) throws JsonProcessing ObjectMapper objectMapper = new ObjectMapper(); JsonNode rootNode = objectMapper.readTree(routeJsonString); JsonNode pathNode = rootNode.path("features").get(0).path("geometry").path("paths").get(0); - List mileposts = new ArrayList(); + List mileposts = new ArrayList<>(); for (JsonNode node : pathNode) { Milepost milepost = new Milepost(); milepost.setCommonName(routeId); @@ -148,12 +148,13 @@ private int getIndexOfMilepost(List mileposts, Milepost milepost) { logger.warn("Milepost has null latitude or longitude"); return -1; } - BigDecimal latitude = milepost.getLatitude().setScale(14, BigDecimal.ROUND_HALF_UP); - BigDecimal longitude = milepost.getLongitude().setScale(14, BigDecimal.ROUND_HALF_UP); + BigDecimal latitude = milepost.getLatitude().setScale(14, RoundingMode.HALF_UP); + BigDecimal longitude = milepost.getLongitude().setScale(14, RoundingMode.HALF_UP); for (int i = 0; i < mileposts.size(); i++) { Milepost currentMilepost = mileposts.get(i); - BigDecimal currentLatitude = currentMilepost.getLatitude().setScale(14, BigDecimal.ROUND_HALF_UP); - BigDecimal currentLongitude = currentMilepost.getLongitude().setScale(14, BigDecimal.ROUND_HALF_UP); + BigDecimal currentLatitude = currentMilepost.getLatitude().setScale(14, RoundingMode.HALF_UP); + BigDecimal currentLongitude = currentMilepost.getLongitude().setScale(14, + RoundingMode.HALF_UP); if (latitude.equals(currentLatitude) && longitude.equals(currentLongitude)) { return i; } From 5c94e4138fc2e8fdcd965a73298e08922db8e429 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Tue, 17 Dec 2024 15:50:35 -0700 Subject: [PATCH 017/168] Addressed a few more IDE warnings --- .../controller/CdotUpstreamPathController.java | 3 ++- .../controller/CdotUpstreamPathControllerTest.java | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java index 93878ec25..b1aba6e42 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java @@ -38,7 +38,8 @@ public CdotUpstreamPathController(CdotGisConnector cdotGisService) { } @PostMapping(value = "/get-buffer-for-path/{routeId}/{desiredDistanceInMiles:.+}") - public ResponseEntity> getBufferForPath(@RequestBody List pathMileposts, @PathVariable String routeId, @PathVariable double desiredDistanceInMiles) throws JsonMappingException, JsonProcessingException { + public ResponseEntity> getBufferForPath(@RequestBody List pathMileposts, @PathVariable String routeId, @PathVariable double desiredDistanceInMiles) throws + JsonProcessingException { logger.info("Number of mileposts in path in request body: {}", pathMileposts.size()); for (Milepost milepost : pathMileposts) { logger.debug("Milepost in path: {}, {}", milepost.getLatitude(), milepost.getLongitude()); diff --git a/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathControllerTest.java b/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathControllerTest.java index 2e3562a8b..1f9f085a8 100644 --- a/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathControllerTest.java +++ b/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathControllerTest.java @@ -64,7 +64,7 @@ void setUp() { void testGetMilepostsForRoute() throws IOException { // prepare String routeJsonString = new String(Files.readAllBytes(Paths.get(PATH_TO_ROUTE_JSON_TEST_DATA))); - ResponseEntity mockResponse = new ResponseEntity(routeJsonString, HttpStatus.OK); + ResponseEntity mockResponse = new ResponseEntity<>(routeJsonString, HttpStatus.OK); when(cdotGisService.getRouteById(ROUTE_ID)).thenReturn(mockResponse); List expectedMileposts = getMockMileposts(); @@ -217,7 +217,7 @@ void testGetBufferForPath_Ascending_Failure_EndOfAllMilepostsReached() throws IO void testGetBufferForPath_Descending_Success() throws IOException { // prepare String routeJsonString = new String(Files.readAllBytes(Paths.get(PATH_TO_ROUTE_JSON_TEST_DATA))); - ResponseEntity mockResponse = new ResponseEntity(routeJsonString, HttpStatus.OK); + ResponseEntity mockResponse = new ResponseEntity<>(routeJsonString, HttpStatus.OK); when(cdotGisService.getRouteById(ROUTE_ID)).thenReturn(mockResponse); List allMileposts = getMockMileposts(); From 34a263a3567f5cf175e07af6834a1b41ada4716d Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Tue, 17 Dec 2024 15:50:57 -0700 Subject: [PATCH 018/168] Removed unused import in CdotUpstreamPathController --- .../cvdatacontroller/controller/CdotUpstreamPathController.java | 1 - 1 file changed, 1 deletion(-) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java index b1aba6e42..fe79d59c3 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java @@ -20,7 +20,6 @@ import org.springframework.web.bind.annotation.RestController; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; From e105c17bce024e3ac837da87cb5d652e62e27072 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Tue, 17 Dec 2024 16:09:06 -0700 Subject: [PATCH 019/168] Transitioned to throwing exceptions instead of returning null in CdotGisConnector and CdotUpstreamPathController --- .../CdotUpstreamPathController.java | 49 +++++++++++++------ .../CdotUpstreamPathControllerTest.java | 39 ++++++++------- .../library/helpers/CdotGisConnector.java | 15 ++---- 3 files changed, 60 insertions(+), 43 deletions(-) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java index fe79d59c3..9736315a3 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java @@ -22,6 +22,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.web.client.RestClientException; @CrossOrigin @RestController @@ -43,13 +44,28 @@ public ResponseEntity> getBufferForPath(@RequestBody List allMileposts = getMilepostsForRoute(routeId); + List allMileposts; + try { + allMileposts = getMilepostsForRoute(routeId); + } catch (RestClientException e) { + logger.error("Error getting mileposts for route", e); + return ResponseEntity.badRequest().body(null); + } if (allMileposts == null || allMileposts.isEmpty()) { logger.warn("No mileposts found for route"); return ResponseEntity.badRequest().body(null); } logger.info("Number of mileposts in route: {}", allMileposts.size()); - PathDirection direction = getPathDirection(pathMileposts, allMileposts); + PathDirection direction; + try { + direction = getPathDirection(pathMileposts, allMileposts); + } catch (NotEnoughMilepostsException e) { + logger.warn("Not enough mileposts in path", e); + return ResponseEntity.badRequest().body(null); + } catch (MilepostNotFoundException e) { + logger.warn("Milepost not found in route", e); + return ResponseEntity.badRequest().body(null); + } if (direction == null) { logger.warn("Invalid path direction"); return ResponseEntity.badRequest().body(null); @@ -96,12 +112,9 @@ public ResponseEntity> getBufferForPath(@RequestBody List getMilepostsForRoute(String routeId) throws JsonProcessingException { + public List getMilepostsForRoute(String routeId) throws JsonProcessingException, + RestClientException { ResponseEntity response = cdotGisService.getRouteById(routeId); - if (response == null || response.getBody() == null) { - logger.warn("Response from CDOT GIS service is null"); - return new ArrayList<>(); - } String routeJsonString = response.getBody(); ObjectMapper objectMapper = new ObjectMapper(); JsonNode rootNode = objectMapper.readTree(routeJsonString); @@ -119,22 +132,19 @@ public List getMilepostsForRoute(String routeId) throws JsonProcessing return mileposts; } - public PathDirection getPathDirection(List pathMileposts, List allMileposts) { + public PathDirection getPathDirection(List pathMileposts, List allMileposts) throws NotEnoughMilepostsException, MilepostNotFoundException { if (pathMileposts.size() < 2) { - logger.warn("Path has less than 2 mileposts"); - return null; + throw new NotEnoughMilepostsException("Path has less than 2 mileposts"); } Milepost firstMilepostInPath = pathMileposts.get(0); Milepost secondMilepostInPath = pathMileposts.get(1); int firstMilepostInPathIndex = getIndexOfMilepost(allMileposts, firstMilepostInPath); if (firstMilepostInPathIndex == -1) { - logger.warn("First milepost not found in route"); - return null; + throw new MilepostNotFoundException("First milepost not found in route"); } int secondMilepostInPathIndex = getIndexOfMilepost(allMileposts, secondMilepostInPath); if (secondMilepostInPathIndex == -1) { - logger.warn("Second milepost not found in route"); - return null; + throw new MilepostNotFoundException("Second milepost not found in route"); } if (firstMilepostInPathIndex < secondMilepostInPathIndex) { return PathDirection.ASCENDING; @@ -216,4 +226,15 @@ public static double calculateDistanceInMetersBetweenTwoPoints(double lat1, doub } } + public static class NotEnoughMilepostsException extends Exception { + public NotEnoughMilepostsException(String message) { + super(message); + } + } + + public static class MilepostNotFoundException extends Exception { + public MilepostNotFoundException(String message) { + super(message); + } + } } \ No newline at end of file diff --git a/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathControllerTest.java b/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathControllerTest.java index 1f9f085a8..eb4f7ebc6 100644 --- a/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathControllerTest.java +++ b/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathControllerTest.java @@ -1,5 +1,6 @@ package com.trihydro.cvdatacontroller.controller; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -86,7 +87,9 @@ void testGetMilepostsForRoute() throws IOException { } @Test - void testGetPathDirection_ASCENDING() throws IOException { + void testGetPathDirection_ASCENDING() + throws IOException, CdotUpstreamPathController.MilepostNotFoundException, + CdotUpstreamPathController.NotEnoughMilepostsException { // prepare List allMileposts = getMockMileposts(); Milepost mp1 = allMileposts.get(0); @@ -101,7 +104,9 @@ void testGetPathDirection_ASCENDING() throws IOException { } @Test - void testGetPathDirection_DESCENDING() throws IOException { + void testGetPathDirection_DESCENDING() + throws IOException, CdotUpstreamPathController.MilepostNotFoundException, + CdotUpstreamPathController.NotEnoughMilepostsException { // prepare List allMileposts = getMockMileposts(); Milepost mp1 = allMileposts.get(1); @@ -116,21 +121,22 @@ void testGetPathDirection_DESCENDING() throws IOException { } @Test - void testGetPathDirection_NOT_ENOUGH_MILEPOSTS() throws IOException { + void testGetPathDirection_NOT_ENOUGH_MILEPOSTS() + throws IOException { // prepare List allMileposts = getMockMileposts(); Milepost mp1 = allMileposts.get(0); List pathMileposts = List.of(mp1); // execute - PathDirection direction = uut.getPathDirection(pathMileposts, allMileposts); - - // verify - Assertions.assertNull(direction); + assertThrows(CdotUpstreamPathController.NotEnoughMilepostsException.class, () -> { + uut.getPathDirection(pathMileposts, allMileposts); + }); } @Test - void testGetPathDirection_FirstMilepostOfPathNotInAllMileposts() throws IOException { + void testGetPathDirection_FirstMilepostOfPathNotInAllMileposts() + throws IOException { // prepare List allMileposts = getMockMileposts(); Milepost mp1 = new Milepost(); @@ -141,14 +147,14 @@ void testGetPathDirection_FirstMilepostOfPathNotInAllMileposts() throws IOExcept List pathMileposts = List.of(mp1, mp2); // execute - PathDirection direction = uut.getPathDirection(pathMileposts, allMileposts); - - // verify - Assertions.assertNull(direction); + assertThrows(CdotUpstreamPathController.MilepostNotFoundException.class, () -> { + uut.getPathDirection(pathMileposts, allMileposts); + }); } @Test - void testGetPathDirection_SecondMilepostOfPathNotInAllMileposts() throws IOException { + void testGetPathDirection_SecondMilepostOfPathNotInAllMileposts() + throws IOException { // prepare List allMileposts = getMockMileposts(); Milepost mp1 = allMileposts.get(0); @@ -159,10 +165,9 @@ void testGetPathDirection_SecondMilepostOfPathNotInAllMileposts() throws IOExcep List pathMileposts = List.of(mp1, mp2); // execute - PathDirection direction = uut.getPathDirection(pathMileposts, allMileposts); - - // verify - Assertions.assertNull(direction); + assertThrows(CdotUpstreamPathController.MilepostNotFoundException.class, () -> { + uut.getPathDirection(pathMileposts, allMileposts); + }); } @Test diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CdotGisConnector.java b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CdotGisConnector.java index 85d6931c0..c0a6d1d45 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CdotGisConnector.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CdotGisConnector.java @@ -10,6 +10,7 @@ import com.trihydro.library.service.RestTemplateProvider; import org.springframework.stereotype.Component; +import org.springframework.web.client.RestClientException; @Component public class CdotGisConnector { @@ -32,23 +33,13 @@ public RestTemplateProvider getRestTemplateProvider() { return restTemplateProvider; } - public ResponseEntity getRouteById(String routeId) { + public ResponseEntity getRouteById(String routeId) throws RestClientException { String targetUrl = baseUrl + "/Route"; logger.info("Getting route with ID {} from CDOT GIS service at: {}", routeId, targetUrl); String params = "?routeId=" + routeId + "&outSR=4326&f=json"; HttpHeaders headers = new HttpHeaders(); headers.set("Accept", "application/json"); HttpEntity entity = new HttpEntity<>(headers); - ResponseEntity response; - try { - response = restTemplateProvider.GetRestTemplate().exchange(targetUrl + params, HttpMethod.GET, entity, String.class); - } catch (Exception e) { - logger.error("Error getting route with ID {} from CDOT GIS service: {}", routeId, e.getMessage(), e); - return null; - } - if (response.getBody() == null) { - logger.warn("Received null response body from CDOT GIS service"); - } - return response; + return restTemplateProvider.GetRestTemplate().exchange(targetUrl + params, HttpMethod.GET, entity, String.class); } } From 6919aff040f5d1ac49868f5d471de72b9ee82747 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Tue, 17 Dec 2024 16:45:11 -0700 Subject: [PATCH 020/168] Removed excess logging from CdotUpstreamPathController --- .../controller/CdotUpstreamPathController.java | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java index 9736315a3..ea5c7ffb6 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java @@ -40,10 +40,7 @@ public CdotUpstreamPathController(CdotGisConnector cdotGisService) { @PostMapping(value = "/get-buffer-for-path/{routeId}/{desiredDistanceInMiles:.+}") public ResponseEntity> getBufferForPath(@RequestBody List pathMileposts, @PathVariable String routeId, @PathVariable double desiredDistanceInMiles) throws JsonProcessingException { - logger.info("Number of mileposts in path in request body: {}", pathMileposts.size()); - for (Milepost milepost : pathMileposts) { - logger.debug("Milepost in path: {}, {}", milepost.getLatitude(), milepost.getLongitude()); - } + logger.info("Getting buffer for path with desired distance: {} miles", desiredDistanceInMiles); List allMileposts; try { allMileposts = getMilepostsForRoute(routeId); @@ -55,7 +52,6 @@ public ResponseEntity> getBufferForPath(@RequestBody List> getBufferForPath(@RequestBody List buffer = new ArrayList<>(); double distanceInMiles = 0; if (direction == PathDirection.ASCENDING) { - logger.info("Path direction is ascending. Start index: {}", startIndex); buffer.add(allMileposts.get(startIndex)); // add mileposts in descending order for (int i = startIndex - 1; i >= 0; i--) { @@ -87,7 +82,6 @@ public ResponseEntity> getBufferForPath(@RequestBody List> getBufferForPath(@RequestBody List Date: Tue, 17 Dec 2024 23:20:51 -0700 Subject: [PATCH 021/168] Refactored traversal logic in CdotUpstreamPathController using strategy pattern --- .../CdotUpstreamPathController.java | 174 ++++++++++++++---- 1 file changed, 142 insertions(+), 32 deletions(-) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java index ea5c7ffb6..4953cbea2 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java @@ -68,34 +68,20 @@ public ResponseEntity> getBufferForPath(@RequestBody List buffer = new ArrayList<>(); - double distanceInMiles = 0; + TraverseContext traverseContext = new TraverseContext(allMileposts, startIndex, desiredDistanceInMiles, direction); if (direction == PathDirection.ASCENDING) { - buffer.add(allMileposts.get(startIndex)); - // add mileposts in descending order - for (int i = startIndex - 1; i >= 0; i--) { - distanceInMiles = DistanceCalculator.calculateDistanceInMiles(buffer); - if (distanceInMiles >= desiredDistanceInMiles) { - break; - } - buffer.add(allMileposts.get(i)); - } + traverseContext.setTraverseStrategy(new DescendingTraverseStrategy()); } else { - // add mileposts in ascending order - for (int i = startIndex + 1; i < allMileposts.size(); i++) { - distanceInMiles = DistanceCalculator.calculateDistanceInMiles(buffer); - if (distanceInMiles >= desiredDistanceInMiles) { - break; - } - buffer.add(allMileposts.get(i)); - } + traverseContext.setTraverseStrategy(new AscendingTraverseStrategy()); } + traverseContext.performTraversal(); + List buffer = traverseContext.getBuffer(); if (buffer.size() < 2) { // at least 2 mileposts are needed to create a valid buffer path logger.warn("Buffer path has less than 2 mileposts"); return ResponseEntity.badRequest().body(null); } + double distanceInMiles = traverseContext.getDistanceInMiles(); if (distanceInMiles < desiredDistanceInMiles) { logger.warn("Buffer path has less distance than desired distance"); return ResponseEntity.badRequest().body(null); @@ -194,6 +180,142 @@ public enum PathDirection { DESCENDING } + public static class NotEnoughMilepostsException extends Exception { + public NotEnoughMilepostsException(String message) { + super(message); + } + } + + public static class MilepostNotFoundException extends Exception { + public MilepostNotFoundException(String message) { + super(message); + } + } + + /** + * Context class for traversing mileposts to get buffer path + */ + public static class TraverseContext { + private final List allMileposts; + private final int startIndex; + private final double desiredDistanceInMiles; + private final PathDirection direction; + + private TraverseStrategy traverseStrategy; + + private List buffer; + private double distanceInMiles; + + public TraverseContext(List allMileposts, int startIndex, double desiredDistanceInMiles, PathDirection direction) { + this.allMileposts = allMileposts; + this.startIndex = startIndex; + this.desiredDistanceInMiles = desiredDistanceInMiles; + this.direction = direction; + this.buffer = new ArrayList<>(); + } + + public void performTraversal() { + traverseStrategy.traverse(this); + } + + public List getAllMileposts() { + return allMileposts; + } + + public int getStartIndex() { + return startIndex; + } + + public double getDesiredDistanceInMiles() { + return desiredDistanceInMiles; + } + + public PathDirection getDirection() { + return direction; + } + + public void setTraverseStrategy(TraverseStrategy traverseStrategy) { + this.traverseStrategy = traverseStrategy; + } + + public List getBuffer() { + return buffer; + } + + public void setBuffer(List buffer) { + this.buffer = buffer; + } + + public double getDistanceInMiles() { + return distanceInMiles; + } + + public void setDistanceInMiles(double distanceInMiles) { + this.distanceInMiles = distanceInMiles; + } + } + + /** + * Interface for traverse strategy to get buffer path + */ + public interface TraverseStrategy { + void traverse(TraverseContext context); + } + + /** + * Traverse strategy to get buffer path by traversing the mileposts in ascending + * direction from a starting milepost. + */ + public static class AscendingTraverseStrategy implements TraverseStrategy { + + @Override + public void traverse(TraverseContext context) { + List buffer = new ArrayList<>(); + List allMileposts = context.getAllMileposts(); + int startIndex = context.getStartIndex(); + double desiredDistanceInMiles = context.getDesiredDistanceInMiles(); + double distanceInMiles = 0; + + buffer.add(allMileposts.get(startIndex)); + for (int i = startIndex + 1; i < allMileposts.size(); i++) { + distanceInMiles = DistanceCalculator.calculateDistanceInMiles(buffer); + if (distanceInMiles >= desiredDistanceInMiles) { + break; + } + buffer.add(allMileposts.get(i)); + } + context.setBuffer(buffer); + context.setDistanceInMiles(distanceInMiles); + } + } + + /** + * Traverse strategy to get buffer path by traversing the mileposts in descending + * direction from a starting milepost. + */ + public static class DescendingTraverseStrategy implements TraverseStrategy { + + @Override + public void traverse(TraverseContext context) { + List buffer = new ArrayList<>(); + List allMileposts = context.getAllMileposts(); + int startIndex = context.getStartIndex(); + double desiredDistanceInMiles = context.getDesiredDistanceInMiles(); + double distanceInMiles = 0; + + buffer.add(allMileposts.get(startIndex)); + for (int i = startIndex - 1; i >= 0; i--) { + distanceInMiles = DistanceCalculator.calculateDistanceInMiles(buffer); + if (distanceInMiles >= desiredDistanceInMiles) { + break; + } + buffer.add(allMileposts.get(i)); + } + context.setBuffer(buffer); + context.setDistanceInMiles(distanceInMiles); + } + } + /** * Helper class to calculate distance between two points and total distance of a buffer path */ @@ -221,16 +343,4 @@ public static double calculateDistanceInMetersBetweenTwoPoints(double lat1, doub return R * c; // Distance in meters } } - - public static class NotEnoughMilepostsException extends Exception { - public NotEnoughMilepostsException(String message) { - super(message); - } - } - - public static class MilepostNotFoundException extends Exception { - public MilepostNotFoundException(String message) { - super(message); - } - } } \ No newline at end of file From 82b5dd76662cb8b6424ce44642a13baac8df19e0 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Tue, 17 Dec 2024 23:22:00 -0700 Subject: [PATCH 022/168] Reformatted CdotUpstreamPathController and CdotUpstreamPathControllerTest classes --- .../CdotUpstreamPathController.java | 160 ++++++++++-------- .../CdotUpstreamPathControllerTest.java | 54 ++++-- 2 files changed, 121 insertions(+), 93 deletions(-) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java index 4953cbea2..bed696599 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java @@ -38,7 +38,9 @@ public CdotUpstreamPathController(CdotGisConnector cdotGisService) { } @PostMapping(value = "/get-buffer-for-path/{routeId}/{desiredDistanceInMiles:.+}") - public ResponseEntity> getBufferForPath(@RequestBody List pathMileposts, @PathVariable String routeId, @PathVariable double desiredDistanceInMiles) throws + public ResponseEntity> getBufferForPath(@RequestBody List pathMileposts, + @PathVariable String routeId, @PathVariable + double desiredDistanceInMiles) throws JsonProcessingException { logger.info("Getting buffer for path with desired distance: {} miles", desiredDistanceInMiles); List allMileposts; @@ -68,7 +70,8 @@ public ResponseEntity> getBufferForPath(@RequestBody List getMilepostsForRoute(String routeId) throws JsonProcessing Milepost milepost = new Milepost(); milepost.setCommonName(routeId); BigDecimal latitude = new BigDecimal(node.get(1).asText()).setScale(14, RoundingMode.HALF_UP); - BigDecimal longitude = new BigDecimal(node.get(0).asText()).setScale(14, RoundingMode.HALF_UP); + BigDecimal longitude = + new BigDecimal(node.get(0).asText()).setScale(14, RoundingMode.HALF_UP); milepost.setLatitude(latitude); milepost.setLongitude(longitude); mileposts.add(milepost); @@ -114,7 +118,8 @@ public List getMilepostsForRoute(String routeId) throws JsonProcessing return mileposts; } - public PathDirection getPathDirection(List pathMileposts, List allMileposts) throws NotEnoughMilepostsException, MilepostNotFoundException { + public PathDirection getPathDirection(List pathMileposts, List allMileposts) + throws NotEnoughMilepostsException, MilepostNotFoundException { if (pathMileposts.size() < 2) { throw new NotEnoughMilepostsException("Path has less than 2 mileposts"); } @@ -156,7 +161,8 @@ private int getIndexOfMilepost(List mileposts, Milepost milepost) { private String convertMilepostsToGeojsonString(List mileposts) { StringBuilder geojsonStringBuilder = new StringBuilder(); - geojsonStringBuilder.append("{ \"type\": \"FeatureCollection\", \"features\": [{ \"type\": \"Feature\", \"geometry\": { \"type\": \"LineString\", \"coordinates\": ["); + geojsonStringBuilder.append( + "{ \"type\": \"FeatureCollection\", \"features\": [{ \"type\": \"Feature\", \"geometry\": { \"type\": \"LineString\", \"coordinates\": ["); for (int i = 0; i < mileposts.size(); i++) { Milepost milepost = mileposts.get(i); geojsonStringBuilder.append("["); @@ -181,85 +187,86 @@ public enum PathDirection { } public static class NotEnoughMilepostsException extends Exception { - public NotEnoughMilepostsException(String message) { + public NotEnoughMilepostsException(String message) { super(message); - } + } } public static class MilepostNotFoundException extends Exception { - public MilepostNotFoundException(String message) { + public MilepostNotFoundException(String message) { super(message); - } + } } /** * Context class for traversing mileposts to get buffer path */ public static class TraverseContext { - private final List allMileposts; - private final int startIndex; - private final double desiredDistanceInMiles; - private final PathDirection direction; - - private TraverseStrategy traverseStrategy; - - private List buffer; - private double distanceInMiles; - - public TraverseContext(List allMileposts, int startIndex, double desiredDistanceInMiles, PathDirection direction) { - this.allMileposts = allMileposts; - this.startIndex = startIndex; - this.desiredDistanceInMiles = desiredDistanceInMiles; - this.direction = direction; - this.buffer = new ArrayList<>(); - } + private final List allMileposts; + private final int startIndex; + private final double desiredDistanceInMiles; + private final PathDirection direction; + + private TraverseStrategy traverseStrategy; + + private List buffer; + private double distanceInMiles; + + public TraverseContext(List allMileposts, int startIndex, + double desiredDistanceInMiles, PathDirection direction) { + this.allMileposts = allMileposts; + this.startIndex = startIndex; + this.desiredDistanceInMiles = desiredDistanceInMiles; + this.direction = direction; + this.buffer = new ArrayList<>(); + } - public void performTraversal() { - traverseStrategy.traverse(this); - } + public void performTraversal() { + traverseStrategy.traverse(this); + } - public List getAllMileposts() { - return allMileposts; - } + public List getAllMileposts() { + return allMileposts; + } - public int getStartIndex() { - return startIndex; - } + public int getStartIndex() { + return startIndex; + } - public double getDesiredDistanceInMiles() { - return desiredDistanceInMiles; - } + public double getDesiredDistanceInMiles() { + return desiredDistanceInMiles; + } - public PathDirection getDirection() { - return direction; - } + public PathDirection getDirection() { + return direction; + } - public void setTraverseStrategy(TraverseStrategy traverseStrategy) { - this.traverseStrategy = traverseStrategy; - } + public void setTraverseStrategy(TraverseStrategy traverseStrategy) { + this.traverseStrategy = traverseStrategy; + } - public List getBuffer() { - return buffer; - } + public List getBuffer() { + return buffer; + } - public void setBuffer(List buffer) { - this.buffer = buffer; - } + public void setBuffer(List buffer) { + this.buffer = buffer; + } - public double getDistanceInMiles() { - return distanceInMiles; - } + public double getDistanceInMiles() { + return distanceInMiles; + } - public void setDistanceInMiles(double distanceInMiles) { - this.distanceInMiles = distanceInMiles; - } + public void setDistanceInMiles(double distanceInMiles) { + this.distanceInMiles = distanceInMiles; + } } /** * Interface for traverse strategy to get buffer path */ public interface TraverseStrategy { - void traverse(TraverseContext context); + void traverse(TraverseContext context); } /** @@ -297,22 +304,22 @@ public static class DescendingTraverseStrategy implements TraverseStrategy { @Override public void traverse(TraverseContext context) { - List buffer = new ArrayList<>(); - List allMileposts = context.getAllMileposts(); - int startIndex = context.getStartIndex(); - double desiredDistanceInMiles = context.getDesiredDistanceInMiles(); - double distanceInMiles = 0; - - buffer.add(allMileposts.get(startIndex)); - for (int i = startIndex - 1; i >= 0; i--) { - distanceInMiles = DistanceCalculator.calculateDistanceInMiles(buffer); - if (distanceInMiles >= desiredDistanceInMiles) { - break; - } - buffer.add(allMileposts.get(i)); + List buffer = new ArrayList<>(); + List allMileposts = context.getAllMileposts(); + int startIndex = context.getStartIndex(); + double desiredDistanceInMiles = context.getDesiredDistanceInMiles(); + double distanceInMiles = 0; + + buffer.add(allMileposts.get(startIndex)); + for (int i = startIndex - 1; i >= 0; i--) { + distanceInMiles = DistanceCalculator.calculateDistanceInMiles(buffer); + if (distanceInMiles >= desiredDistanceInMiles) { + break; } - context.setBuffer(buffer); - context.setDistanceInMiles(distanceInMiles); + buffer.add(allMileposts.get(i)); + } + context.setBuffer(buffer); + context.setDistanceInMiles(distanceInMiles); } } @@ -325,14 +332,17 @@ public static double calculateDistanceInMiles(List buffer) { for (int i = 0; i < buffer.size() - 1; i++) { Milepost mp1 = buffer.get(i); Milepost mp2 = buffer.get(i + 1); - double distanceInMeters = DistanceCalculator.calculateDistanceInMetersBetweenTwoPoints(mp1.getLatitude().doubleValue(), - mp1.getLongitude().doubleValue(), mp2.getLatitude().doubleValue(), mp2.getLongitude().doubleValue()); + double distanceInMeters = DistanceCalculator.calculateDistanceInMetersBetweenTwoPoints( + mp1.getLatitude().doubleValue(), + mp1.getLongitude().doubleValue(), mp2.getLatitude().doubleValue(), + mp2.getLongitude().doubleValue()); distanceInMiles += distanceInMeters / 1609.34; } return distanceInMiles; } - public static double calculateDistanceInMetersBetweenTwoPoints(double lat1, double lon1, double lat2, double lon2) { + public static double calculateDistanceInMetersBetweenTwoPoints(double lat1, double lon1, + double lat2, double lon2) { final int R = 6371000; // Radius of the earth in meters double latDistance = Math.toRadians(lat2 - lat1); double lonDistance = Math.toRadians(lon2 - lon1); diff --git a/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathControllerTest.java b/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathControllerTest.java index eb4f7ebc6..73a7caf36 100644 --- a/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathControllerTest.java +++ b/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathControllerTest.java @@ -30,7 +30,8 @@ class CdotUpstreamPathControllerTest { private final String ROUTE_ID = "025A"; // I-25 - private final String PATH_TO_ROUTE_JSON_TEST_DATA = "src/test/resources/com/trihydro/cvdatacontroller/controller/cdotRouteResponseForI25_First30Mileposts.json"; + private final String PATH_TO_ROUTE_JSON_TEST_DATA = + "src/test/resources/com/trihydro/cvdatacontroller/controller/cdotRouteResponseForI25_First30Mileposts.json"; @Mock CdotGisConnector cdotGisService = Mockito.mock(CdotGisConnector.class); @@ -39,7 +40,8 @@ class CdotUpstreamPathControllerTest { CdotUpstreamPathController uut; List getMockMileposts() throws IOException { - String routeJsonString = new String(Files.readAllBytes(Paths.get(PATH_TO_ROUTE_JSON_TEST_DATA))); + String routeJsonString = + new String(Files.readAllBytes(Paths.get(PATH_TO_ROUTE_JSON_TEST_DATA))); ObjectMapper objectMapper = new ObjectMapper(); JsonNode rootNode = objectMapper.readTree(routeJsonString); JsonNode pathNode = rootNode.path("features").get(0).path("geometry").path("paths").get(0); @@ -48,7 +50,8 @@ List getMockMileposts() throws IOException { Milepost milepost = new Milepost(); milepost.setCommonName(ROUTE_ID); BigDecimal latitude = new BigDecimal(node.get(1).asText()).setScale(14, RoundingMode.HALF_UP); - BigDecimal longitude = new BigDecimal(node.get(0).asText()).setScale(14, RoundingMode.HALF_UP); + BigDecimal longitude = + new BigDecimal(node.get(0).asText()).setScale(14, RoundingMode.HALF_UP); milepost.setLatitude(latitude); milepost.setLongitude(longitude); mileposts.add(milepost); @@ -64,7 +67,8 @@ void setUp() { @Test void testGetMilepostsForRoute() throws IOException { // prepare - String routeJsonString = new String(Files.readAllBytes(Paths.get(PATH_TO_ROUTE_JSON_TEST_DATA))); + String routeJsonString = + new String(Files.readAllBytes(Paths.get(PATH_TO_ROUTE_JSON_TEST_DATA))); ResponseEntity mockResponse = new ResponseEntity<>(routeJsonString, HttpStatus.OK); when(cdotGisService.getRouteById(ROUTE_ID)).thenReturn(mockResponse); List expectedMileposts = getMockMileposts(); @@ -173,7 +177,8 @@ void testGetPathDirection_SecondMilepostOfPathNotInAllMileposts() @Test void testGetBufferForPath_Ascending_Success() throws IOException { // prepare - String routeJsonString = new String(Files.readAllBytes(Paths.get(PATH_TO_ROUTE_JSON_TEST_DATA))); + String routeJsonString = + new String(Files.readAllBytes(Paths.get(PATH_TO_ROUTE_JSON_TEST_DATA))); ResponseEntity mockResponse = new ResponseEntity<>(routeJsonString, HttpStatus.OK); when(cdotGisService.getRouteById(ROUTE_ID)).thenReturn(mockResponse); @@ -185,21 +190,25 @@ void testGetBufferForPath_Ascending_Success() throws IOException { double desiredDistanceInMiles = 0.5; // execute - ResponseEntity> response = uut.getBufferForPath(pathMileposts, ROUTE_ID, desiredDistanceInMiles); + ResponseEntity> response = + uut.getBufferForPath(pathMileposts, ROUTE_ID, desiredDistanceInMiles); // verify List buffer = response.getBody(); assert buffer != null; Assertions.assertFalse(buffer.isEmpty()); double distanceInMiles = getDistanceInMiles(buffer); - Assertions.assertTrue(distanceInMiles >= desiredDistanceInMiles); // buffer should be at least as long as desired distance - Assertions.assertTrue(distanceInMiles <= desiredDistanceInMiles + 1); // buffer should not be much longer than desired distance + Assertions.assertTrue(distanceInMiles >= + desiredDistanceInMiles); // buffer should be at least as long as desired distance + Assertions.assertTrue(distanceInMiles <= + desiredDistanceInMiles + 1); // buffer should not be much longer than desired distance } @Test void testGetBufferForPath_Ascending_Failure_EndOfAllMilepostsReached() throws IOException { // prepare - String routeJsonString = new String(Files.readAllBytes(Paths.get(PATH_TO_ROUTE_JSON_TEST_DATA))); + String routeJsonString = + new String(Files.readAllBytes(Paths.get(PATH_TO_ROUTE_JSON_TEST_DATA))); ResponseEntity mockResponse = new ResponseEntity<>(routeJsonString, HttpStatus.OK); when(cdotGisService.getRouteById(ROUTE_ID)).thenReturn(mockResponse); @@ -211,7 +220,8 @@ void testGetBufferForPath_Ascending_Failure_EndOfAllMilepostsReached() throws IO double desiredDistanceInMiles = 5.0; // execute - ResponseEntity> response = uut.getBufferForPath(pathMileposts, ROUTE_ID, desiredDistanceInMiles); + ResponseEntity> response = + uut.getBufferForPath(pathMileposts, ROUTE_ID, desiredDistanceInMiles); // verify List buffer = response.getBody(); @@ -221,7 +231,8 @@ void testGetBufferForPath_Ascending_Failure_EndOfAllMilepostsReached() throws IO @Test void testGetBufferForPath_Descending_Success() throws IOException { // prepare - String routeJsonString = new String(Files.readAllBytes(Paths.get(PATH_TO_ROUTE_JSON_TEST_DATA))); + String routeJsonString = + new String(Files.readAllBytes(Paths.get(PATH_TO_ROUTE_JSON_TEST_DATA))); ResponseEntity mockResponse = new ResponseEntity<>(routeJsonString, HttpStatus.OK); when(cdotGisService.getRouteById(ROUTE_ID)).thenReturn(mockResponse); @@ -233,21 +244,25 @@ void testGetBufferForPath_Descending_Success() throws IOException { double desiredDistanceInMiles = 0.5; // execute - ResponseEntity> response = uut.getBufferForPath(pathMileposts, ROUTE_ID, desiredDistanceInMiles); + ResponseEntity> response = + uut.getBufferForPath(pathMileposts, ROUTE_ID, desiredDistanceInMiles); // verify List buffer = response.getBody(); assert buffer != null; Assertions.assertFalse(buffer.isEmpty()); double distanceInMiles = getDistanceInMiles(buffer); - Assertions.assertTrue(distanceInMiles >= desiredDistanceInMiles); // buffer should be at least as long as desired distance - Assertions.assertTrue(distanceInMiles <= desiredDistanceInMiles + 1); // buffer should not be much longer than desired distance + Assertions.assertTrue(distanceInMiles >= + desiredDistanceInMiles); // buffer should be at least as long as desired distance + Assertions.assertTrue(distanceInMiles <= + desiredDistanceInMiles + 1); // buffer should not be much longer than desired distance } @Test void testGetBufferForPath_Descending_Failure_EndOfAllMilepostsReached() throws IOException { // prepare - String routeJsonString = new String(Files.readAllBytes(Paths.get(PATH_TO_ROUTE_JSON_TEST_DATA))); + String routeJsonString = + new String(Files.readAllBytes(Paths.get(PATH_TO_ROUTE_JSON_TEST_DATA))); ResponseEntity mockResponse = new ResponseEntity<>(routeJsonString, HttpStatus.OK); when(cdotGisService.getRouteById(ROUTE_ID)).thenReturn(mockResponse); @@ -259,7 +274,8 @@ void testGetBufferForPath_Descending_Failure_EndOfAllMilepostsReached() throws I double desiredDistanceInMiles = 5.0; // execute - ResponseEntity> response = uut.getBufferForPath(pathMileposts, ROUTE_ID, desiredDistanceInMiles); + ResponseEntity> response = + uut.getBufferForPath(pathMileposts, ROUTE_ID, desiredDistanceInMiles); // verify List buffer = response.getBody(); @@ -269,7 +285,8 @@ void testGetBufferForPath_Descending_Failure_EndOfAllMilepostsReached() throws I @Test void testGetBufferForPath_PathDirectionIsNull() throws IOException { // prepare - String routeJsonString = new String(Files.readAllBytes(Paths.get(PATH_TO_ROUTE_JSON_TEST_DATA))); + String routeJsonString = + new String(Files.readAllBytes(Paths.get(PATH_TO_ROUTE_JSON_TEST_DATA))); ResponseEntity mockResponse = new ResponseEntity<>(routeJsonString, HttpStatus.OK); when(cdotGisService.getRouteById(ROUTE_ID)).thenReturn(mockResponse); @@ -280,7 +297,8 @@ void testGetBufferForPath_PathDirectionIsNull() throws IOException { int desiredDistanceInMiles = 5; // execute - ResponseEntity> response = uut.getBufferForPath(pathMileposts, ROUTE_ID, desiredDistanceInMiles); + ResponseEntity> response = + uut.getBufferForPath(pathMileposts, ROUTE_ID, desiredDistanceInMiles); // verify List buffer = response.getBody(); From 1a6504e830eaa0a4a599b860e5ca7bb920801116 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Tue, 17 Dec 2024 23:35:15 -0700 Subject: [PATCH 023/168] Introduced AbstractTraverseStrategy to reduce code duplication and improve maintainability --- .../CdotUpstreamPathController.java | 41 +++++++++---------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java index bed696599..3660c215b 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java @@ -271,9 +271,11 @@ public interface TraverseStrategy { /** * Traverse strategy to get buffer path by traversing the mileposts in ascending - * direction from a starting milepost. + * or descending direction from a starting milepost. */ - public static class AscendingTraverseStrategy implements TraverseStrategy { + public abstract static class AbstractTraverseStrategy implements TraverseStrategy { + + protected abstract int getNextIndex(int currentIndex); @Override public void traverse(TraverseContext context) { @@ -284,7 +286,7 @@ public void traverse(TraverseContext context) { double distanceInMiles = 0; buffer.add(allMileposts.get(startIndex)); - for (int i = startIndex + 1; i < allMileposts.size(); i++) { + for (int i = getNextIndex(startIndex); i >= 0 && i < allMileposts.size(); i = getNextIndex(i)) { distanceInMiles = DistanceCalculator.calculateDistanceInMiles(buffer); if (distanceInMiles >= desiredDistanceInMiles) { break; @@ -297,29 +299,26 @@ public void traverse(TraverseContext context) { } /** - * Traverse strategy to get buffer path by traversing the mileposts in descending + * Traverse strategy to get buffer path by traversing the mileposts in ascending * direction from a starting milepost. */ - public static class DescendingTraverseStrategy implements TraverseStrategy { + public static class AscendingTraverseStrategy extends AbstractTraverseStrategy { @Override - public void traverse(TraverseContext context) { - List buffer = new ArrayList<>(); - List allMileposts = context.getAllMileposts(); - int startIndex = context.getStartIndex(); - double desiredDistanceInMiles = context.getDesiredDistanceInMiles(); - double distanceInMiles = 0; + protected int getNextIndex(int currentIndex) { + return currentIndex + 1; + } + } - buffer.add(allMileposts.get(startIndex)); - for (int i = startIndex - 1; i >= 0; i--) { - distanceInMiles = DistanceCalculator.calculateDistanceInMiles(buffer); - if (distanceInMiles >= desiredDistanceInMiles) { - break; - } - buffer.add(allMileposts.get(i)); - } - context.setBuffer(buffer); - context.setDistanceInMiles(distanceInMiles); + /** + * Traverse strategy to get buffer path by traversing the mileposts in descending + * direction from a starting milepost. + */ + public static class DescendingTraverseStrategy extends AbstractTraverseStrategy { + + @Override + protected int getNextIndex(int currentIndex) { + return currentIndex - 1; } } From 060ef0134997b2ef76020215a5de90b0fa94459f Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Thu, 19 Dec 2024 14:37:40 -0700 Subject: [PATCH 024/168] Updated DistanceCalculator to use Milepost.angularDistanceTo() for calculating distance between mileposts --- .../CdotUpstreamPathController.java | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java index 3660c215b..e86176ce3 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java @@ -326,30 +326,17 @@ protected int getNextIndex(int currentIndex) { * Helper class to calculate distance between two points and total distance of a buffer path */ public static class DistanceCalculator { + final static int R = 6371000; // Radius of the earth in meters + public static double calculateDistanceInMiles(List buffer) { double distanceInMiles = 0; for (int i = 0; i < buffer.size() - 1; i++) { Milepost mp1 = buffer.get(i); Milepost mp2 = buffer.get(i + 1); - double distanceInMeters = DistanceCalculator.calculateDistanceInMetersBetweenTwoPoints( - mp1.getLatitude().doubleValue(), - mp1.getLongitude().doubleValue(), mp2.getLatitude().doubleValue(), - mp2.getLongitude().doubleValue()); + double distanceInMeters = mp1.angularDistanceTo(mp2) * R; distanceInMiles += distanceInMeters / 1609.34; } return distanceInMiles; } - - public static double calculateDistanceInMetersBetweenTwoPoints(double lat1, double lon1, - double lat2, double lon2) { - final int R = 6371000; // Radius of the earth in meters - double latDistance = Math.toRadians(lat2 - lat1); - double lonDistance = Math.toRadians(lon2 - lon1); - double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2) - + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) - * Math.sin(lonDistance / 2) * Math.sin(lonDistance / 2); - double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); - return R * c; // Distance in meters - } } } \ No newline at end of file From d8eb78dcc6359df1a6865fa9f0f65d7cb31d92bd Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Thu, 19 Dec 2024 16:05:04 -0700 Subject: [PATCH 025/168] Added JavaDocs for AbstractTraverseStrategy.traverse() and CdotUpstreamPathController.getBufferForPath() methods --- .../CdotUpstreamPathController.java | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java index e86176ce3..9cb55c62e 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java @@ -37,6 +37,24 @@ public CdotUpstreamPathController(CdotGisConnector cdotGisService) { this.cdotGisService = cdotGisService; } + /** + * Retrieves a buffer path of mileposts for a given route and desired distance. + * + * This method takes a list of path mileposts, a route ID, and a desired distance in miles. + * It fetches all mileposts for the specified route and determines the direction of the path. + * Then, it traverses the mileposts to create a buffer path that meets the desired distance. + * + * Note: The current implementation pulls back the entire route linestring in one request. + * There is a possibility to optimize this by hitting the geo REST service multiple times + * to fetch smaller segments of the route. However, this method will proceed with the current + * implementation unless performance issues are observed. + * + * @param pathMileposts the list of mileposts defining the path + * @param routeId the ID of the route + * @param desiredDistanceInMiles the desired distance for the buffer path in miles + * @return a ResponseEntity containing the buffer path of mileposts or a bad request status if an error occurs + * @throws JsonProcessingException if there is an error processing the JSON response from the geo service + */ @PostMapping(value = "/get-buffer-for-path/{routeId}/{desiredDistanceInMiles:.+}") public ResponseEntity> getBufferForPath(@RequestBody List pathMileposts, @PathVariable String routeId, @PathVariable @@ -277,6 +295,18 @@ public abstract static class AbstractTraverseStrategy implements TraverseStrateg protected abstract int getNextIndex(int currentIndex); + /** + * Traverses the mileposts to create a buffer path. + * + * This method iterates through the mileposts starting from the given start index + * and adds them to the buffer until the desired distance in miles is reached. + * + * Note: The current implementation recalculates the total distance of the buffer + * after adding each milepost, which can be inefficient. If performance issues are + * observed, consider optimizing this calculation. + * + * @param context the context containing the mileposts, start index, desired distance, and direction + */ @Override public void traverse(TraverseContext context) { List buffer = new ArrayList<>(); From abd68c7c0d86d817e50569c97804b592db5163a5 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Thu, 19 Dec 2024 16:13:08 -0700 Subject: [PATCH 026/168] Added JavaDocs for CdotGisConnector.getRouteById() and CdotUpstreamPathController.getMilepostsForRoute() methods --- .../controller/CdotUpstreamPathController.java | 13 +++++++++++++ .../trihydro/library/helpers/CdotGisConnector.java | 11 +++++++++++ 2 files changed, 24 insertions(+) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java index 9cb55c62e..c1ea0d7b9 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java @@ -115,6 +115,19 @@ public ResponseEntity> getBufferForPath(@RequestBody ListThis method uses `CdotGisService.getRouteById()` to retrieve the route information + * in JSON format. The JSON response contains all the latitude and longitude points + * in the route. This information is then extracted into the `Milepost` model and + * returned as a list of mileposts.

+ * + * @param routeId the ID of the route to retrieve mileposts for + * @return a list of `Milepost` objects representing the mileposts in the route + * @throws JsonProcessingException if there is an error processing the JSON response + * @throws RestClientException if an error occurs while making the request + */ public List getMilepostsForRoute(String routeId) throws JsonProcessingException, RestClientException { ResponseEntity response = cdotGisService.getRouteById(routeId); diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CdotGisConnector.java b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CdotGisConnector.java index c0a6d1d45..06c4b49a3 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CdotGisConnector.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CdotGisConnector.java @@ -33,6 +33,17 @@ public RestTemplateProvider getRestTemplateProvider() { return restTemplateProvider; } + /** + * Retrieves the route information from the CDOT GIS service by route ID. + * + *

This method sends a GET request to the CDOT GIS service to retrieve the route information + * in JSON format. The JSON response includes every latitude and longitude point associated + * with the specified route, such as I-25.

+ * + * @param routeId the ID of the route to retrieve + * @return a ResponseEntity containing the JSON response from the CDOT GIS service + * @throws RestClientException if an error occurs while making the request + */ public ResponseEntity getRouteById(String routeId) throws RestClientException { String targetUrl = baseUrl + "/Route"; logger.info("Getting route with ID {} from CDOT GIS service at: {}", routeId, targetUrl); From 3bbcba4b7f76b33da8ac37cf1ff885ec2146f8f4 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Thu, 19 Dec 2024 16:32:16 -0700 Subject: [PATCH 027/168] Updated CDOT GIS endpoint to use `Routes_withDEC` instead of `Routes` --- ...tRouteResponseForI25_First30Mileposts.json | 154 ++++++++++++++---- .../library/helpers/CdotGisConnector.java | 2 +- .../library/helpers/CdotGisConnectorTest.java | 4 +- 3 files changed, 125 insertions(+), 35 deletions(-) diff --git a/cv-data-controller/src/test/resources/com/trihydro/cvdatacontroller/controller/cdotRouteResponseForI25_First30Mileposts.json b/cv-data-controller/src/test/resources/com/trihydro/cvdatacontroller/controller/cdotRouteResponseForI25_First30Mileposts.json index e8b2167b6..7306d9b14 100644 --- a/cv-data-controller/src/test/resources/com/trihydro/cvdatacontroller/controller/cdotRouteResponseForI25_First30Mileposts.json +++ b/cv-data-controller/src/test/resources/com/trihydro/cvdatacontroller/controller/cdotRouteResponseForI25_First30Mileposts.json @@ -47,44 +47,134 @@ "Route": "025A", "MMin": -0, "MMax": 298.87900000000002, - "SHAPE_Length": 4.4977027447245632 + "SHAPE_Length": 4.4977027441765571 }, "geometry": { "paths": [ [ - [-104.48045588599996, 36.993878229000074], - [-104.48050318099996, 36.994486231000053], - [-104.48065092399997, 36.995038290000025], - [-104.48070509599995, 36.99524070700005], - [-104.48080757599996, 36.995446935000075], - [-104.48084011699996, 36.995512422000047], - [-104.48109407099997, 36.995913712000061], - [-104.48129848899998, 36.996175908000055], - [-104.48187755499998, 36.996844846000045], - [-104.48219789199999, 36.99729805000004], - [-104.48243650499995, 36.997797080000055], - [-104.48248663299995, 36.997977548000051], - [-104.48255274399997, 36.998345181000047], - [-104.48256583399996, 36.998729556000058], - [-104.48252486699994, 36.999069289000033], - [-104.48251842099995, 36.999122742000054], - [-104.48241381599996, 36.999516043000028], - [-104.48041568299999, 37.005994416000078], - [-104.48016812399999, 37.006796975000043], - [-104.48006938599997, 37.007213984000032], - [-104.48000987099999, 37.007636323000042], - [-104.48000904399998, 37.007642192000048], - [-104.47999405199994, 37.00807076600006], - [-104.48002256199999, 37.008504324000057], - [-104.48009628499995, 37.008939769000051], - [-104.48021678199996, 37.00937487300007], - [-104.48030103699995, 37.009608998000033], - [-104.48237161199995, 37.015362141000026], - [-104.48260622599997, 37.01598049200004], - [-104.48277556599999, 37.016368184000044] + [ + -104.48045588599996, + 36.993878229000074 + ], + [ + -104.48050318099996, + 36.994486232000042 + ], + [ + -104.48065092399997, + 36.995038290000025 + ], + [ + -104.48070509599995, + 36.99524070700005 + ], + [ + -104.48080757499997, + 36.995446935000075 + ], + [ + -104.48084011699996, + 36.995512422000047 + ], + [ + -104.48109407099997, + 36.995913712000061 + ], + [ + -104.48129848999997, + 36.996175908000055 + ], + [ + -104.48187755499998, + 36.996844846000045 + ], + [ + -104.48219789199999, + 36.99729805000004 + ], + [ + -104.48243650499995, + 36.997797080000055 + ], + [ + -104.48248663299995, + 36.997977548000051 + ], + [ + -104.48255274299999, + 36.998345181000047 + ], + [ + -104.48256583299997, + 36.998729557000047 + ], + [ + -104.48252486699994, + 36.999069289000033 + ], + [ + -104.48251842099995, + 36.999122742000054 + ], + [ + -104.48241381599996, + 36.999516043000028 + ], + [ + -104.48041568299999, + 37.005994416000078 + ], + [ + -104.48016812399999, + 37.006796975000043 + ], + [ + -104.48006938599997, + 37.007213985000078 + ], + [ + -104.48000987099999, + 37.007636323000042 + ], + [ + -104.48000904399998, + 37.007642192000048 + ], + [ + -104.47999405199994, + 37.00807076600006 + ], + [ + -104.48002256199999, + 37.008504324000057 + ], + [ + -104.48009628499995, + 37.008939769000051 + ], + [ + -104.48021678199996, + 37.009374874000059 + ], + [ + -104.48030103699995, + 37.009608998000033 + ], + [ + -104.48237161199995, + 37.015362141000026 + ], + [ + -104.48260622599997, + 37.01598049100005 + ], + [ + -104.48277556599999, + 37.016368185000033 + ] ] ] } } ] -} +} \ No newline at end of file diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CdotGisConnector.java b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CdotGisConnector.java index 06c4b49a3..8067cdc42 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CdotGisConnector.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CdotGisConnector.java @@ -14,7 +14,7 @@ @Component public class CdotGisConnector { - private final String baseUrl = "https://dtdapps.coloradodot.info/arcgis/rest/services/LRS/Routes/MapServer/exts/CdotLrsAccessRounded"; + private final String baseUrl = "https://dtdapps.coloradodot.info/arcgis/rest/services/LRS/Routes_withDEC/MapServer/exts/CdotLrsAccessRounded"; private final RestTemplateProvider restTemplateProvider; diff --git a/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CdotGisConnectorTest.java b/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CdotGisConnectorTest.java index ec399a427..354431cdb 100644 --- a/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CdotGisConnectorTest.java +++ b/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CdotGisConnectorTest.java @@ -18,7 +18,7 @@ class CdotGisConnectorTest extends BaseServiceTest { @InjectMocks private CdotGisConnector uut; - private final String expectedBaseUrl = "https://dtdapps.coloradodot.info/arcgis/rest/services/LRS/Routes/MapServer/exts/CdotLrsAccessRounded"; + private final String expectedBaseUrl = "https://dtdapps.coloradodot.info/arcgis/rest/services/LRS/Routes_withDEC/MapServer/exts/CdotLrsAccessRounded"; @Test void testInitialization() { @@ -29,7 +29,7 @@ void testInitialization() { @Test void testGetBaseUrl() { - Assertions.assertEquals("https://dtdapps.coloradodot.info/arcgis/rest/services/LRS/Routes/MapServer/exts/CdotLrsAccessRounded", uut.getBaseUrl()); + Assertions.assertEquals("https://dtdapps.coloradodot.info/arcgis/rest/services/LRS/Routes_withDEC/MapServer/exts/CdotLrsAccessRounded", uut.getBaseUrl()); } @Test From 778b456902ab05595e2dadebacb9e98b30d028fd Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Sun, 29 Dec 2024 09:42:25 -0700 Subject: [PATCH 028/168] Removed `@Autowired` annotation from CdotUpstreamPathController constructor --- .../cvdatacontroller/controller/CdotUpstreamPathController.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java index c1ea0d7b9..ffc600920 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java @@ -10,7 +10,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.PathVariable; @@ -32,7 +31,6 @@ public class CdotUpstreamPathController extends BaseController { private final Logger logger = LoggerFactory.getLogger(CdotUpstreamPathController.class); - @Autowired public CdotUpstreamPathController(CdotGisConnector cdotGisService) { this.cdotGisService = cdotGisService; } From 5ccc58ce628d5d039bdf6150de8bc8ce1f446216 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Sun, 29 Dec 2024 09:43:17 -0700 Subject: [PATCH 029/168] Removed `@Autowired` annotation from CdotGisConnector constructor --- .../java/com/trihydro/library/helpers/CdotGisConnector.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CdotGisConnector.java b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CdotGisConnector.java index 8067cdc42..9271ad75f 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CdotGisConnector.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CdotGisConnector.java @@ -2,7 +2,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; @@ -20,7 +19,6 @@ public class CdotGisConnector { private final Logger logger = LoggerFactory.getLogger(CdotGisConnector.class); - @Autowired public CdotGisConnector(RestTemplateProvider _restTemplateProvider) { this.restTemplateProvider = _restTemplateProvider; } From 03be8861a1920195a85f2b578bfe567e81e72929 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Sun, 29 Dec 2024 09:44:24 -0700 Subject: [PATCH 030/168] Used `expectedBaseUrl` instead of hardcoded string in CdotGisConnectorTest.testGetBaseUrl() --- .../java/com/trihydro/library/helpers/CdotGisConnectorTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CdotGisConnectorTest.java b/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CdotGisConnectorTest.java index 354431cdb..2ad1dd7bf 100644 --- a/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CdotGisConnectorTest.java +++ b/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CdotGisConnectorTest.java @@ -29,7 +29,7 @@ void testInitialization() { @Test void testGetBaseUrl() { - Assertions.assertEquals("https://dtdapps.coloradodot.info/arcgis/rest/services/LRS/Routes_withDEC/MapServer/exts/CdotLrsAccessRounded", uut.getBaseUrl()); + Assertions.assertEquals(expectedBaseUrl, uut.getBaseUrl()); } @Test From 212e2ebf40a5246053ddcb089f9c8fd8dec13d58 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Sun, 29 Dec 2024 09:45:37 -0700 Subject: [PATCH 031/168] Removed initialization test from CdotGisConnectorTest --- .../com/trihydro/library/helpers/CdotGisConnectorTest.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CdotGisConnectorTest.java b/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CdotGisConnectorTest.java index 2ad1dd7bf..b0338c758 100644 --- a/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CdotGisConnectorTest.java +++ b/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CdotGisConnectorTest.java @@ -20,13 +20,6 @@ class CdotGisConnectorTest extends BaseServiceTest { private final String expectedBaseUrl = "https://dtdapps.coloradodot.info/arcgis/rest/services/LRS/Routes_withDEC/MapServer/exts/CdotLrsAccessRounded"; - @Test - void testInitialization() { - Assertions.assertNotNull(uut); - Assertions.assertEquals(expectedBaseUrl, uut.getBaseUrl()); - Assertions.assertNotNull(uut.getRestTemplateProvider()); - } - @Test void testGetBaseUrl() { Assertions.assertEquals(expectedBaseUrl, uut.getBaseUrl()); From 3f59545ea910ad2dc33c2f3771c14257771fc2bb Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Fri, 10 Jan 2025 08:37:24 -0700 Subject: [PATCH 032/168] Update notUsed field naming to doNotUse --- .../controller/ActiveTimController.java | 16 ++++---- .../controller/DataFrameController.java | 14 +++---- .../library/helpers/CreateBaseTimUtil.java | 8 ++-- .../library/helpers/JsonToJavaConverter.java | 8 ++-- .../library/helpers/TimGenerationHelper.java | 8 ++-- .../library/model/TimUpdateModel.java | 40 +++++++++---------- .../library/service/WydotTimServiceTest.java | 2 +- .../app/services/DataFrameService.java | 14 +++---- .../app/services/DataFrameServiceTest.java | 19 +++++---- 9 files changed, 64 insertions(+), 65 deletions(-) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java index 1afe4c81a..92fcc016d 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java @@ -162,10 +162,10 @@ public ResponseEntity> GetExpiringActiveTims() { // DataFrame properties activeTim.setDataFrameId(rs.getInt("DATA_FRAME_ID")); activeTim.setDurationTime(rs.getInt("DURATION_TIME")); - activeTim.setNotUsed1((short) 0); // as of J2735 this should be set to 0 and is ignored - activeTim.setNotUsed((short) 0); // as of J2735 this should be set to 0 and is ignored - activeTim.setNotUsed3((short) 0); // as of J2735 this should be set to 0 and is ignored - activeTim.setNotUsed2((short) 0); // as of J2735 this should be set to 0 and is ignored + activeTim.setDoNotUse2((short) 0); // as of J2735 2020 this should be set to 0 and is ignored + activeTim.setDoNotUse1((short) 0); // as of J2735 2020 this should be set to 0 and is ignored + activeTim.setDoNotUse4((short) 0); // as of J2735 2020 this should be set to 0 and is ignored + activeTim.setDoNotUse3((short) 0); // as of J2735 2020 this should be set to 0 and is ignored activeTim.setUrl(rs.getString("URL")); int frameTypeValue = rs.getInt("FRAME_TYPE"); @@ -293,10 +293,10 @@ public ResponseEntity GetUpdateModelFromActiveTimId(@PathVariabl // DataFrame properties activeTim.setDataFrameId(rs.getInt("DATA_FRAME_ID")); activeTim.setDurationTime(rs.getInt("DURATION_TIME")); - activeTim.setNotUsed1((short) 0); // as of J2735 2020 this should be set to 0 and is ignored - activeTim.setNotUsed((short) 0); // as of J2735 2020 this should be set to 0 and is ignored - activeTim.setNotUsed3((short) 0); // as of J2735 2020 this should be set to 0 and is ignored - activeTim.setNotUsed2((short) 0); // as of J2735 2020 this should be set to 0 and is ignored + activeTim.setDoNotUse2((short) 0); // as of J2735 2020 this should be set to 0 and is ignored + activeTim.setDoNotUse1((short) 0); // as of J2735 2020 this should be set to 0 and is ignored + activeTim.setDoNotUse4((short) 0); // as of J2735 2020 this should be set to 0 and is ignored + activeTim.setDoNotUse3((short) 0); // as of J2735 2020 this should be set to 0 and is ignored activeTim.setUrl(rs.getString("URL")); int frameTypeValue = rs.getInt("FRAME_TYPE"); diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/DataFrameController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/DataFrameController.java index 8a63fb457..a63bd6db9 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/DataFrameController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/DataFrameController.java @@ -14,9 +14,6 @@ import java.util.List; import java.util.TimeZone; -import com.trihydro.library.helpers.SQLNullHandler; -import com.trihydro.library.tables.TimDbTables; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -27,6 +24,9 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; +import com.trihydro.library.helpers.SQLNullHandler; +import com.trihydro.library.tables.TimDbTables; + import springfox.documentation.annotations.ApiIgnore; import us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage.DataFrame; @@ -112,7 +112,7 @@ public ResponseEntity AddDataFrame(@RequestBody DataFrame dFrame, @PathVar if (col.equals("TIM_ID")) { sqlNullHandler.setLongOrNull(preparedStatement, fieldNum, timId); } else if (col.equals("SSP_TIM_RIGHTS")) { - sqlNullHandler.setShortOrNull(preparedStatement, fieldNum, dFrame.getNotUsed()); + sqlNullHandler.setShortOrNull(preparedStatement, fieldNum, dFrame.getDoNotUse1()); } else if (col.equals("FRAME_TYPE")) { Integer ordinal = null; if (dFrame.getFrameType() != null) { @@ -124,11 +124,11 @@ public ResponseEntity AddDataFrame(@RequestBody DataFrame dFrame, @PathVar } else if (col.equals("PRIORITY")) { sqlNullHandler.setIntegerOrNull(preparedStatement, fieldNum, dFrame.getPriority()); } else if (col.equals("SSP_LOCATION_RIGHTS")) { - sqlNullHandler.setShortOrNull(preparedStatement, fieldNum, dFrame.getNotUsed1()); + sqlNullHandler.setShortOrNull(preparedStatement, fieldNum, dFrame.getDoNotUse2()); } else if (col.equals("SSP_MSG_TYPES")) { - sqlNullHandler.setShortOrNull(preparedStatement, fieldNum, dFrame.getNotUsed3()); + sqlNullHandler.setShortOrNull(preparedStatement, fieldNum, dFrame.getDoNotUse4()); } else if (col.equals("SSP_MSG_CONTENT")) { - sqlNullHandler.setShortOrNull(preparedStatement, fieldNum, dFrame.getNotUsed2()); + sqlNullHandler.setShortOrNull(preparedStatement, fieldNum, dFrame.getDoNotUse3()); } else if (col.equals("CONTENT")) { sqlNullHandler.setStringOrNull(preparedStatement, fieldNum, dFrame.getContent()); } else if (col.equals("URL")) { diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CreateBaseTimUtil.java b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CreateBaseTimUtil.java index 4b256573c..68afd2472 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CreateBaseTimUtil.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CreateBaseTimUtil.java @@ -59,10 +59,10 @@ public WydotTravelerInputData buildTim(WydotTim wydotTim, TimGenerationProps gen // set TIM Properties OdeTravelerInformationMessage.DataFrame dataFrame = new OdeTravelerInformationMessage.DataFrame(); - dataFrame.setNotUsed((short) 0); // as of J2735 2020 this should be set to 0 and is ignored - dataFrame.setNotUsed1((short) 0); // as of J2735 2020 this should be set to 0 and is ignored - dataFrame.setNotUsed2((short) 0); // as of J2735 2020 this should be set to 0 and is ignored - dataFrame.setNotUsed3((short) 0); // as of J2735 2020 this should be set to 0 and is ignored + dataFrame.setDoNotUse1((short) 0); // as of J2735 2020 this should be set to 0 and is ignored + dataFrame.setDoNotUse2((short) 0); // as of J2735 2020 this should be set to 0 and is ignored + dataFrame.setDoNotUse3((short) 0); // as of J2735 2020 this should be set to 0 and is ignored + dataFrame.setDoNotUse4((short) 0); // as of J2735 2020 this should be set to 0 and is ignored // set TIM TimeStamp and StartDateTime to current time in UTC String nowAsISO = Instant.now().toString(); diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/JsonToJavaConverter.java b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/JsonToJavaConverter.java index aefc1fd61..0b72b4f69 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/JsonToJavaConverter.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/JsonToJavaConverter.java @@ -536,8 +536,8 @@ else if (sequenceArrNode.get("item").get("text") != null) JsonNode startTimeNode = travelerDataFrame.get("startTime"); JsonNode durationNode = travelerDataFrame.get("durationTime"); JsonNode priorityNode = travelerDataFrame.get("priority"); - JsonNode notUsed1Node = travelerDataFrame.get("notUsed1"); - JsonNode notUsedNode = travelerDataFrame.get("notUsed"); + JsonNode doNotUse2Node = travelerDataFrame.get("doNotUse2"); + JsonNode doNotUse1Node = travelerDataFrame.get("doNotUse1"); LocalDate now = LocalDate.now(); LocalDate firstDay = now.with(firstDayOfYear()); @@ -555,8 +555,8 @@ else if (sequenceArrNode.get("item").get("text") != null) dataFrame.setStartDateTime(startDate.toString() + "Z"); dataFrame.setDurationTime(durationNode.asInt()); dataFrame.setPriority(priorityNode.asInt()); - dataFrame.setNotUsed1((short) notUsed1Node.asInt()); - dataFrame.setNotUsed((short) notUsedNode.asInt()); + dataFrame.setDoNotUse2((short) doNotUse2Node.asInt()); + dataFrame.setDoNotUse1((short) doNotUse1Node.asInt()); tim.setMsgCnt(timNode.get("msgCnt").asInt()); diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/TimGenerationHelper.java b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/TimGenerationHelper.java index d763367f9..74a5972d9 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/TimGenerationHelper.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/TimGenerationHelper.java @@ -739,13 +739,13 @@ private DataFrame getDataFrame(TimUpdateModel aTim, Milepost anchor, boolean res // DataFrame DataFrame df = new DataFrame(); - df.setNotUsed(aTim.getNotUsed()); + df.setDoNotUse1(aTim.getDoNotUse1()); df.setFrameType(aTim.getFrameType()); df.setMsgId(msgId); df.setPriority(5);// 0-7, 0 being least important, 7 being most - df.setNotUsed1(aTim.getNotUsed1()); - df.setNotUsed3(aTim.getNotUsed3()); - df.setNotUsed2(aTim.getNotUsed2()); + df.setDoNotUse2(aTim.getDoNotUse2()); + df.setDoNotUse4(aTim.getDoNotUse4()); + df.setDoNotUse3(aTim.getDoNotUse3()); if (aTim.getDfContent() != null) df.setContent(aTim.getDfContent().getStringValue()); df.setUrl(aTim.getUrl()); diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/model/TimUpdateModel.java b/cv-data-service-library/src/main/java/com/trihydro/library/model/TimUpdateModel.java index dd7b2c727..7333b268e 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/model/TimUpdateModel.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/model/TimUpdateModel.java @@ -32,10 +32,10 @@ public class TimUpdateModel extends ActiveTim { private int dataFrameId; private TravelerInfoType frameType; private int durationTime; - private short notUsed1; - private short notUsed; - private short notUsed3; - private short notUsed2; + private short doNotUse2; + private short doNotUse1; + private short doNotUse4; + private short doNotUse3; private ContentEnum dfContent; private String url; @@ -172,12 +172,12 @@ public void setFrameType(TravelerInfoType frameType) { this.frameType = frameType; } - public short getNotUsed() { - return notUsed; + public short getDoNotUse1() { + return doNotUse1; } - public void setNotUsed(short notUsed) { - this.notUsed = notUsed; + public void setDoNotUse1(short doNotUse1) { + this.doNotUse1 = doNotUse1; } public ContentEnum getDfContent() { @@ -188,28 +188,28 @@ public void setDfContent(ContentEnum dfContent) { this.dfContent = dfContent; } - public short getNotUsed2() { - return notUsed2; + public short getDoNotUse3() { + return doNotUse3; } - public void setNotUsed2(short notUsed2) { - this.notUsed2 = notUsed2; + public void setDoNotUse3(short doNotUse3) { + this.doNotUse3 = doNotUse3; } - public short getNotUsed3() { - return notUsed3; + public short getDoNotUse4() { + return doNotUse4; } - public void setNotUsed3(short notUsed3) { - this.notUsed3 = notUsed3; + public void setDoNotUse4(short doNotUse4) { + this.doNotUse4 = doNotUse4; } - public short getNotUsed1() { - return notUsed1; + public short getDoNotUse2() { + return doNotUse2; } - public void setNotUsed1(short notUsed1) { - this.notUsed1 = notUsed1; + public void setDoNotUse2(short doNotUse2) { + this.doNotUse2 = doNotUse2; } public BigDecimal getAnchorLong() { diff --git a/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java b/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java index 1c658cf52..9d8e9e111 100644 --- a/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java +++ b/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java @@ -143,7 +143,7 @@ private List getActiveTims(boolean isSat) { } private OdeTravelerInformationMessage getMockOdeTravelerInformationMessage() { - String timJson = "{\"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.0030982\",\"nodeLat\":\"0.0014562\",\"delta\":\"node-LL3\"},{\"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\"}]}"; + String timJson = "{\"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.0030982\",\"nodeLat\":\"0.0014562\",\"delta\":\"node-LL3\"},{\"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\"}]}"; Gson gson = new Gson(); OdeTravelerInformationMessage mockOdeTravelerInformationMessage = gson.fromJson(timJson, OdeTravelerInformationMessage.class); return mockOdeTravelerInformationMessage; diff --git a/logger-kafka-consumer/src/main/java/com/trihydro/loggerkafkaconsumer/app/services/DataFrameService.java b/logger-kafka-consumer/src/main/java/com/trihydro/loggerkafkaconsumer/app/services/DataFrameService.java index 0a8e34c14..8e3c776eb 100644 --- a/logger-kafka-consumer/src/main/java/com/trihydro/loggerkafkaconsumer/app/services/DataFrameService.java +++ b/logger-kafka-consumer/src/main/java/com/trihydro/loggerkafkaconsumer/app/services/DataFrameService.java @@ -10,12 +10,12 @@ import java.util.Date; import java.util.TimeZone; -import com.trihydro.library.helpers.SQLNullHandler; -import com.trihydro.library.tables.TimDbTables; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import com.trihydro.library.helpers.SQLNullHandler; +import com.trihydro.library.tables.TimDbTables; + import us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage.DataFrame; @Component @@ -46,7 +46,7 @@ public Long AddDataFrame(DataFrame dFrame, Long timId) { if (col.equals("TIM_ID")) { sqlNullHandler.setLongOrNull(preparedStatement, fieldNum, timId); } else if (col.equals("SSP_TIM_RIGHTS")) { - sqlNullHandler.setShortOrNull(preparedStatement, fieldNum, dFrame.getNotUsed()); + sqlNullHandler.setShortOrNull(preparedStatement, fieldNum, dFrame.getDoNotUse1()); } else if (col.equals("FRAME_TYPE")) { Integer ordinal = null; if (dFrame.getFrameType() != null) { @@ -58,11 +58,11 @@ public Long AddDataFrame(DataFrame dFrame, Long timId) { } else if (col.equals("PRIORITY")) { sqlNullHandler.setIntegerOrNull(preparedStatement, fieldNum, dFrame.getPriority()); } else if (col.equals("SSP_LOCATION_RIGHTS")) { - sqlNullHandler.setShortOrNull(preparedStatement, fieldNum, dFrame.getNotUsed1()); + sqlNullHandler.setShortOrNull(preparedStatement, fieldNum, dFrame.getDoNotUse2()); } else if (col.equals("SSP_MSG_TYPES")) { - sqlNullHandler.setShortOrNull(preparedStatement, fieldNum, dFrame.getNotUsed3()); + sqlNullHandler.setShortOrNull(preparedStatement, fieldNum, dFrame.getDoNotUse4()); } else if (col.equals("SSP_MSG_CONTENT")) { - sqlNullHandler.setShortOrNull(preparedStatement, fieldNum, dFrame.getNotUsed2()); + sqlNullHandler.setShortOrNull(preparedStatement, fieldNum, dFrame.getDoNotUse3()); } else if (col.equals("CONTENT")) { sqlNullHandler.setStringOrNull(preparedStatement, fieldNum, dFrame.getContent()); } else if (col.equals("URL")) { diff --git a/logger-kafka-consumer/src/test/java/com/trihydro/loggerkafkaconsumer/app/services/DataFrameServiceTest.java b/logger-kafka-consumer/src/test/java/com/trihydro/loggerkafkaconsumer/app/services/DataFrameServiceTest.java index 658483209..663951b0d 100644 --- a/logger-kafka-consumer/src/test/java/com/trihydro/loggerkafkaconsumer/app/services/DataFrameServiceTest.java +++ b/logger-kafka-consumer/src/test/java/com/trihydro/loggerkafkaconsumer/app/services/DataFrameServiceTest.java @@ -1,8 +1,5 @@ package com.trihydro.loggerkafkaconsumer.app.services; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.verify; - import java.sql.SQLException; import java.sql.Timestamp; import java.text.DateFormat; @@ -11,15 +8,17 @@ import java.util.Date; import java.util.TimeZone; -import com.trihydro.library.helpers.SQLNullHandler; -import com.trihydro.library.tables.TimDbTables; - import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.Mock; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.verify; import org.mockito.Spy; +import com.trihydro.library.helpers.SQLNullHandler; +import com.trihydro.library.tables.TimDbTables; + import us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage.DataFrame; public class DataFrameServiceTest extends TestBase { @@ -51,13 +50,13 @@ public void AddDataFrame_SUCCESS() throws SQLException, ParseException { // Assert Assertions.assertEquals(Long.valueOf(-1), data); verify(mockSqlNullHandler).setLongOrNull(mockPreparedStatement, 1, -1l);// TIM_ID - verify(mockSqlNullHandler).setShortOrNull(mockPreparedStatement, 2, dFrame.getNotUsed());// SSP_TIM_RIGHTS + verify(mockSqlNullHandler).setShortOrNull(mockPreparedStatement, 2, dFrame.getDoNotUse1());// SSP_TIM_RIGHTS & NotUsed verify(mockSqlNullHandler).setIntegerOrNull(mockPreparedStatement, 3, null);// FRAME_TYPE verify(mockSqlNullHandler).setIntegerOrNull(mockPreparedStatement, 4, dFrame.getDurationTime());// DURATION_TIME verify(mockSqlNullHandler).setIntegerOrNull(mockPreparedStatement, 5, dFrame.getPriority());// PRIORITY - verify(mockSqlNullHandler).setShortOrNull(mockPreparedStatement, 6, dFrame.getNotUsed1());// SSP_LOCATION_RIGHTS - verify(mockSqlNullHandler).setShortOrNull(mockPreparedStatement, 7, dFrame.getNotUsed3());// SSP_MSG_TYPES - verify(mockSqlNullHandler).setShortOrNull(mockPreparedStatement, 8, dFrame.getNotUsed2());// SSP_MSG_CONTENT + verify(mockSqlNullHandler).setShortOrNull(mockPreparedStatement, 6, dFrame.getDoNotUse2());// SSP_LOCATION_RIGHTS & NotUsed1 + verify(mockSqlNullHandler).setShortOrNull(mockPreparedStatement, 7, dFrame.getDoNotUse4());// SSP_MSG_TYPES & NotUsed3 + verify(mockSqlNullHandler).setShortOrNull(mockPreparedStatement, 8, dFrame.getDoNotUse3());// SSP_MSG_CONTENT & NotUsed2 verify(mockSqlNullHandler).setStringOrNull(mockPreparedStatement, 9, dFrame.getContent());// CONTENT verify(mockSqlNullHandler).setStringOrNull(mockPreparedStatement, 10, dFrame.getUrl());// URL verify(mockSqlNullHandler).setTimestampOrNull(mockPreparedStatement, 11, time);// START_DATE_TIME From 501bf6117bf7f90ad4babef4d97ad518fa91f3f6 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Fri, 10 Jan 2025 08:38:35 -0700 Subject: [PATCH 033/168] Update x/y pos, elevation, width fields to comply with J2735 2024 --- .../cvdatacontroller/controller/NodeXYController.java | 8 ++++---- .../cvdatacontroller/controller/PathNodeXYController.java | 4 ++-- .../cvdatacontroller/controller/NodeXYControllerTest.java | 8 ++++---- .../loggerkafkaconsumer/app/services/NodeLLService.java | 8 ++++---- .../loggerkafkaconsumer/app/services/NodeXYService.java | 8 ++++---- .../app/services/NodeXYServiceTest.java | 8 ++++---- 6 files changed, 22 insertions(+), 22 deletions(-) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/NodeXYController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/NodeXYController.java index c65e98ced..9975e45fd 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/NodeXYController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/NodeXYController.java @@ -56,19 +56,19 @@ else if (col.equals("NODE_LAT")) else if (col.equals("NODE_LONG")) sqlNullHandler.setBigDecimalOrNull(preparedStatement, fieldNum, nodeXY.getNodeLong()); else if (col.equals("X")) - sqlNullHandler.setBigDecimalOrNull(preparedStatement, fieldNum, nodeXY.getX()); + sqlNullHandler.setBigDecimalOrNull(preparedStatement, fieldNum, nodeXY.getXpos()); else if (col.equals("Y")) - sqlNullHandler.setBigDecimalOrNull(preparedStatement, fieldNum, nodeXY.getY()); + sqlNullHandler.setBigDecimalOrNull(preparedStatement, fieldNum, nodeXY.getYpos()); else if (col.equals("ATTRIBUTES_DWIDTH")) if (nodeXY.getAttributes() != null) sqlNullHandler.setBigDecimalOrNull(preparedStatement, fieldNum, - nodeXY.getAttributes().getdWidth()); + nodeXY.getAttributes().getDwidth()); else preparedStatement.setString(fieldNum, null); else if (col.equals("ATTRIBUTES_DELEVATION")) if (nodeXY.getAttributes() != null) sqlNullHandler.setBigDecimalOrNull(preparedStatement, fieldNum, - nodeXY.getAttributes().getdElevation()); + nodeXY.getAttributes().getDelevation()); else preparedStatement.setString(fieldNum, null); fieldNum++; diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/PathNodeXYController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/PathNodeXYController.java index a98f6b2bd..3fa1e6a04 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/PathNodeXYController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/PathNodeXYController.java @@ -62,8 +62,8 @@ public ResponseEntity GetNodeXYForPath(@PathVariable int pathId) { nodexy.setDelta(rs.getString("DELTA")); nodexy.setNodeLat(rs.getBigDecimal("NODE_LAT")); nodexy.setNodeLong(rs.getBigDecimal("NODE_LONG")); - nodexy.setX(rs.getBigDecimal("X")); - nodexy.setY(rs.getBigDecimal("Y")); + nodexy.setXpos(rs.getBigDecimal("X")); + nodexy.setYpos(rs.getBigDecimal("Y")); nodeXYs.add(nodexy); } diff --git a/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/NodeXYControllerTest.java b/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/NodeXYControllerTest.java index a64953b23..4037489ff 100644 --- a/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/NodeXYControllerTest.java +++ b/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/NodeXYControllerTest.java @@ -50,11 +50,11 @@ public void AddNodeXY_SUCCESS() throws SQLException { verify(mockSqlNullHandler).setStringOrNull(mockPreparedStatement, 1, nodeXY.getDelta());// DELTA verify(mockSqlNullHandler).setBigDecimalOrNull(mockPreparedStatement, 2, nodeXY.getNodeLat());// NODE_LAT verify(mockSqlNullHandler).setBigDecimalOrNull(mockPreparedStatement, 3, nodeXY.getNodeLong());// NODE_LONG - verify(mockSqlNullHandler).setBigDecimalOrNull(mockPreparedStatement, 4, nodeXY.getX());// X - verify(mockSqlNullHandler).setBigDecimalOrNull(mockPreparedStatement, 5, nodeXY.getY());// Y - verify(mockSqlNullHandler).setBigDecimalOrNull(mockPreparedStatement, 6, nodeXY.getAttributes().getdWidth());// ATTRIBUTES_DWIDTH + verify(mockSqlNullHandler).setBigDecimalOrNull(mockPreparedStatement, 4, nodeXY.getXpos());// X + verify(mockSqlNullHandler).setBigDecimalOrNull(mockPreparedStatement, 5, nodeXY.getYpos());// Y + verify(mockSqlNullHandler).setBigDecimalOrNull(mockPreparedStatement, 6, nodeXY.getAttributes().getDwidth());// ATTRIBUTES_DWIDTH verify(mockSqlNullHandler).setBigDecimalOrNull(mockPreparedStatement, 7, - nodeXY.getAttributes().getdElevation());// ATTRIBUTES_DELEVATION + nodeXY.getAttributes().getDelevation());// ATTRIBUTES_DELEVATION verify(mockPreparedStatement).close(); verify(mockConnection).close(); } diff --git a/logger-kafka-consumer/src/main/java/com/trihydro/loggerkafkaconsumer/app/services/NodeLLService.java b/logger-kafka-consumer/src/main/java/com/trihydro/loggerkafkaconsumer/app/services/NodeLLService.java index 93d8f05ca..37d49acff 100644 --- a/logger-kafka-consumer/src/main/java/com/trihydro/loggerkafkaconsumer/app/services/NodeLLService.java +++ b/logger-kafka-consumer/src/main/java/com/trihydro/loggerkafkaconsumer/app/services/NodeLLService.java @@ -45,19 +45,19 @@ else if (col.equals("NODE_LAT")) else if (col.equals("NODE_LONG")) sqlNullHandler.setBigDecimalOrNull(preparedStatement, fieldNum, nodeXY.getNodeLong()); else if (col.equals("X")) - sqlNullHandler.setBigDecimalOrNull(preparedStatement, fieldNum, nodeXY.getX()); + sqlNullHandler.setBigDecimalOrNull(preparedStatement, fieldNum, nodeXY.getXpos()); else if (col.equals("Y")) - sqlNullHandler.setBigDecimalOrNull(preparedStatement, fieldNum, nodeXY.getY()); + sqlNullHandler.setBigDecimalOrNull(preparedStatement, fieldNum, nodeXY.getYpos()); else if (col.equals("ATTRIBUTES_DWIDTH")) if (nodeXY.getAttributes() != null) sqlNullHandler.setBigDecimalOrNull(preparedStatement, fieldNum, - nodeXY.getAttributes().getdWidth()); + nodeXY.getAttributes().getDwidth()); else preparedStatement.setNull(fieldNum, java.sql.Types.NUMERIC); else if (col.equals("ATTRIBUTES_DELEVATION")) if (nodeXY.getAttributes() != null) sqlNullHandler.setBigDecimalOrNull(preparedStatement, fieldNum, - nodeXY.getAttributes().getdElevation()); + nodeXY.getAttributes().getDelevation()); else preparedStatement.setNull(fieldNum, java.sql.Types.NUMERIC); fieldNum++; diff --git a/logger-kafka-consumer/src/main/java/com/trihydro/loggerkafkaconsumer/app/services/NodeXYService.java b/logger-kafka-consumer/src/main/java/com/trihydro/loggerkafkaconsumer/app/services/NodeXYService.java index 5409d9c66..c522ac062 100644 --- a/logger-kafka-consumer/src/main/java/com/trihydro/loggerkafkaconsumer/app/services/NodeXYService.java +++ b/logger-kafka-consumer/src/main/java/com/trihydro/loggerkafkaconsumer/app/services/NodeXYService.java @@ -45,19 +45,19 @@ else if (col.equals("NODE_LAT")) else if (col.equals("NODE_LONG")) sqlNullHandler.setBigDecimalOrNull(preparedStatement, fieldNum, nodeXY.getNodeLong()); else if (col.equals("X")) - sqlNullHandler.setBigDecimalOrNull(preparedStatement, fieldNum, nodeXY.getX()); + sqlNullHandler.setBigDecimalOrNull(preparedStatement, fieldNum, nodeXY.getXpos()); else if (col.equals("Y")) - sqlNullHandler.setBigDecimalOrNull(preparedStatement, fieldNum, nodeXY.getY()); + sqlNullHandler.setBigDecimalOrNull(preparedStatement, fieldNum, nodeXY.getYpos()); else if (col.equals("ATTRIBUTES_DWIDTH")) if (nodeXY.getAttributes() != null) sqlNullHandler.setBigDecimalOrNull(preparedStatement, fieldNum, - nodeXY.getAttributes().getdWidth()); + nodeXY.getAttributes().getDwidth()); else preparedStatement.setNull(fieldNum, java.sql.Types.NUMERIC); else if (col.equals("ATTRIBUTES_DELEVATION")) if (nodeXY.getAttributes() != null) sqlNullHandler.setBigDecimalOrNull(preparedStatement, fieldNum, - nodeXY.getAttributes().getdElevation()); + nodeXY.getAttributes().getDelevation()); else preparedStatement.setNull(fieldNum, java.sql.Types.NUMERIC); fieldNum++; diff --git a/logger-kafka-consumer/src/test/java/com/trihydro/loggerkafkaconsumer/app/services/NodeXYServiceTest.java b/logger-kafka-consumer/src/test/java/com/trihydro/loggerkafkaconsumer/app/services/NodeXYServiceTest.java index 1efffcc5b..7e901a3ee 100644 --- a/logger-kafka-consumer/src/test/java/com/trihydro/loggerkafkaconsumer/app/services/NodeXYServiceTest.java +++ b/logger-kafka-consumer/src/test/java/com/trihydro/loggerkafkaconsumer/app/services/NodeXYServiceTest.java @@ -43,11 +43,11 @@ public void AddNodeXY_SUCCESS() throws SQLException { verify(mockSqlNullHandler).setStringOrNull(mockPreparedStatement, 1, nodeXY.getDelta());// DELTA verify(mockSqlNullHandler).setBigDecimalOrNull(mockPreparedStatement, 2, nodeXY.getNodeLat());// NODE_LAT verify(mockSqlNullHandler).setBigDecimalOrNull(mockPreparedStatement, 3, nodeXY.getNodeLong());// NODE_LONG - verify(mockSqlNullHandler).setBigDecimalOrNull(mockPreparedStatement, 4, nodeXY.getX());// X - verify(mockSqlNullHandler).setBigDecimalOrNull(mockPreparedStatement, 5, nodeXY.getY());// Y - verify(mockSqlNullHandler).setBigDecimalOrNull(mockPreparedStatement, 6, nodeXY.getAttributes().getdWidth());// ATTRIBUTES_DWIDTH + verify(mockSqlNullHandler).setBigDecimalOrNull(mockPreparedStatement, 4, nodeXY.getXpos());// X + verify(mockSqlNullHandler).setBigDecimalOrNull(mockPreparedStatement, 5, nodeXY.getYpos());// Y + verify(mockSqlNullHandler).setBigDecimalOrNull(mockPreparedStatement, 6, nodeXY.getAttributes().getDwidth());// ATTRIBUTES_DWIDTH verify(mockSqlNullHandler).setBigDecimalOrNull(mockPreparedStatement, 7, - nodeXY.getAttributes().getdElevation());// ATTRIBUTES_DELEVATION + nodeXY.getAttributes().getDelevation());// ATTRIBUTES_DELEVATION verify(mockPreparedStatement).close(); verify(mockConnection).close(); } From 7a469deb77df8d2557b88914ac7b7fcffea680c0 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Fri, 10 Jan 2025 08:41:18 -0700 Subject: [PATCH 034/168] Update field names in cv-data-service-library test resources --- .../src/test/resources/broadcastTim_OdeOutput.json | 8 ++++---- .../src/test/resources/rxMsg_TIM_OdeOutput.json | 8 ++++---- .../src/test/resources/rxMsg_TIM_OdeOutput_Geometry.json | 8 ++++---- .../resources/rxMsg_TIM_OdeOutput_MultipleRegions.json | 8 ++++---- .../src/test/resources/rxMsg_TIM_SpeedLimit.json | 8 ++++---- .../src/test/resources/sdxDecodeResponse.json | 2 +- .../src/test/resources/tim_construction.json | 8 ++++---- .../test/resources/tim_construction_MultipleRegions.json | 8 ++++---- .../src/test/resources/tim_parking.json | 8 ++++---- .../src/test/resources/tim_parking_MultipleRegions.json | 8 ++++---- cv-data-service-library/src/test/resources/tim_vsl.json | 8 ++++---- .../src/test/resources/tim_vsl_MultipleRegions.json | 8 ++++---- 12 files changed, 45 insertions(+), 45 deletions(-) diff --git a/cv-data-service-library/src/test/resources/broadcastTim_OdeOutput.json b/cv-data-service-library/src/test/resources/broadcastTim_OdeOutput.json index 2889ddd83..bd4554e74 100644 --- a/cv-data-service-library/src/test/resources/broadcastTim_OdeOutput.json +++ b/cv-data-service-library/src/test/resources/broadcastTim_OdeOutput.json @@ -22,7 +22,7 @@ "urlB": "null", "dataframes": [ { - "notUsed": 1, + "doNotUse1": 1, "frameType": "advisory", "msgId": { "furtherInfoID": "CDEF" @@ -30,7 +30,7 @@ "startDateTime": "2018-03-15T21:18:46.719-07:00", "durationTime": 32000, "priority": 5, - "notUsed1": 1, + "doNotUse2": 1, "regions": [ { "name": "westbound_I80_370.0_365.0_RSU-10.145.1.100_VSL", @@ -179,8 +179,8 @@ } } ], - "notUsed3": 0, - "notUsed2": 1, + "doNotUse4": 0, + "doNotUse3": 1, "content": "Advisory", "items": [ "268", diff --git a/cv-data-service-library/src/test/resources/rxMsg_TIM_OdeOutput.json b/cv-data-service-library/src/test/resources/rxMsg_TIM_OdeOutput.json index f61c08d40..169a60727 100644 --- a/cv-data-service-library/src/test/resources/rxMsg_TIM_OdeOutput.json +++ b/cv-data-service-library/src/test/resources/rxMsg_TIM_OdeOutput.json @@ -82,10 +82,10 @@ } }, "durationTime": 32000, - "notUsed2": 0, - "notUsed3": 0, - "notUsed": 0, - "notUsed1": 0, + "doNotUse3": 0, + "doNotUse4": 0, + "doNotUse1": 0, + "doNotUse2": 0, "frameType": { "roadSignage": "" }, diff --git a/cv-data-service-library/src/test/resources/rxMsg_TIM_OdeOutput_Geometry.json b/cv-data-service-library/src/test/resources/rxMsg_TIM_OdeOutput_Geometry.json index a0482b36f..cff628b73 100644 --- a/cv-data-service-library/src/test/resources/rxMsg_TIM_OdeOutput_Geometry.json +++ b/cv-data-service-library/src/test/resources/rxMsg_TIM_OdeOutput_Geometry.json @@ -69,10 +69,10 @@ } }, "durationTime": 32000, - "notUsed2": 0, - "notUsed3": 0, - "notUsed": 0, - "notUsed1": 0, + "doNotUse3": 0, + "doNotUse4": 0, + "doNotUse1": 0, + "doNotUse2": 0, "frameType": { "roadSignage": "" }, diff --git a/cv-data-service-library/src/test/resources/rxMsg_TIM_OdeOutput_MultipleRegions.json b/cv-data-service-library/src/test/resources/rxMsg_TIM_OdeOutput_MultipleRegions.json index 95472d2c5..1549e6c85 100644 --- a/cv-data-service-library/src/test/resources/rxMsg_TIM_OdeOutput_MultipleRegions.json +++ b/cv-data-service-library/src/test/resources/rxMsg_TIM_OdeOutput_MultipleRegions.json @@ -126,10 +126,10 @@ ] }, "durationTime": 32000, - "notUsed2": 0, - "notUsed3": 0, - "notUsed": 0, - "notUsed1": 0, + "doNotUse3": 0, + "doNotUse4": 0, + "doNotUse1": 0, + "doNotUse2": 0, "frameType": { "roadSignage": "" }, diff --git a/cv-data-service-library/src/test/resources/rxMsg_TIM_SpeedLimit.json b/cv-data-service-library/src/test/resources/rxMsg_TIM_SpeedLimit.json index 2e3e5efeb..4692d3167 100644 --- a/cv-data-service-library/src/test/resources/rxMsg_TIM_SpeedLimit.json +++ b/cv-data-service-library/src/test/resources/rxMsg_TIM_SpeedLimit.json @@ -82,10 +82,10 @@ } }, "durationTime": 32000, - "notUsed2": 0, - "notUsed3": 0, - "notUsed": 0, - "notUsed1": 0, + "doNotUse3": 0, + "doNotUse4": 0, + "doNotUse1": 0, + "doNotUse2": 0, "frameType": { "roadSignage": "" }, diff --git a/cv-data-service-library/src/test/resources/sdxDecodeResponse.json b/cv-data-service-library/src/test/resources/sdxDecodeResponse.json index dc4716bd7..9ca0bc47a 100644 --- a/cv-data-service-library/src/test/resources/sdxDecodeResponse.json +++ b/cv-data-service-library/src/test/resources/sdxDecodeResponse.json @@ -1,4 +1,4 @@ { "messageType": "MessageFrame", - "decodedMessage": "3113469004null1414344751-1101051425111111111111111120194690043200051westbound_I80_39.9_53.31_SAT-4035A5DF_RC_LYMI80EGRAD00414344751-11010514253270000000011111100000-1048300445417415787-1101068786414338729-1048297813417401082-1101173822414302517-1048296846417313218-1101278808414263469-1048334156417231472-1101362065414212124-1048363596417151273-1048348231417067803-1101430219414153700-1101515051414095801-1048292665416990008-1101609734414047121-1048303785416903264-1101704290413998478-1048330081416818875-1101798529413950074-1048362115416736381-1048394037416654255-1101901550413914121-1102014424413891332-1048426742416569080-1102126907413868840-1048459137416484285-1102235582413840132-1048492892416400669-1102332568413793094-1048526150416318091-1048559229416236049-1102434259413752451-1102543983413731407-1048592545416153296-1102655116413714865-1048625771416070802-1102767179413702216-1048658799415988821-1102881705413689256-1048694127415905527-1048732305415821992-1102996201413671479-1103105581413647716-1048769216415741004-1103216030413622307-1048806392415659600-1103325763413587617-1048843990415577334-11033794134135705071158955907null" + "decodedMessage": "3113469004null1414344751-1101051425111111111111111120194690043200051westbound_I80_39.9_53.31_SAT-4035A5DF_RC_LYMI80EGRAD00414344751-11010514253270000000011111100000-1048300445417415787-1101068786414338729-1048297813417401082-1101173822414302517-1048296846417313218-1101278808414263469-1048334156417231472-1101362065414212124-1048363596417151273-1048348231417067803-1101430219414153700-1101515051414095801-1048292665416990008-1101609734414047121-1048303785416903264-1101704290413998478-1048330081416818875-1101798529413950074-1048362115416736381-1048394037416654255-1101901550413914121-1102014424413891332-1048426742416569080-1102126907413868840-1048459137416484285-1102235582413840132-1048492892416400669-1102332568413793094-1048526150416318091-1048559229416236049-1102434259413752451-1102543983413731407-1048592545416153296-1102655116413714865-1048625771416070802-1102767179413702216-1048658799415988821-1102881705413689256-1048694127415905527-1048732305415821992-1102996201413671479-1103105581413647716-1048769216415741004-1103216030413622307-1048806392415659600-1103325763413587617-1048843990415577334-11033794134135705071158955907null" } diff --git a/cv-data-service-library/src/test/resources/tim_construction.json b/cv-data-service-library/src/test/resources/tim_construction.json index c47424c2d..604df86df 100644 --- a/cv-data-service-library/src/test/resources/tim_construction.json +++ b/cv-data-service-library/src/test/resources/tim_construction.json @@ -80,8 +80,8 @@ } }, "durationTime": 32000, - "notUsed2": 1, - "notUsed3": 1, + "doNotUse3": 1, + "doNotUse4": 1, "startYear": 2021, "msgId": { "roadSignID": { @@ -101,8 +101,8 @@ } }, "url": null, - "notUsed": 1, - "notUsed1": 1, + "doNotUse1": 1, + "doNotUse2": 1, "frameType": { "advisory": "" }, "startTime": 89280 } diff --git a/cv-data-service-library/src/test/resources/tim_construction_MultipleRegions.json b/cv-data-service-library/src/test/resources/tim_construction_MultipleRegions.json index c31beceec..2d04c77a7 100644 --- a/cv-data-service-library/src/test/resources/tim_construction_MultipleRegions.json +++ b/cv-data-service-library/src/test/resources/tim_construction_MultipleRegions.json @@ -120,8 +120,8 @@ ] }, "durationTime": 32000, - "notUsed2": 1, - "notUsed3": 1, + "doNotUse3": 1, + "doNotUse4": 1, "startYear": 2021, "msgId": { "roadSignID": { @@ -141,8 +141,8 @@ } }, "url": null, - "notUsed": 1, - "notUsed1": 1, + "doNotUse1": 1, + "doNotUse2": 1, "frameType": { "advisory": "" }, "startTime": 89280 } diff --git a/cv-data-service-library/src/test/resources/tim_parking.json b/cv-data-service-library/src/test/resources/tim_parking.json index be3d8c709..a4c3ad27f 100644 --- a/cv-data-service-library/src/test/resources/tim_parking.json +++ b/cv-data-service-library/src/test/resources/tim_parking.json @@ -75,8 +75,8 @@ } }, "durationTime": 120, - "notUsed2": 1, - "notUsed3": 1, + "doNotUse3": 1, + "doNotUse4": 1, "startYear": 2021, "msgId": { "roadSignID": { @@ -96,8 +96,8 @@ } }, "url": null, - "notUsed": 1, - "notUsed1": 1, + "doNotUse1": 1, + "doNotUse2": 1, "frameType": { "advisory": "" }, "startTime": 117800 } diff --git a/cv-data-service-library/src/test/resources/tim_parking_MultipleRegions.json b/cv-data-service-library/src/test/resources/tim_parking_MultipleRegions.json index 2d18e11d7..ed2a9ce79 100644 --- a/cv-data-service-library/src/test/resources/tim_parking_MultipleRegions.json +++ b/cv-data-service-library/src/test/resources/tim_parking_MultipleRegions.json @@ -110,8 +110,8 @@ ] }, "durationTime": 120, - "notUsed2": 1, - "notUsed3": 1, + "doNotUse3": 1, + "doNotUse4": 1, "startYear": 2021, "msgId": { "roadSignID": { @@ -131,8 +131,8 @@ } }, "url": null, - "notUsed": 1, - "notUsed1": 1, + "doNotUse1": 1, + "doNotUse2": 1, "frameType": { "advisory": "" }, "startTime": 117800 } diff --git a/cv-data-service-library/src/test/resources/tim_vsl.json b/cv-data-service-library/src/test/resources/tim_vsl.json index 3621812d5..25bafd26a 100644 --- a/cv-data-service-library/src/test/resources/tim_vsl.json +++ b/cv-data-service-library/src/test/resources/tim_vsl.json @@ -65,8 +65,8 @@ } }, "durationTime": 32000, - "notUsed2": 1, - "notUsed3": 1, + "doNotUse3": 1, + "doNotUse4": 1, "startYear": 2021, "msgId": { "roadSignID": { @@ -86,8 +86,8 @@ } }, "url": null, - "notUsed": 1, - "notUsed1": 1, + "doNotUse1": 1, + "doNotUse2": 1, "frameType": { "roadSignage": "" }, "startTime": 115721 } diff --git a/cv-data-service-library/src/test/resources/tim_vsl_MultipleRegions.json b/cv-data-service-library/src/test/resources/tim_vsl_MultipleRegions.json index c8d6cde06..fe99be538 100644 --- a/cv-data-service-library/src/test/resources/tim_vsl_MultipleRegions.json +++ b/cv-data-service-library/src/test/resources/tim_vsl_MultipleRegions.json @@ -90,8 +90,8 @@ ] }, "durationTime": 32000, - "notUsed2": 1, - "notUsed3": 1, + "doNotUse3": 1, + "doNotUse4": 1, "startYear": 2021, "msgId": { "roadSignID": { @@ -111,8 +111,8 @@ } }, "url": null, - "notUsed": 1, - "notUsed1": 1, + "doNotUse1": 1, + "doNotUse2": 1, "frameType": { "roadSignage": "" }, "startTime": 115721 } From 4f45ff94c9f32c90d93c006b6d02b00b9b6c2410 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Fri, 10 Jan 2025 08:42:05 -0700 Subject: [PATCH 035/168] Update logger-kafka-consumer testing resource field names --- .../src/test/resources/TIM_odeTimStartDateTime.json | 8 ++++---- .../src/test/resources/TIM_odeTim_Rsus.json | 8 ++++---- .../src/test/resources/TIM_unsigned.json | 8 ++++---- .../src/test/resources/rxMsg_TIM_OdeOutput.json | 8 ++++---- .../test/resources/rxMsg_TIM_OdeOutput_NullMetadata.json | 8 ++++---- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/logger-kafka-consumer/src/test/resources/TIM_odeTimStartDateTime.json b/logger-kafka-consumer/src/test/resources/TIM_odeTimStartDateTime.json index 9821975ea..ed7c8f1ef 100644 --- a/logger-kafka-consumer/src/test/resources/TIM_odeTimStartDateTime.json +++ b/logger-kafka-consumer/src/test/resources/TIM_odeTimStartDateTime.json @@ -243,8 +243,8 @@ } }, "durationTime": 32000, - "notUsed2": 1, - "notUsed3": 1, + "doNotUse3": 1, + "doNotUse4": 1, "startYear": 2020, "msgId": { "roadSignID": { @@ -276,8 +276,8 @@ } }, "url": null, - "notUsed": 1, - "notUsed1": 1, + "doNotUse1": 1, + "doNotUse2": 1, "frameType": { "advisory": "" }, diff --git a/logger-kafka-consumer/src/test/resources/TIM_odeTim_Rsus.json b/logger-kafka-consumer/src/test/resources/TIM_odeTim_Rsus.json index ef2374a1b..798566907 100644 --- a/logger-kafka-consumer/src/test/resources/TIM_odeTim_Rsus.json +++ b/logger-kafka-consumer/src/test/resources/TIM_odeTim_Rsus.json @@ -222,10 +222,10 @@ "name": "I_I 80_RSU-10.145.12.27_RC_test-t-12" } }, - "notUsed1": 1, - "notUsed2": 1, - "notUsed3": 1, - "notUsed": 1, + "doNotUse2": 1, + "doNotUse3": 1, + "doNotUse4": 1, + "doNotUse1": 1, "startTime": 502536, "startYear": 2020, "url": null diff --git a/logger-kafka-consumer/src/test/resources/TIM_unsigned.json b/logger-kafka-consumer/src/test/resources/TIM_unsigned.json index 3b3d056d3..2a74209cc 100644 --- a/logger-kafka-consumer/src/test/resources/TIM_unsigned.json +++ b/logger-kafka-consumer/src/test/resources/TIM_unsigned.json @@ -142,8 +142,8 @@ } }, "durationTime": "32000", - "notUsed2": "1", - "notUsed3": "1", + "doNotUse3": "1", + "doNotUse4": "1", "startYear": "2022", "msgId": { "roadSignID": { @@ -168,8 +168,8 @@ } }, "url": "null", - "notUsed": "1", - "notUsed1": "1", + "doNotUse1": "1", + "doNotUse2": "1", "frameType": { "advisory": "" }, diff --git a/logger-kafka-consumer/src/test/resources/rxMsg_TIM_OdeOutput.json b/logger-kafka-consumer/src/test/resources/rxMsg_TIM_OdeOutput.json index f61c08d40..169a60727 100644 --- a/logger-kafka-consumer/src/test/resources/rxMsg_TIM_OdeOutput.json +++ b/logger-kafka-consumer/src/test/resources/rxMsg_TIM_OdeOutput.json @@ -82,10 +82,10 @@ } }, "durationTime": 32000, - "notUsed2": 0, - "notUsed3": 0, - "notUsed": 0, - "notUsed1": 0, + "doNotUse3": 0, + "doNotUse4": 0, + "doNotUse1": 0, + "doNotUse2": 0, "frameType": { "roadSignage": "" }, diff --git a/logger-kafka-consumer/src/test/resources/rxMsg_TIM_OdeOutput_NullMetadata.json b/logger-kafka-consumer/src/test/resources/rxMsg_TIM_OdeOutput_NullMetadata.json index d756c5efd..99c9e6fae 100644 --- a/logger-kafka-consumer/src/test/resources/rxMsg_TIM_OdeOutput_NullMetadata.json +++ b/logger-kafka-consumer/src/test/resources/rxMsg_TIM_OdeOutput_NullMetadata.json @@ -54,10 +54,10 @@ } }, "durationTime": 32000, - "notUsed2": 0, - "notUsed3": 0, - "notUsed": 0, - "notUsed1": 0, + "doNotUse3": 0, + "doNotUse4": 0, + "doNotUse1": 0, + "doNotUse2": 0, "frameType": { "roadSignage": "" }, From e6eec679a6cd0b9e9a5da9b6b516ac580cd51e91 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Fri, 10 Jan 2025 08:42:21 -0700 Subject: [PATCH 036/168] Update sample data field names for J2735 2024 --- developer-tools/geojson-from-ode-tim/sampledata.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/developer-tools/geojson-from-ode-tim/sampledata.json b/developer-tools/geojson-from-ode-tim/sampledata.json index e6daa0016..b8ec7a2fc 100644 --- a/developer-tools/geojson-from-ode-tim/sampledata.json +++ b/developer-tools/geojson-from-ode-tim/sampledata.json @@ -21,7 +21,7 @@ "packetID": "24BE29D8A92FDF0930", "dataframes": [ { - "notUsed": 0, + "doNotUse1": 0, "frameType": "advisory", "msgId": { "roadSignID": { @@ -36,7 +36,7 @@ "startDateTime": "2024-10-02T11:00:50.814Z", "durationTime": 32000, "priority": 5, - "notUsed1": 0, + "doNotUse2": 0, "regions": [ { "name": "D_US 14_SAT-D99EEE98_RC_BJUS14EB", @@ -443,8 +443,8 @@ } } ], - "notUsed2": 0, - "notUsed3": 0, + "doNotUse3": 0, + "doNotUse4": 0, "content": "advisory", "items": [ "770", From fc5bfd8e4a01e14dfb3b5ac9a09bc52f990e16e0 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Fri, 10 Jan 2025 09:04:47 -0700 Subject: [PATCH 037/168] Update version from 1.4.0-SNAPSHOT to 2.0.0 --- README.md | 12 +- cert-expiration/Dockerfile | 2 +- cert-expiration/pom.xml | 2 +- cv-data-controller/Dockerfile | 2 +- cv-data-controller/pom.xml | 2 +- cv-data-service-library/pom.xml | 2 +- cv-data-tasks/Dockerfile | 4 +- cv-data-tasks/pom.xml | 2 +- local-deployment/docker-compose.yml | 258 ++++++++++++++-------------- logger-kafka-consumer/Dockerfile | 2 +- logger-kafka-consumer/pom.xml | 2 +- ode-data-logger/Dockerfile | 2 +- ode-data-logger/pom.xml | 2 +- ode-mongo-logger/Dockerfile | 2 +- ode-mongo-logger/pom.xml | 2 +- ode-wrapper/Dockerfile | 2 +- ode-wrapper/pom.xml | 2 +- pom.xml | 2 +- rsu-data-controller/Dockerfile | 4 +- rsu-data-controller/pom.xml | 2 +- tim-refresh/Dockerfile | 2 +- tim-refresh/pom.xml | 2 +- 22 files changed, 157 insertions(+), 157 deletions(-) diff --git a/README.md b/README.md index ea9c51a74..f009bbc00 100644 --- a/README.md +++ b/README.md @@ -98,28 +98,28 @@ This will create the `target` folder under each module. From here, create a new ``` . ├── cv-data-controller -│ ├── cv-data-controller-1.4.0-SNAPSHOT.jar +│ ├── cv-data-controller-2.0.0.jar │ ├── Dockerfile ├── cv-data-tasks -│ ├── cv-data-tasks-1.4.0-SNAPSHOT.jar +│ ├── cv-data-tasks-2.0.0.jar │ ├── Dockerfile ├── docker-compose.yml ├── ode-data-logger │ ├── Dockerfile -│ ├── ode-data-logger-1.4.0-SNAPSHOT.jar +│ ├── ode-data-logger-2.0.0.jar ├── ode-mongo-logger │ ├── Dockerfile -│ ├── ode-mongo-logger-1.4.0-SNAPSHOT.jar +│ ├── ode-mongo-logger-2.0.0.jar ├── ode-wrapper │ ├── Dockerfile -│ ├── ode-wrapper-1.4.0-SNAPSHOT.jar +│ ├── ode-wrapper-2.0.0.jar ├── ode-wrapper-docs │ └── swagger-ui-master │ ├── Dockerfile │ ├── (swagger folder structure) └── tim-refresh ├── Dockerfile - ├── tim-refresh-1.4.0-SNAPSHOT.jar + ├── tim-refresh-2.0.0.jar ``` diff --git a/cert-expiration/Dockerfile b/cert-expiration/Dockerfile index eac2f7a07..ffdc93264 100644 --- a/cert-expiration/Dockerfile +++ b/cert-expiration/Dockerfile @@ -2,4 +2,4 @@ FROM maven:3.8-eclipse-temurin-21-alpine ADD . /home/wyocv/wyocv_applications/cert-expiration -CMD java -jar /home/wyocv/wyocv_applications/cert-expiration/cert-expiration-1.4.0-SNAPSHOT.jar +CMD java -jar /home/wyocv/wyocv_applications/cert-expiration/cert-expiration-2.0.0.jar diff --git a/cert-expiration/pom.xml b/cert-expiration/pom.xml index a1d7d8551..e5f0ef2d9 100644 --- a/cert-expiration/pom.xml +++ b/cert-expiration/pom.xml @@ -5,7 +5,7 @@ com.wyocv wyo-cv - 1.4.0-SNAPSHOT + 2.0.0 cert-expiration diff --git a/cv-data-controller/Dockerfile b/cv-data-controller/Dockerfile index aa1315beb..15162929c 100644 --- a/cv-data-controller/Dockerfile +++ b/cv-data-controller/Dockerfile @@ -2,4 +2,4 @@ FROM maven:3.8-eclipse-temurin-21-alpine ADD . /home/wyocv/wyocv_applications/cv-data-controller -CMD java --add-opens java.base/java.lang=ALL-UNNAMED -jar /home/wyocv/wyocv_applications/cv-data-controller/cv-data-controller-1.4.0-SNAPSHOT.jar +CMD java --add-opens java.base/java.lang=ALL-UNNAMED -jar /home/wyocv/wyocv_applications/cv-data-controller/cv-data-controller-2.0.0.jar diff --git a/cv-data-controller/pom.xml b/cv-data-controller/pom.xml index e0d5e9533..eb51634e0 100644 --- a/cv-data-controller/pom.xml +++ b/cv-data-controller/pom.xml @@ -7,7 +7,7 @@ com.wyocv wyo-cv - 1.4.0-SNAPSHOT + 2.0.0 diff --git a/cv-data-service-library/pom.xml b/cv-data-service-library/pom.xml index 0b10b989d..552f01c84 100644 --- a/cv-data-service-library/pom.xml +++ b/cv-data-service-library/pom.xml @@ -4,7 +4,7 @@ com.wyocv wyo-cv - 1.4.0-SNAPSHOT + 2.0.0 cv-data-service-library diff --git a/cv-data-tasks/Dockerfile b/cv-data-tasks/Dockerfile index fb6a92067..dda4b6f66 100644 --- a/cv-data-tasks/Dockerfile +++ b/cv-data-tasks/Dockerfile @@ -1,5 +1,5 @@ # Required resources for deployment: -# - cv-data-tasks-1.4.0-SNAPSHOT.jar +# - cv-data-tasks-2.0.0.jar FROM maven:3.8-eclipse-temurin-21-alpine @@ -10,4 +10,4 @@ ADD . $install_dir # Uncomment and modify the certificate name on the following line to import a certificate into the Java keystore # RUN keytool -import -alias resdf -storepass changeit -noprompt -cacerts -file ${install_dir}/.cer -CMD java -jar ${install_dir}/cv-data-tasks-1.4.0-SNAPSHOT.jar +CMD java -jar ${install_dir}/cv-data-tasks-2.0.0.jar diff --git a/cv-data-tasks/pom.xml b/cv-data-tasks/pom.xml index 43d6188c4..6265b5b9e 100644 --- a/cv-data-tasks/pom.xml +++ b/cv-data-tasks/pom.xml @@ -10,7 +10,7 @@ com.wyocv wyo-cv - 1.4.0-SNAPSHOT + 2.0.0 diff --git a/local-deployment/docker-compose.yml b/local-deployment/docker-compose.yml index 9ff1b78a0..89dd8727e 100644 --- a/local-deployment/docker-compose.yml +++ b/local-deployment/docker-compose.yml @@ -1,109 +1,109 @@ version: "2" services: # external dependencies ---------------------------------------------- - kafka: - image: bitnami/kafka:latest - hostname: kafka - ports: - - "9092:9092" - volumes: - - kafka:/bitnami - environment: - KAFKA_ENABLE_KRAFT: "yes" - KAFKA_CFG_PROCESS_ROLES: "broker,controller" - KAFKA_CFG_CONTROLLER_LISTENER_NAMES: "CONTROLLER" - KAFKA_CFG_LISTENERS: "PLAINTEXT://:9094,CONTROLLER://:9093,EXTERNAL://:9092" - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP: "CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,EXTERNAL:PLAINTEXT" - KAFKA_CFG_ADVERTISED_LISTENERS: "PLAINTEXT://kafka:9094,EXTERNAL://${DOCKER_HOST_IP}:9092" - KAFKA_BROKER_ID: "1" - KAFKA_CFG_CONTROLLER_QUORUM_VOTERS: "1@kafka:9093" - ALLOW_PLAINTEXT_LISTENER: "yes" - KAFKA_CFG_NODE_ID: "1" - KAFKA_CFG_DELETE_TOPIC_ENABLE: "true" - KAFKA_CFG_LOG_RETENTION_HOURS: 2 - logging: - options: - max-size: "10m" - max-file: "5" + # kafka: + # image: bitnami/kafka:latest + # hostname: kafka + # ports: + # - "9092:9092" + # volumes: + # - kafka:/bitnami + # environment: + # KAFKA_ENABLE_KRAFT: "yes" + # KAFKA_CFG_PROCESS_ROLES: "broker,controller" + # KAFKA_CFG_CONTROLLER_LISTENER_NAMES: "CONTROLLER" + # KAFKA_CFG_LISTENERS: "PLAINTEXT://:9094,CONTROLLER://:9093,EXTERNAL://:9092" + # KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP: "CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,EXTERNAL:PLAINTEXT" + # KAFKA_CFG_ADVERTISED_LISTENERS: "PLAINTEXT://kafka:9094,EXTERNAL://${DOCKER_HOST_IP}:9092" + # KAFKA_BROKER_ID: "1" + # KAFKA_CFG_CONTROLLER_QUORUM_VOTERS: "1@kafka:9093" + # ALLOW_PLAINTEXT_LISTENER: "yes" + # KAFKA_CFG_NODE_ID: "1" + # KAFKA_CFG_DELETE_TOPIC_ENABLE: "true" + # KAFKA_CFG_LOG_RETENTION_HOURS: 2 + # logging: + # options: + # max-size: "10m" + # max-file: "5" - kafka_init: - image: bitnami/kafka:latest - depends_on: - kafka: - condition: service_started - volumes: - - ./docker-scripts/kafka/kafka_init.sh:/kafka_init.sh - entrypoint: ["/bin/sh", "kafka_init.sh"] + # kafka_init: + # image: bitnami/kafka:latest + # depends_on: + # kafka: + # condition: service_started + # volumes: + # - ./docker-scripts/kafka/kafka_init.sh:/kafka_init.sh + # entrypoint: ["/bin/sh", "kafka_init.sh"] - ode: - image: usdotjpoode/jpo-ode:2024-q2 - ports: - - "8080:8080" - - "9090:9090" - - "46753:46753/udp" - - "46800:46800/udp" - - "47900:47900/udp" - - "44900:44900/udp" - - "44910:44910/udp" - - "44920:44920/udp" - - "44930:44930/udp" - - "44940:44940/udp" - - "5555:5555/udp" - - "6666:6666/udp" - environment: - DOCKER_HOST_IP: ${DOCKER_HOST_IP} - ZK: ${DOCKER_HOST_IP}:2181 - ODE_SECURITY_SVCS_SIGNATURE_URI: http://notused - ODE_RSU_USERNAME: testusername - ODE_RSU_PASSWORD: testpassword - DATA_SIGNING_ENABLED_RSU: false - DATA_SIGNING_ENABLED_SDW: false - DEFAULT_SNMP_PROTOCOL: NTCIP1218 - depends_on: - - kafka - volumes: - - ${DOCKER_SHARED_VOLUME}:/jpo-ode - - ${DOCKER_SHARED_VOLUME}/uploads:/home/uploads - logging: - options: - max-size: "10m" - max-file: "5" + # ode: + # image: usdotjpoode/jpo-ode:2024-q2 + # ports: + # - "8080:8080" + # - "9090:9090" + # - "46753:46753/udp" + # - "46800:46800/udp" + # - "47900:47900/udp" + # - "44900:44900/udp" + # - "44910:44910/udp" + # - "44920:44920/udp" + # - "44930:44930/udp" + # - "44940:44940/udp" + # - "5555:5555/udp" + # - "6666:6666/udp" + # environment: + # DOCKER_HOST_IP: ${DOCKER_HOST_IP} + # ZK: ${DOCKER_HOST_IP}:2181 + # ODE_SECURITY_SVCS_SIGNATURE_URI: http://notused + # ODE_RSU_USERNAME: testusername + # ODE_RSU_PASSWORD: testpassword + # DATA_SIGNING_ENABLED_RSU: false + # DATA_SIGNING_ENABLED_SDW: false + # DEFAULT_SNMP_PROTOCOL: NTCIP1218 + # depends_on: + # - kafka + # volumes: + # - ${DOCKER_SHARED_VOLUME}:/jpo-ode + # - ${DOCKER_SHARED_VOLUME}/uploads:/home/uploads + # logging: + # options: + # max-size: "10m" + # max-file: "5" - adm: - image: usdotjpoode/asn1_codec:2024-q2 - environment: - DOCKER_HOST_IP: ${DOCKER_HOST_IP} - ACM_CONFIG_FILE: adm.properties - ACM_LOG_TO_CONSOLE: "true" - ACM_LOG_TO_FILE: "false" - ACM_LOG_LEVEL: ERROR - depends_on: - - kafka - volumes: - - ${DOCKER_SHARED_VOLUME}:/asn1_codec_share - logging: - options: - max-size: "10m" - max-file: "5" - restart: on-failure + # adm: + # image: usdotjpoode/asn1_codec:2024-q2 + # environment: + # DOCKER_HOST_IP: ${DOCKER_HOST_IP} + # ACM_CONFIG_FILE: adm.properties + # ACM_LOG_TO_CONSOLE: "true" + # ACM_LOG_TO_FILE: "false" + # ACM_LOG_LEVEL: ERROR + # depends_on: + # - kafka + # volumes: + # - ${DOCKER_SHARED_VOLUME}:/asn1_codec_share + # logging: + # options: + # max-size: "10m" + # max-file: "5" + # restart: on-failure - aem: - image: usdotjpoode/asn1_codec:2024-q2 - environment: - DOCKER_HOST_IP: ${DOCKER_HOST_IP} - ACM_CONFIG_FILE: aem.properties - ACM_LOG_TO_CONSOLE: "true" - ACM_LOG_TO_FILE: "false" - ACM_LOG_LEVEL: ERROR - depends_on: - - kafka - volumes: - - ${DOCKER_SHARED_VOLUME}:/asn1_codec_share - logging: - options: - max-size: "10m" - max-file: "5" - restart: on-failure + # aem: + # image: usdotjpoode/asn1_codec:2024-q2 + # environment: + # DOCKER_HOST_IP: ${DOCKER_HOST_IP} + # ACM_CONFIG_FILE: aem.properties + # ACM_LOG_TO_CONSOLE: "true" + # ACM_LOG_TO_FILE: "false" + # ACM_LOG_LEVEL: ERROR + # depends_on: + # - kafka + # volumes: + # - ${DOCKER_SHARED_VOLUME}:/asn1_codec_share + # logging: + # options: + # max-size: "10m" + # max-file: "5" + # restart: on-failure # Note: the SDX does not accept unsigned data, so this is commented out for now # sdw_depositor: @@ -125,33 +125,33 @@ services: # max-size: "10m" # max-file: "5" - postgres: - image: postgis/postgis:15-master - restart: always - ports: - - '5432:5432' - environment: - POSTGRES_USER: ${POSTGRES_USER} - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} - volumes: - - pgdb:/var/lib/postgresql/data - logging: - options: - max-size: '10m' + # postgres: + # image: postgis/postgis:15-master + # restart: always + # ports: + # - '5432:5432' + # environment: + # POSTGRES_USER: ${POSTGRES_USER} + # POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + # volumes: + # - pgdb:/var/lib/postgresql/data + # logging: + # options: + # max-size: '10m' - mongo: - image: mongo - restart: always - environment: - MONGO_INITDB_ROOT_USERNAME: ${MONGO_USER} - MONGO_INITDB_ROOT_PASSWORD: ${MONGO_PASSWORD} - ports: - - '27017:27017' - volumes: - - mongodb_data_container:/data/db - logging: - options: - max-size: '10m' + # mongo: + # image: mongo + # restart: always + # environment: + # MONGO_INITDB_ROOT_USERNAME: ${MONGO_USER} + # MONGO_INITDB_ROOT_PASSWORD: ${MONGO_PASSWORD} + # ports: + # - '27017:27017' + # volumes: + # - mongodb_data_container:/data/db + # logging: + # options: + # max-size: '10m' # end of external dependencies ---------------------------------------------- # internal dependencies ------------------------------------------------------ @@ -188,7 +188,7 @@ services: CONFIG_DB_PASSWORD: ${POSTGRES_PASSWORD} CONFIG_MAXIMUM_POOL_SIZE: 7 CONFIG_CONNECTION_TIMEOUT: 300000 - CONFIG_ODE_URL: http://ode:8080 + CONFIG_ODE_URL: http://${DOCKER_HOST_IP}:8080 CONFIG_ENV: local SPRING_DATA_NEO4J_URI: bolt://milepost-graph-db:7687 CONFIG_ALERT_ADDRESSES: test@gmail.com @@ -206,7 +206,7 @@ services: restart: always environment: SERVER_PORT: 7777 - CONFIG_ODE_URL: http://ode:8080 + CONFIG_ODE_URL: http://${DOCKER_HOST_IP}:8080 CONFIG_DB_URL: jdbc:postgresql://${POSTGRES_DB_HOSTNAME}:5432/${POSTGRES_DB_NAME}?user=${POSTGRES_USER} CONFIG_DB_USERNAME: ${POSTGRES_USER} CONFIG_DB_PASSWORD: ${POSTGRES_PASSWORD} @@ -255,7 +255,7 @@ services: build: ../cv-data-tasks restart: always environment: - CONFIG_ODE_URL: http://ode:8080 + CONFIG_ODE_URL: http://${DOCKER_HOST_IP}:8080 CONFIG_CV_REST_SERVICE: http://cv-data-controller:8888 CONFIG_CV_REST_SERVICE_DEV: http://cv-data-controller:8888 CONFIG_CV_REST_SERVICE_PROD: http://cv-data-controller:8888 @@ -350,7 +350,7 @@ services: build: ../tim-refresh restart: always environment: - CONFIG_ODE_URL: http://ode:8080 + CONFIG_ODE_URL: http://${DOCKER_HOST_IP}:8080 CONFIG_SDW_TTL: oneyear CONFIG_CV_REST_SERVICE: http://cv-data-controller:8888 CONFIG_SDW_REST_URL: ${SDW_REST_URL} diff --git a/logger-kafka-consumer/Dockerfile b/logger-kafka-consumer/Dockerfile index e7a1433e1..71ffac2b4 100644 --- a/logger-kafka-consumer/Dockerfile +++ b/logger-kafka-consumer/Dockerfile @@ -2,4 +2,4 @@ FROM maven:3.8-eclipse-temurin-21-alpine ADD . /home/wyocv/wyocv_applications/logger-kafka-consumer -CMD java -jar /home/wyocv/wyocv_applications/logger-kafka-consumer/logger-kafka-consumer-1.4.0-SNAPSHOT.jar +CMD java -jar /home/wyocv/wyocv_applications/logger-kafka-consumer/logger-kafka-consumer-2.0.0.jar diff --git a/logger-kafka-consumer/pom.xml b/logger-kafka-consumer/pom.xml index cf3999f6e..235025152 100644 --- a/logger-kafka-consumer/pom.xml +++ b/logger-kafka-consumer/pom.xml @@ -10,7 +10,7 @@ com.wyocv wyo-cv - 1.4.0-SNAPSHOT + 2.0.0 logger-kafka-consumer diff --git a/ode-data-logger/Dockerfile b/ode-data-logger/Dockerfile index 3f8bcaab5..8004f2e3f 100644 --- a/ode-data-logger/Dockerfile +++ b/ode-data-logger/Dockerfile @@ -2,4 +2,4 @@ FROM maven:3.8-eclipse-temurin-21-alpine ADD . /home/wyocv/wyocv_applications/ode-data-logger -CMD java -jar /home/wyocv/wyocv_applications/ode-data-logger/ode-data-logger-1.4.0-SNAPSHOT.jar \ No newline at end of file +CMD java -jar /home/wyocv/wyocv_applications/ode-data-logger/ode-data-logger-2.0.0.jar \ No newline at end of file diff --git a/ode-data-logger/pom.xml b/ode-data-logger/pom.xml index 9c6c0e665..7242580ac 100644 --- a/ode-data-logger/pom.xml +++ b/ode-data-logger/pom.xml @@ -5,7 +5,7 @@ com.wyocv wyo-cv - 1.4.0-SNAPSHOT + 2.0.0 ode-data-logger diff --git a/ode-mongo-logger/Dockerfile b/ode-mongo-logger/Dockerfile index d50d5c06f..82f38ce64 100644 --- a/ode-mongo-logger/Dockerfile +++ b/ode-mongo-logger/Dockerfile @@ -2,4 +2,4 @@ FROM maven:3.8-eclipse-temurin-21-alpine ADD . /home/wyocv/wyocv_applications/ode-mongo-logger -CMD java -jar /home/wyocv/wyocv_applications/ode-mongo-logger/ode-mongo-logger-1.4.0-SNAPSHOT.jar +CMD java -jar /home/wyocv/wyocv_applications/ode-mongo-logger/ode-mongo-logger-2.0.0.jar diff --git a/ode-mongo-logger/pom.xml b/ode-mongo-logger/pom.xml index fd11a35fb..c22895755 100644 --- a/ode-mongo-logger/pom.xml +++ b/ode-mongo-logger/pom.xml @@ -4,7 +4,7 @@ com.wyocv wyo-cv - 1.4.0-SNAPSHOT + 2.0.0 diff --git a/ode-wrapper/Dockerfile b/ode-wrapper/Dockerfile index 43ad44fad..f55fa10ff 100644 --- a/ode-wrapper/Dockerfile +++ b/ode-wrapper/Dockerfile @@ -2,4 +2,4 @@ FROM maven:3.8-eclipse-temurin-21-alpine ADD . /home/wyocv/wyocv_applications/ode-wrapper -CMD java -jar /home/wyocv/wyocv_applications/ode-wrapper/ode-wrapper-1.4.0-SNAPSHOT.jar +CMD java -jar /home/wyocv/wyocv_applications/ode-wrapper/ode-wrapper-2.0.0.jar diff --git a/ode-wrapper/pom.xml b/ode-wrapper/pom.xml index 0ab5650b3..ab5cdfff6 100644 --- a/ode-wrapper/pom.xml +++ b/ode-wrapper/pom.xml @@ -9,7 +9,7 @@ com.wyocv wyo-cv - 1.4.0-SNAPSHOT + 2.0.0 diff --git a/pom.xml b/pom.xml index 95889eb51..6c60578ef 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ com.wyocv wyo-cv - 1.4.0-SNAPSHOT + 2.0.0 pom diff --git a/rsu-data-controller/Dockerfile b/rsu-data-controller/Dockerfile index bcc9a172d..b6dc43322 100644 --- a/rsu-data-controller/Dockerfile +++ b/rsu-data-controller/Dockerfile @@ -10,6 +10,6 @@ RUN apt-get install -y snmp RUN apt-get autoremove -y \ && apt-get clean -y -ADD rsu-data-controller-1.4.0-SNAPSHOT.jar /app/ +ADD rsu-data-controller-2.0.0.jar /app/ -CMD java -jar /app/rsu-data-controller-1.4.0-SNAPSHOT.jar \ No newline at end of file +CMD java -jar /app/rsu-data-controller-2.0.0.jar \ No newline at end of file diff --git a/rsu-data-controller/pom.xml b/rsu-data-controller/pom.xml index 5fc377e44..ee15f5d24 100644 --- a/rsu-data-controller/pom.xml +++ b/rsu-data-controller/pom.xml @@ -7,7 +7,7 @@ com.wyocv wyo-cv - 1.4.0-SNAPSHOT + 2.0.0 diff --git a/tim-refresh/Dockerfile b/tim-refresh/Dockerfile index 6467d799f..dc5d9d725 100644 --- a/tim-refresh/Dockerfile +++ b/tim-refresh/Dockerfile @@ -2,4 +2,4 @@ FROM maven:3.8-eclipse-temurin-21-alpine ADD . /home/wyocv/wyocv_applications/tim-refresh -CMD java -jar /home/wyocv/wyocv_applications/tim-refresh/tim-refresh-1.4.0-SNAPSHOT.jar +CMD java -jar /home/wyocv/wyocv_applications/tim-refresh/tim-refresh-2.0.0.jar diff --git a/tim-refresh/pom.xml b/tim-refresh/pom.xml index b404c34ff..4c398c667 100644 --- a/tim-refresh/pom.xml +++ b/tim-refresh/pom.xml @@ -6,7 +6,7 @@ com.wyocv wyo-cv - 1.4.0-SNAPSHOT + 2.0.0 From 3244caed7ba994c985aeac47f48190d337168406 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Fri, 10 Jan 2025 09:35:31 -0700 Subject: [PATCH 038/168] Uncomment local-deployment services --- local-deployment/docker-compose.yml | 250 ++++++++++++++-------------- 1 file changed, 125 insertions(+), 125 deletions(-) diff --git a/local-deployment/docker-compose.yml b/local-deployment/docker-compose.yml index 89dd8727e..a231e34b1 100644 --- a/local-deployment/docker-compose.yml +++ b/local-deployment/docker-compose.yml @@ -1,109 +1,109 @@ version: "2" services: # external dependencies ---------------------------------------------- - # kafka: - # image: bitnami/kafka:latest - # hostname: kafka - # ports: - # - "9092:9092" - # volumes: - # - kafka:/bitnami - # environment: - # KAFKA_ENABLE_KRAFT: "yes" - # KAFKA_CFG_PROCESS_ROLES: "broker,controller" - # KAFKA_CFG_CONTROLLER_LISTENER_NAMES: "CONTROLLER" - # KAFKA_CFG_LISTENERS: "PLAINTEXT://:9094,CONTROLLER://:9093,EXTERNAL://:9092" - # KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP: "CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,EXTERNAL:PLAINTEXT" - # KAFKA_CFG_ADVERTISED_LISTENERS: "PLAINTEXT://kafka:9094,EXTERNAL://${DOCKER_HOST_IP}:9092" - # KAFKA_BROKER_ID: "1" - # KAFKA_CFG_CONTROLLER_QUORUM_VOTERS: "1@kafka:9093" - # ALLOW_PLAINTEXT_LISTENER: "yes" - # KAFKA_CFG_NODE_ID: "1" - # KAFKA_CFG_DELETE_TOPIC_ENABLE: "true" - # KAFKA_CFG_LOG_RETENTION_HOURS: 2 - # logging: - # options: - # max-size: "10m" - # max-file: "5" + kafka: + image: bitnami/kafka:latest + hostname: kafka + ports: + - "9092:9092" + volumes: + - kafka:/bitnami + environment: + KAFKA_ENABLE_KRAFT: "yes" + KAFKA_CFG_PROCESS_ROLES: "broker,controller" + KAFKA_CFG_CONTROLLER_LISTENER_NAMES: "CONTROLLER" + KAFKA_CFG_LISTENERS: "PLAINTEXT://:9094,CONTROLLER://:9093,EXTERNAL://:9092" + KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP: "CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,EXTERNAL:PLAINTEXT" + KAFKA_CFG_ADVERTISED_LISTENERS: "PLAINTEXT://kafka:9094,EXTERNAL://${DOCKER_HOST_IP}:9092" + KAFKA_BROKER_ID: "1" + KAFKA_CFG_CONTROLLER_QUORUM_VOTERS: "1@kafka:9093" + ALLOW_PLAINTEXT_LISTENER: "yes" + KAFKA_CFG_NODE_ID: "1" + KAFKA_CFG_DELETE_TOPIC_ENABLE: "true" + KAFKA_CFG_LOG_RETENTION_HOURS: 2 + logging: + options: + max-size: "10m" + max-file: "5" - # kafka_init: - # image: bitnami/kafka:latest - # depends_on: - # kafka: - # condition: service_started - # volumes: - # - ./docker-scripts/kafka/kafka_init.sh:/kafka_init.sh - # entrypoint: ["/bin/sh", "kafka_init.sh"] + kafka_init: + image: bitnami/kafka:latest + depends_on: + kafka: + condition: service_started + volumes: + - ./docker-scripts/kafka/kafka_init.sh:/kafka_init.sh + entrypoint: ["/bin/sh", "kafka_init.sh"] - # ode: - # image: usdotjpoode/jpo-ode:2024-q2 - # ports: - # - "8080:8080" - # - "9090:9090" - # - "46753:46753/udp" - # - "46800:46800/udp" - # - "47900:47900/udp" - # - "44900:44900/udp" - # - "44910:44910/udp" - # - "44920:44920/udp" - # - "44930:44930/udp" - # - "44940:44940/udp" - # - "5555:5555/udp" - # - "6666:6666/udp" - # environment: - # DOCKER_HOST_IP: ${DOCKER_HOST_IP} - # ZK: ${DOCKER_HOST_IP}:2181 - # ODE_SECURITY_SVCS_SIGNATURE_URI: http://notused - # ODE_RSU_USERNAME: testusername - # ODE_RSU_PASSWORD: testpassword - # DATA_SIGNING_ENABLED_RSU: false - # DATA_SIGNING_ENABLED_SDW: false - # DEFAULT_SNMP_PROTOCOL: NTCIP1218 - # depends_on: - # - kafka - # volumes: - # - ${DOCKER_SHARED_VOLUME}:/jpo-ode - # - ${DOCKER_SHARED_VOLUME}/uploads:/home/uploads - # logging: - # options: - # max-size: "10m" - # max-file: "5" + ode: + image: usdotjpoode/jpo-ode:2024-q2 + ports: + - "8080:8080" + - "9090:9090" + - "46753:46753/udp" + - "46800:46800/udp" + - "47900:47900/udp" + - "44900:44900/udp" + - "44910:44910/udp" + - "44920:44920/udp" + - "44930:44930/udp" + - "44940:44940/udp" + - "5555:5555/udp" + - "6666:6666/udp" + environment: + DOCKER_HOST_IP: ${DOCKER_HOST_IP} + ZK: ${DOCKER_HOST_IP}:2181 + ODE_SECURITY_SVCS_SIGNATURE_URI: http://notused + ODE_RSU_USERNAME: testusername + ODE_RSU_PASSWORD: testpassword + DATA_SIGNING_ENABLED_RSU: false + DATA_SIGNING_ENABLED_SDW: false + DEFAULT_SNMP_PROTOCOL: NTCIP1218 + depends_on: + - kafka + volumes: + - ${DOCKER_SHARED_VOLUME}:/jpo-ode + - ${DOCKER_SHARED_VOLUME}/uploads:/home/uploads + logging: + options: + max-size: "10m" + max-file: "5" - # adm: - # image: usdotjpoode/asn1_codec:2024-q2 - # environment: - # DOCKER_HOST_IP: ${DOCKER_HOST_IP} - # ACM_CONFIG_FILE: adm.properties - # ACM_LOG_TO_CONSOLE: "true" - # ACM_LOG_TO_FILE: "false" - # ACM_LOG_LEVEL: ERROR - # depends_on: - # - kafka - # volumes: - # - ${DOCKER_SHARED_VOLUME}:/asn1_codec_share - # logging: - # options: - # max-size: "10m" - # max-file: "5" - # restart: on-failure + adm: + image: usdotjpoode/asn1_codec:2024-q2 + environment: + DOCKER_HOST_IP: ${DOCKER_HOST_IP} + ACM_CONFIG_FILE: adm.properties + ACM_LOG_TO_CONSOLE: "true" + ACM_LOG_TO_FILE: "false" + ACM_LOG_LEVEL: ERROR + depends_on: + - kafka + volumes: + - ${DOCKER_SHARED_VOLUME}:/asn1_codec_share + logging: + options: + max-size: "10m" + max-file: "5" + restart: on-failure - # aem: - # image: usdotjpoode/asn1_codec:2024-q2 - # environment: - # DOCKER_HOST_IP: ${DOCKER_HOST_IP} - # ACM_CONFIG_FILE: aem.properties - # ACM_LOG_TO_CONSOLE: "true" - # ACM_LOG_TO_FILE: "false" - # ACM_LOG_LEVEL: ERROR - # depends_on: - # - kafka - # volumes: - # - ${DOCKER_SHARED_VOLUME}:/asn1_codec_share - # logging: - # options: - # max-size: "10m" - # max-file: "5" - # restart: on-failure + aem: + image: usdotjpoode/asn1_codec:2024-q2 + environment: + DOCKER_HOST_IP: ${DOCKER_HOST_IP} + ACM_CONFIG_FILE: aem.properties + ACM_LOG_TO_CONSOLE: "true" + ACM_LOG_TO_FILE: "false" + ACM_LOG_LEVEL: ERROR + depends_on: + - kafka + volumes: + - ${DOCKER_SHARED_VOLUME}:/asn1_codec_share + logging: + options: + max-size: "10m" + max-file: "5" + restart: on-failure # Note: the SDX does not accept unsigned data, so this is commented out for now # sdw_depositor: @@ -125,33 +125,33 @@ services: # max-size: "10m" # max-file: "5" - # postgres: - # image: postgis/postgis:15-master - # restart: always - # ports: - # - '5432:5432' - # environment: - # POSTGRES_USER: ${POSTGRES_USER} - # POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} - # volumes: - # - pgdb:/var/lib/postgresql/data - # logging: - # options: - # max-size: '10m' + postgres: + image: postgis/postgis:15-master + restart: always + ports: + - '5432:5432' + environment: + POSTGRES_USER: ${POSTGRES_USER} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + volumes: + - pgdb:/var/lib/postgresql/data + logging: + options: + max-size: '10m' - # mongo: - # image: mongo - # restart: always - # environment: - # MONGO_INITDB_ROOT_USERNAME: ${MONGO_USER} - # MONGO_INITDB_ROOT_PASSWORD: ${MONGO_PASSWORD} - # ports: - # - '27017:27017' - # volumes: - # - mongodb_data_container:/data/db - # logging: - # options: - # max-size: '10m' + mongo: + image: mongo + restart: always + environment: + MONGO_INITDB_ROOT_USERNAME: ${MONGO_USER} + MONGO_INITDB_ROOT_PASSWORD: ${MONGO_PASSWORD} + ports: + - '27017:27017' + volumes: + - mongodb_data_container:/data/db + logging: + options: + max-size: '10m' # end of external dependencies ---------------------------------------------- # internal dependencies ------------------------------------------------------ From 4451c38a6f7266b47a4b1404ff989be8124c0d6e Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Fri, 10 Jan 2025 09:37:24 -0700 Subject: [PATCH 039/168] Remove DOCKER_HOST_IP from CONFIG_ODE_URL --- local-deployment/docker-compose.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/local-deployment/docker-compose.yml b/local-deployment/docker-compose.yml index a231e34b1..9ff1b78a0 100644 --- a/local-deployment/docker-compose.yml +++ b/local-deployment/docker-compose.yml @@ -188,7 +188,7 @@ services: CONFIG_DB_PASSWORD: ${POSTGRES_PASSWORD} CONFIG_MAXIMUM_POOL_SIZE: 7 CONFIG_CONNECTION_TIMEOUT: 300000 - CONFIG_ODE_URL: http://${DOCKER_HOST_IP}:8080 + CONFIG_ODE_URL: http://ode:8080 CONFIG_ENV: local SPRING_DATA_NEO4J_URI: bolt://milepost-graph-db:7687 CONFIG_ALERT_ADDRESSES: test@gmail.com @@ -206,7 +206,7 @@ services: restart: always environment: SERVER_PORT: 7777 - CONFIG_ODE_URL: http://${DOCKER_HOST_IP}:8080 + CONFIG_ODE_URL: http://ode:8080 CONFIG_DB_URL: jdbc:postgresql://${POSTGRES_DB_HOSTNAME}:5432/${POSTGRES_DB_NAME}?user=${POSTGRES_USER} CONFIG_DB_USERNAME: ${POSTGRES_USER} CONFIG_DB_PASSWORD: ${POSTGRES_PASSWORD} @@ -255,7 +255,7 @@ services: build: ../cv-data-tasks restart: always environment: - CONFIG_ODE_URL: http://${DOCKER_HOST_IP}:8080 + CONFIG_ODE_URL: http://ode:8080 CONFIG_CV_REST_SERVICE: http://cv-data-controller:8888 CONFIG_CV_REST_SERVICE_DEV: http://cv-data-controller:8888 CONFIG_CV_REST_SERVICE_PROD: http://cv-data-controller:8888 @@ -350,7 +350,7 @@ services: build: ../tim-refresh restart: always environment: - CONFIG_ODE_URL: http://${DOCKER_HOST_IP}:8080 + CONFIG_ODE_URL: http://ode:8080 CONFIG_SDW_TTL: oneyear CONFIG_CV_REST_SERVICE: http://cv-data-controller:8888 CONFIG_SDW_REST_URL: ${SDW_REST_URL} From 164ec8d20a0b11e787d93061d6e4dc9ada160b02 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 23 Jan 2025 14:40:03 -0700 Subject: [PATCH 040/168] Remove unnecessary tables/triggers/etc. from .sql files --- .../pgsql/setup/sql/1-create_all_tables.sql | 85 +++++++------------ .../pgsql/setup/sql/4-create_all_triggers.sql | 15 ---- .../pgsql/teardown/sql/1-drop_all_tables.sql | 2 - 3 files changed, 31 insertions(+), 71 deletions(-) diff --git a/db-scripts/pgsql/setup/sql/1-create_all_tables.sql b/db-scripts/pgsql/setup/sql/1-create_all_tables.sql index b8c72654c..af409be51 100644 --- a/db-scripts/pgsql/setup/sql/1-create_all_tables.sql +++ b/db-scripts/pgsql/setup/sql/1-create_all_tables.sql @@ -3,7 +3,7 @@ SET client_encoding TO 'UTF8'; -- not part of a dependency relationship -- -CREATE TABLE active_tim_holding ( +CREATE TABLE IF NOT EXISTS active_tim_holding ( active_tim_holding_id bigint NOT NULL, client_id varchar(255), direction varchar(50) NOT NULL, @@ -29,7 +29,7 @@ ALTER TABLE active_tim_holding ALTER COLUMN END_LONGITUDE SET NOT NULL; ALTER TABLE active_tim_holding ALTER COLUMN DIRECTION SET NOT NULL; -CREATE TABLE http_logging ( +CREATE TABLE IF NOT EXISTS http_logging ( http_logging_id bigint NOT NULL, request_time timestamp NOT NULL, rest_request varchar(2000) NOT NULL, @@ -41,7 +41,7 @@ ALTER TABLE http_logging ALTER COLUMN REQUEST_TIME SET NOT NULL; ALTER TABLE http_logging ALTER COLUMN REST_REQUEST SET NOT NULL; -CREATE TABLE milepost_test ( +CREATE TABLE IF NOT EXISTS milepost_test ( route varchar(255), milepost decimal(38,8), direction varchar(255), @@ -52,7 +52,7 @@ CREATE TABLE milepost_test ( ) ; -CREATE TABLE mileposts ( +CREATE TABLE IF NOT EXISTS mileposts ( common_name varchar(20), direction varchar(1), milepost decimal(38,8), @@ -63,7 +63,7 @@ CREATE TABLE mileposts ( ) ; -CREATE TABLE rw_buffer_action_lut ( +CREATE TABLE IF NOT EXISTS rw_buffer_action_lut ( description varchar(50), code varchar(20), rw_buffer_action_lut_id bigint NOT NULL @@ -71,7 +71,7 @@ CREATE TABLE rw_buffer_action_lut ( ALTER TABLE rw_buffer_action_lut ADD PRIMARY KEY (rw_buffer_action_lut_id); -CREATE TABLE tim_type ( +CREATE TABLE IF NOT EXISTS tim_type ( type varchar(10), description varchar(255), tim_type_id bigint NOT NULL @@ -79,7 +79,7 @@ CREATE TABLE tim_type ( ALTER TABLE tim_type ADD PRIMARY KEY (tim_type_id); -CREATE TABLE entity_type ( +CREATE TABLE IF NOT EXISTS entity_type ( entity_type_id bigint NOT NULL, name varchar(128) NOT NULL, description varchar(255) @@ -89,7 +89,7 @@ ALTER TABLE entity_type ALTER COLUMN ENTITY_TYPE_ID SET NOT NULL; ALTER TABLE entity_type ALTER COLUMN NAME SET NOT NULL; -CREATE TABLE status_type ( +CREATE TABLE IF NOT EXISTS status_type ( status_type_id bigint NOT NULL, name varchar(128) NOT NULL, description varchar(255) @@ -99,7 +99,7 @@ ALTER TABLE status_type ALTER COLUMN STATUS_TYPE_ID SET NOT NULL; ALTER TABLE status_type ALTER COLUMN NAME SET NOT NULL; -CREATE TABLE security_result_code_type ( +CREATE TABLE IF NOT EXISTS security_result_code_type ( security_result_code_type varchar(255) NOT NULL, security_result_code_type_id bigint NOT NULL ) ; @@ -107,7 +107,7 @@ ALTER TABLE security_result_code_type ADD PRIMARY KEY (security_result_code_type ALTER TABLE security_result_code_type ALTER COLUMN SECURITY_RESULT_CODE_TYPE SET NOT NULL; -CREATE TABLE category ( +CREATE TABLE IF NOT EXISTS category ( category_id bigint NOT NULL, category varchar(255) ) ; @@ -115,7 +115,7 @@ ALTER TABLE category ADD PRIMARY KEY (category_id); ALTER TABLE category ALTER COLUMN CATEGORY_ID SET NOT NULL; -CREATE TABLE node_xy ( +CREATE TABLE IF NOT EXISTS node_xy ( node_xy_id bigint NOT NULL, delta varchar(255), node_lat double precision, @@ -129,7 +129,7 @@ ALTER TABLE node_xy ADD PRIMARY KEY (node_xy_id); ALTER TABLE node_xy ALTER COLUMN NODE_XY_ID SET NOT NULL; -CREATE TABLE node_ll ( +CREATE TABLE IF NOT EXISTS node_ll ( node_ll_id bigint NOT NULL, delta varchar(255), node_lat double precision, @@ -143,7 +143,7 @@ ALTER TABLE node_ll ADD PRIMARY KEY (node_ll_id); ALTER TABLE node_ll ALTER COLUMN NODE_LL_ID SET NOT NULL; -CREATE TABLE computed_lane ( +CREATE TABLE IF NOT EXISTS computed_lane ( computed_lane_id bigint NOT NULL, lane_id bigint NOT NULL, offset_small_x bigint NOT NULL, @@ -163,17 +163,6 @@ ALTER TABLE computed_lane ALTER COLUMN OFFSET_SMALL_Y SET NOT NULL; ALTER TABLE computed_lane ALTER COLUMN OFFSET_LARGE_Y SET NOT NULL; -CREATE TABLE rsu_firmware ( - firmware_id varchar(128) NOT NULL, - firmware_file varchar(255) NOT NULL, - update_process varchar(255), - release_date timestamp(0) NOT NULL -) ; -ALTER TABLE rsu_firmware ADD PRIMARY KEY (firmware_id); -ALTER TABLE rsu_firmware ALTER COLUMN FIRMWARE_FILE SET NOT NULL; -ALTER TABLE rsu_firmware ALTER COLUMN RELEASE_DATE SET NOT NULL; - - CREATE TABLE status_log ( log_id bigint NOT NULL, status_time timestamp NOT NULL, @@ -193,7 +182,7 @@ ALTER TABLE status_log ADD CONSTRAINT entypetolog_fk FOREIGN KEY (entity_type_id ALTER TABLE status_log ADD CONSTRAINT sttypetolog_fk FOREIGN KEY (status_type_id) REFERENCES status_type(status_type_id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE; -CREATE TABLE itis_code ( +CREATE TABLE IF NOT EXISTS itis_code ( itis_code_id bigint NOT NULL, description varchar(255) NOT NULL, category_id bigint NOT NULL, @@ -206,7 +195,7 @@ ALTER TABLE itis_code ALTER COLUMN CATEGORY_ID SET NOT NULL; ALTER TABLE itis_code ADD CONSTRAINT fk_category FOREIGN KEY (category_id) REFERENCES category(category_id) ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE; -CREATE TABLE tim ( +CREATE TABLE IF NOT EXISTS tim ( msg_cnt varchar(255), url_b varchar(255), time_stamp timestamp, @@ -243,7 +232,7 @@ ALTER TABLE tim ADD PRIMARY KEY (tim_id); ALTER TABLE tim ADD CONSTRAINT fk_sec_result_code_type_tim FOREIGN KEY (security_result_code) REFERENCES security_result_code_type(security_result_code_type_id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE; -CREATE TABLE shape_point ( +CREATE TABLE IF NOT EXISTS shape_point ( shape_point_id bigint NOT NULL, lane_width bigint, directionality bigint, @@ -258,7 +247,7 @@ ALTER TABLE shape_point ALTER COLUMN SHAPE_POINT_ID SET NOT NULL; ALTER TABLE shape_point ADD CONSTRAINT fk_computed_lane_shape_point FOREIGN KEY (computed_lane_id) REFERENCES computed_lane(computed_lane_id) ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE; -CREATE TABLE path ( +CREATE TABLE IF NOT EXISTS path ( path_id bigint NOT NULL, scale bigint, type varchar(255), @@ -269,7 +258,7 @@ ALTER TABLE path ALTER COLUMN PATH_ID SET NOT NULL; ALTER TABLE path ADD CONSTRAINT fk_computed_lane_path FOREIGN KEY (computed_lane_id) REFERENCES computed_lane(computed_lane_id) ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE; -CREATE TABLE data_list ( +CREATE TABLE IF NOT EXISTS data_list ( data_list_id bigint NOT NULL, node_xy_id bigint NOT NULL, path_endpoint_angle bigint NOT NULL, @@ -289,18 +278,6 @@ ALTER TABLE data_list ALTER COLUMN LANE_ANGLE SET NOT NULL; ALTER TABLE data_list ADD CONSTRAINT fk_node_xy_data_list FOREIGN KEY (node_xy_id) REFERENCES node_xy(node_xy_id) ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE; -CREATE TABLE rsu ( - rsu_id bigint NOT NULL, - deviceid integer, - update_username varchar(255) DEFAULT 'ADMIN', - update_password varchar(128), - firmware_id varchar(128) -) ; -ALTER TABLE rsu ADD PRIMARY KEY (rsu_id); -ALTER TABLE rsu ALTER COLUMN RSU_ID SET NOT NULL; -ALTER TABLE rsu ADD CONSTRAINT fk_rsu2firmware FOREIGN KEY (firmware_id) REFERENCES rsu_firmware(firmware_id) ON DELETE SET NULL NOT DEFERRABLE INITIALLY IMMEDIATE; - - CREATE TABLE incident_action_lut ( description varchar(60), code varchar(10), @@ -311,7 +288,7 @@ ALTER TABLE incident_action_lut ADD PRIMARY KEY (incident_action_lut_id); ALTER TABLE incident_action_lut ADD CONSTRAINT fk_itis_code_incident_action FOREIGN KEY (itis_code_id) REFERENCES itis_code(itis_code_id) ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE; -CREATE TABLE incident_effect_lut ( +CREATE TABLE IF NOT EXISTS incident_effect_lut ( description varchar(50), code varchar(20), itis_code_id bigint, @@ -321,7 +298,7 @@ ALTER TABLE incident_effect_lut ADD PRIMARY KEY (incident_effect_lut_id); ALTER TABLE incident_effect_lut ADD CONSTRAINT fk_itis_code_incident_effect FOREIGN KEY (itis_code_id) REFERENCES itis_code(itis_code_id) ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE; -CREATE TABLE incident_problem_lut ( +CREATE TABLE IF NOT EXISTS incident_problem_lut ( description varchar(50), code varchar(20), itis_code_id bigint, @@ -331,7 +308,7 @@ ALTER TABLE incident_problem_lut ADD PRIMARY KEY (incident_problem_lut_id); ALTER TABLE incident_problem_lut ADD CONSTRAINT fk_itis_code_incident_problem FOREIGN KEY (itis_code_id) REFERENCES itis_code(itis_code_id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE; -CREATE TABLE active_tim ( +CREATE TABLE IF NOT EXISTS active_tim ( tim_id bigint, milepost_start double precision, milepost_stop double precision, @@ -356,7 +333,7 @@ ALTER TABLE active_tim ADD PRIMARY KEY (active_tim_id); ALTER TABLE active_tim ADD CONSTRAINT fk_tim_active_tim FOREIGN KEY (tim_id) REFERENCES tim(tim_id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE; -CREATE TABLE data_frame ( +CREATE TABLE IF NOT EXISTS data_frame ( data_frame_id bigint NOT NULL, tim_id bigint NOT NULL, ssp_tim_rights integer, @@ -385,7 +362,7 @@ ALTER TABLE data_frame ALTER COLUMN TIM_ID SET NOT NULL; ALTER TABLE data_frame ADD CONSTRAINT fk_tim_df FOREIGN KEY (tim_id) REFERENCES tim(tim_id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE; -CREATE TABLE path_node_ll ( +CREATE TABLE IF NOT EXISTS path_node_ll ( path_node_ll_id bigint NOT NULL, path_id bigint NOT NULL, node_ll_id bigint NOT NULL @@ -399,7 +376,7 @@ ALTER TABLE path_node_ll ADD CONSTRAINT fk_path_node_ll_node_ll FOREIGN KEY (nod ALTER TABLE path_node_ll ADD CONSTRAINT fk_path_node_ll_path FOREIGN KEY (path_id) REFERENCES path(path_id) ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE; -CREATE TABLE path_node_xy ( +CREATE TABLE IF NOT EXISTS path_node_xy ( path_node_xy_id bigint NOT NULL, path_id bigint NOT NULL, node_xy_id bigint NOT NULL @@ -413,7 +390,7 @@ ALTER TABLE path_node_xy ADD CONSTRAINT fk_node_xy_path FOREIGN KEY (node_xy_id) ALTER TABLE path_node_xy ADD CONSTRAINT fk_path_node_xy FOREIGN KEY (path_id) REFERENCES path(path_id) ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE; -CREATE TABLE shape_point_node_xy ( +CREATE TABLE IF NOT EXISTS shape_point_node_xy ( shape_point_node_xy_id bigint NOT NULL, shape_point_id bigint NOT NULL, node_xy_id bigint NOT NULL @@ -427,7 +404,7 @@ ALTER TABLE shape_point_node_xy ADD CONSTRAINT fk_node_xy_shape_point FOREIGN KE ALTER TABLE shape_point_node_xy ADD CONSTRAINT fk_shape_point_node_xy FOREIGN KEY (shape_point_id) REFERENCES shape_point(shape_point_id) ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE; -CREATE TABLE old_region ( +CREATE TABLE IF NOT EXISTS old_region ( old_region_id bigint NOT NULL, direction varchar(255) NOT NULL, extent bigint, @@ -452,7 +429,7 @@ ALTER TABLE old_region ALTER COLUMN CIRCLE_UNITS SET NOT NULL; ALTER TABLE old_region ADD CONSTRAINT fk_shape_point FOREIGN KEY (shape_point_id) REFERENCES shape_point(shape_point_id) ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE; -CREATE TABLE tim_rsu ( +CREATE TABLE IF NOT EXISTS tim_rsu ( tim_rsu_id bigint NOT NULL, rsu_id bigint NOT NULL, tim_id bigint NOT NULL, @@ -463,13 +440,13 @@ ALTER TABLE tim_rsu ADD PRIMARY KEY (tim_rsu_id); ALTER TABLE tim_rsu ALTER COLUMN TIM_RSU_ID SET NOT NULL; ALTER TABLE tim_rsu ALTER COLUMN RSU_ID SET NOT NULL; ALTER TABLE tim_rsu ALTER COLUMN TIM_ID SET NOT NULL; -ALTER TABLE tim_rsu ADD CONSTRAINT sys_c0021538 FOREIGN KEY (rsu_id) REFERENCES rsu(rsu_id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE; +ALTER TABLE tim_rsu ADD CONSTRAINT sys_c0021538 FOREIGN KEY (rsu_id) REFERENCES rsus(rsu_id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE; ALTER TABLE tim_rsu ADD CONSTRAINT sys_c0021539 FOREIGN KEY (tim_id) REFERENCES tim(tim_id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE; -- dependent level 3 (dependent on level 2 tables and possibly level 1/level 0 tables) -- -CREATE TABLE data_frame_itis_code ( +CREATE TABLE IF NOT EXISTS data_frame_itis_code ( data_frame_itis_code_id bigint NOT NULL, itis_code_id bigint, data_frame_id bigint NOT NULL, @@ -484,7 +461,7 @@ ALTER TABLE data_frame_itis_code ADD CONSTRAINT fk_data_frame_itis_code FOREIGN ALTER TABLE data_frame_itis_code ADD CONSTRAINT fk_itis_code FOREIGN KEY (itis_code_id) REFERENCES itis_code(itis_code_id) ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE; -CREATE TABLE region ( +CREATE TABLE IF NOT EXISTS region ( region_id bigint NOT NULL, data_frame_id bigint NOT NULL, name varchar(255), @@ -522,7 +499,7 @@ ALTER TABLE region ADD CONSTRAINT fk_old_region FOREIGN KEY (old_region_id) REFE ALTER TABLE region ADD CONSTRAINT fk_path FOREIGN KEY (path_id) REFERENCES path(path_id) ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE; -CREATE TABLE region_list ( +CREATE TABLE IF NOT EXISTS region_list ( region_list_id bigint NOT NULL, old_region_id bigint NOT NULL, x_offset bigint NOT NULL, diff --git a/db-scripts/pgsql/setup/sql/4-create_all_triggers.sql b/db-scripts/pgsql/setup/sql/4-create_all_triggers.sql index cdf6466b7..64750cd7b 100644 --- a/db-scripts/pgsql/setup/sql/4-create_all_triggers.sql +++ b/db-scripts/pgsql/setup/sql/4-create_all_triggers.sql @@ -362,21 +362,6 @@ CREATE TRIGGER trg_region_list_id BEFORE INSERT ON region_list FOR EACH ROW EXECUTE PROCEDURE trigger_fct_trg_region_list_id(); -DROP TRIGGER IF EXISTS trg_rsu_id ON rsu CASCADE; -CREATE OR REPLACE FUNCTION trigger_fct_trg_rsu_id() RETURNS trigger AS $BODY$ -BEGIN -select nextval('rsu_id_seq') -into STRICT NEW.rsu_id -; -RETURN NEW; -end -$BODY$ - LANGUAGE 'plpgsql' SECURITY DEFINER; - -CREATE TRIGGER trg_rsu_id - BEFORE INSERT ON rsu FOR EACH ROW - EXECUTE PROCEDURE trigger_fct_trg_rsu_id(); - DROP TRIGGER IF EXISTS trg_shape_point_id ON shape_point CASCADE; CREATE OR REPLACE FUNCTION trigger_fct_trg_shape_point_id() RETURNS trigger AS $BODY$ BEGIN diff --git a/db-scripts/pgsql/teardown/sql/1-drop_all_tables.sql b/db-scripts/pgsql/teardown/sql/1-drop_all_tables.sql index d1a7f777f..37da92f81 100644 --- a/db-scripts/pgsql/teardown/sql/1-drop_all_tables.sql +++ b/db-scripts/pgsql/teardown/sql/1-drop_all_tables.sql @@ -13,14 +13,12 @@ drop table if exists category cascade; drop table if exists node_xy cascade; drop table if exists node_ll cascade; drop table if exists computed_lane cascade; -drop table if exists rsu_firmware cascade; drop table if exists status_log cascade; drop table if exists itis_code cascade; drop table if exists tim cascade; drop table if exists shape_point cascade; drop table if exists path cascade; drop table if exists data_list cascade; -drop table if exists rsu cascade; drop table if exists incident_action_lut cascade; drop table if exists incident_effect_lut cascade; drop table if exists incident_problem_lut cascade; From 856478959e4e886ca754e4d873939092519f2cc3 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 23 Jan 2025 14:44:11 -0700 Subject: [PATCH 041/168] Update outdated references to rsu table to use existing cv-manager rsus table --- .../controller/ActiveTimController.java | 14 ++-- .../controller/RsuController.java | 73 ++++++++++++------- .../trihydro/library/service/RsuService.java | 31 ++++++-- .../app/services/ActiveTimService.java | 9 +-- .../app/services/RsuService.java | 4 +- 5 files changed, 83 insertions(+), 48 deletions(-) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java index 1afe4c81a..45119991d 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java @@ -532,9 +532,7 @@ public ResponseEntity> GetActiveTimIndicesByRsu(@PathVariable Stri String selectStatement = "select tim_rsu.rsu_index from active_tim"; selectStatement += " inner join tim on active_tim.tim_id = tim.tim_id"; selectStatement += " inner join tim_rsu on tim_rsu.tim_id = tim.tim_id"; - selectStatement += " inner join rsu on rsu.rsu_id = tim_rsu.rsu_id"; - selectStatement += " inner join rsu_view on rsu.deviceid = rsu_view.deviceid"; - selectStatement += " where rsu_view.ipv4_address = '" + rsuTarget + "'"; + selectStatement += " inner join rsus on rsus.rsu_id = tim_rsu.rsu_id"; rs = statement.executeQuery(selectStatement); @@ -1127,12 +1125,11 @@ public ResponseEntity> GetActiveRsuTims() { connection = dbInteractions.getConnectionPool(); statement = connection.createStatement(); - String query = "select active_tim.*, rsu_view.ipv4_address, tim_rsu.rsu_index from active_tim"; + String query = "select active_tim.*, rsus.ipv4_address, tim_rsu.rsu_index from active_tim"; query += " inner join tim_rsu on active_tim.tim_id = tim_rsu.tim_id"; - query += " inner join rsu on tim_rsu.rsu_id = rsu.rsu_id"; - query += " inner join rsu_view on rsu.deviceid = rsu_view.deviceid"; + query += " inner join rsus on tim_rsu.rsu_id = rsus.rsu_id"; query += " where sat_record_id is null"; - query += " order by rsu_view.ipv4_address, tim_rsu.rsu_index"; // Required by ValidateRsus + query += " order by rsus.ipv4_address, tim_rsu.rsu_index"; // Required by ValidateRsus rs = statement.executeQuery(query); @@ -1205,8 +1202,7 @@ public ResponseEntity GetActiveRsuTim(@RequestBody ActiveRsuTimQueryM statement = connection.createStatement(); String query = "select * from active_tim"; query += " inner join tim_rsu on active_tim.tim_id = tim_rsu.tim_id"; - query += " inner join rsu on tim_rsu.rsu_id = rsu.rsu_id"; - query += " inner join rsu_view on rsu.deviceid = rsu_view.deviceid"; + query += " inner join rsus on tim_rsu.rsu_id = rsus.rsu_id"; query += " where ipv4_address = '" + artqm.getIpv4() + "' and client_id = '" + artqm.getClientId() + "' and active_tim.direction = '" + artqm.getDirection() + "'"; diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/RsuController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/RsuController.java index a3ded3655..e273adf92 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/RsuController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/RsuController.java @@ -37,9 +37,8 @@ public ResponseEntity> SelectAllRsus() { connection = dbInteractions.getConnectionPool(); statement = connection.createStatement(); - // select all RSUs from RSU table - rs = statement.executeQuery( - "select * from rsu inner join rsu_view on rsu.deviceid = rsu_view.deviceid order by milepost asc"); + // select all RSUs from rsus table + rs = statement.executeQuery("select rsu_id, ST_X(ST_AsText(geography)) as longitude, ST_Y(ST_AsText(geography)) as latitude, ipv4_address, primary_route, milepost from rsus order by milepost asc"); while (rs.next()) { WydotRsu rsu = new WydotRsu(); @@ -47,7 +46,7 @@ public ResponseEntity> SelectAllRsus() { rsu.setRsuTarget(rs.getString("IPV4_ADDRESS")); rsu.setLatitude(rs.getBigDecimal("LATITUDE")); rsu.setLongitude(rs.getBigDecimal("LONGITUDE")); - rsu.setRoute(rs.getString("ROUTE")); + rsu.setRoute(rs.getString("PRIMARY_ROUTE")); rsu.setMilepost(rs.getDouble("MILEPOST")); rsus.add(rsu); } @@ -74,9 +73,9 @@ public ResponseEntity> SelectAllRsus() { return ResponseEntity.ok(rsus); } - @RequestMapping(value = "/selectActiveRSUs", method = RequestMethod.GET, headers = "Accept=application/json") - public ResponseEntity> SelectActiveRsus() { - List rsus = new ArrayList(); + @RequestMapping(method = RequestMethod.GET, value = "/rsus-for-tim/{timId}") + public ResponseEntity> GetFullRsusTimIsOn(@PathVariable Long timId) { + List rsus = new ArrayList(); Connection connection = null; ResultSet rs = null; Statement statement = null; @@ -87,15 +86,25 @@ public ResponseEntity> SelectActiveRsus() { // select all RSUs that are labeled as 'Existing' in the WYDOT view rs = statement.executeQuery( - "select rsu.*, rsu_view.latitude, rsu_view.longitude, rsu_view.ipv4_address from rsu inner join rsu_view on rsu.deviceid = rsu_view.deviceid where rsu_view.status = 'Existing'"); + "select rsus.rsu_id, rsu_credentials.username as update_username, " + + "rsu_credentials.password as update_password, ST_X(ST_AsText(rsus.geography)) " + + "as longitude, ST_Y(ST_AsText(rsus.geography)) as latitude, rsus.ipv4_address, " + + "tim_rsu.rsu_index from rsus inner join rsu_credentials on " + + "rsu_credentials.credential_id = rsus.credential_id inner join tim_rsu on " + + "tim_rsu.rsu_id = rsus.rsu_id where tim_rsu.tim_id = " + timId); while (rs.next()) { - WydotRsu rsu = new WydotRsu(); - // rsu.setRsuId(rs.getInt("rsu_id")); + WydotRsuTim rsu = new WydotRsuTim(); rsu.setRsuTarget(rs.getString("IPV4_ADDRESS")); rsu.setLatitude(rs.getBigDecimal("LATITUDE")); rsu.setLongitude(rs.getBigDecimal("LONGITUDE")); - rsus.add(rsu); + rsu.setIndex(rs.getInt("RSU_INDEX")); + rsu.setRsuUsername(rs.getString("UPDATE_USERNAME")); + rsu.setRsuPassword(rs.getString("UPDATE_PASSWORD")); + // only add unique values in + if (!rsus.contains(rsu)) { + rsus.add(rsu); + } } } catch (SQLException e) { e.printStackTrace(); @@ -118,9 +127,9 @@ public ResponseEntity> SelectActiveRsus() { return ResponseEntity.ok(rsus); } - @RequestMapping(method = RequestMethod.GET, value = "/rsus-for-tim/{timId}") - public ResponseEntity> GetFullRsusTimIsOn(@PathVariable Long timId) { - List rsus = new ArrayList(); + @RequestMapping(method = RequestMethod.GET, value = "/rsus-by-geometry/{geometry}") + public ResponseEntity> SelectRsusByGeometry(@PathVariable String geometry) { + ArrayList rsus = new ArrayList(); Connection connection = null; ResultSet rs = null; Statement statement = null; @@ -129,23 +138,32 @@ public ResponseEntity> GetFullRsusTimIsOn(@PathVariable Long t connection = dbInteractions.getConnectionPool(); statement = connection.createStatement(); - // select all RSUs that are labeled as 'Existing' in the WYDOT view + // select all RSUs from RSU table rs = statement.executeQuery( - "select rsu.*, tim_rsu.rsu_index, rsu_view.latitude, rsu_view.longitude, rsu_view.ipv4_address from rsu inner join rsu_view on rsu.deviceid = rsu_view.deviceid inner join tim_rsu on tim_rsu.rsu_id = rsu.rsu_id where tim_rsu.tim_id = " - + timId); + "SELECT rsu_id, ST_X(ST_AsText(geography)) as longitude, " + + "ST_Y(ST_AsText(geography)) as latitude, primary_route, milepost, ipv4_address, sc.username, sc.password " + + "FROM rsus " + + "JOIN snmp_credentials AS sc ON rsus.snmp_credential_id = sc.snmp_credential_id " + + "WHERE rsu_id NOT IN (" + + "SELECT rsu_id " + + "FROM rsu_organization AS ro " + + "JOIN organizations AS o ON ro.organization_id = o.organization_id " + + "WHERE o.name = 'Region 1') " + + "AND ST_Intersects(" + + "ST_Buffer(ST_GeomFromText('" + geometry + "'), 1), geography)" + ); while (rs.next()) { - WydotRsuTim rsu = new WydotRsuTim(); + WydotRsu rsu = new WydotRsu(); + rsu.setRsuId(rs.getInt("RSU_ID")); rsu.setRsuTarget(rs.getString("IPV4_ADDRESS")); rsu.setLatitude(rs.getBigDecimal("LATITUDE")); rsu.setLongitude(rs.getBigDecimal("LONGITUDE")); - rsu.setIndex(rs.getInt("RSU_INDEX")); - rsu.setRsuUsername(rs.getString("UPDATE_USERNAME")); - rsu.setRsuPassword(rs.getString("UPDATE_PASSWORD")); - // only add unique values in - if (!rsus.contains(rsu)) { - rsus.add(rsu); - } + rsu.setRoute(rs.getString("PRIMARY_ROUTE")); + rsu.setMilepost(rs.getDouble("MILEPOST")); + rsu.setRsuUsername(rs.getString("USERNAME")); + rsu.setRsuPassword(rs.getString("PASSWORD")); + rsus.add(rsu); } } catch (SQLException e) { e.printStackTrace(); @@ -181,8 +199,7 @@ public ResponseEntity> SelectRsusByRoute(@PathVariable Strin // select all RSUs from RSU table rs = statement.executeQuery( - "select * from rsu inner join rsu_view on rsu.deviceid = rsu_view.deviceid where rsu_view.route like '%" - + route + "%' and rsu_view.status = 'Existing' order by milepost asc"); + "select rsu_id, ST_X(ST_AsText(geography)) as longitude, ST_Y(ST_AsText(geography)) as latitude, ipv4_address, primary_route, milepost from rsus where primary_route like %'%" + route + "%'"); while (rs.next()) { WydotRsu rsu = new WydotRsu(); @@ -257,4 +274,4 @@ public ResponseEntity> GetActiveRsuTimIndexes(@PathVariable Intege } return ResponseEntity.ok(indexes); } -} +} \ No newline at end of file diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/service/RsuService.java b/cv-data-service-library/src/main/java/com/trihydro/library/service/RsuService.java index 99bc6977a..a4bb929b3 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/service/RsuService.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/service/RsuService.java @@ -6,11 +6,6 @@ import java.util.List; import java.util.stream.Collectors; -import com.trihydro.library.helpers.Utility; -import com.trihydro.library.model.Coordinate; -import com.trihydro.library.model.WydotRsu; -import com.trihydro.library.model.WydotRsuTim; - import org.gavaghan.geodesy.Ellipsoid; import org.gavaghan.geodesy.GeodeticCalculator; import org.gavaghan.geodesy.GeodeticCurve; @@ -19,6 +14,11 @@ import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; +import com.trihydro.library.helpers.Utility; +import com.trihydro.library.model.Coordinate; +import com.trihydro.library.model.WydotRsu; +import com.trihydro.library.model.WydotRsuTim; + @Component public class RsuService extends CvDataServiceLibrary { @@ -43,6 +43,13 @@ public List selectRsusByRoute(String route) { return Arrays.asList(response.getBody()); } + public List selectRsusByGeometry(String geometry) { + String url = String.format("%s/rsus-by-geometry/%s", config.getCvRestService(), geometry); + ResponseEntity response = restTemplateProvider.GetRestTemplate().getForEntity(url, + WydotRsu[].class); + return Arrays.asList(response.getBody()); + } + public List getFullRsusTimIsOn(Long timId) { String url = String.format("%s/rsus-for-tim/%d", config.getCvRestService(), timId); ResponseEntity response = restTemplateProvider.GetRestTemplate().getForEntity(url, @@ -202,6 +209,20 @@ public List getRsusByLatLong(String direction, Coordinate startPoint, return rsus; } + public List getRsusByGeometry(List geometry) { + String coordinates = "LINESTRING("; + for (Coordinate coordinate : geometry) { + coordinates += coordinate.getLongitude() + " " + coordinate.getLatitude() + ","; + } + coordinates = coordinates.substring(0, coordinates.length() - 1) + ")"; + List rsus = selectRsusByGeometry(coordinates); + for (WydotRsu rsu : rsus) { + rsu.setRsuRetries(3); + rsu.setRsuTimeout(5000); + } + return rsus; + } + private List getRsusByRouteWithRetryAndTimeout(String route) { List rsus = selectRsusByRoute(route); for (WydotRsu rsu : rsus) { diff --git a/logger-kafka-consumer/src/main/java/com/trihydro/loggerkafkaconsumer/app/services/ActiveTimService.java b/logger-kafka-consumer/src/main/java/com/trihydro/loggerkafkaconsumer/app/services/ActiveTimService.java index d24a6cabc..e3593bbd0 100644 --- a/logger-kafka-consumer/src/main/java/com/trihydro/loggerkafkaconsumer/app/services/ActiveTimService.java +++ b/logger-kafka-consumer/src/main/java/com/trihydro/loggerkafkaconsumer/app/services/ActiveTimService.java @@ -14,14 +14,14 @@ import java.util.Date; import java.util.TimeZone; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + import com.trihydro.library.helpers.SQLNullHandler; import com.trihydro.library.model.ActiveTim; import com.trihydro.library.model.Coordinate; import com.trihydro.library.tables.TimDbTables; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - @Component public class ActiveTimService extends BaseService { @@ -280,8 +280,7 @@ public ActiveTim getActiveRsuTim(String clientId, String direction, String ipv4A query += " atim.START_LATITUDE, atim.START_LONGITUDE, atim.END_LATITUDE, atim.END_LONGITUDE"; query += " from active_tim atim"; query += " inner join tim_rsu on atim.tim_id = tim_rsu.tim_id"; - query += " inner join rsu on tim_rsu.rsu_id = rsu.rsu_id"; - query += " inner join rsu_view on rsu.deviceid = rsu_view.deviceid"; + query += " inner join rsus on tim_rsu.rsu_id = rsus.rsu_id"; query += " where sat_record_id is null and ipv4_address = '" + ipv4Address + "' and client_id = '" + clientId + "' and atim.direction = '" + direction + "'"; diff --git a/logger-kafka-consumer/src/main/java/com/trihydro/loggerkafkaconsumer/app/services/RsuService.java b/logger-kafka-consumer/src/main/java/com/trihydro/loggerkafkaconsumer/app/services/RsuService.java index 42637a0a2..ce59cd4d1 100644 --- a/logger-kafka-consumer/src/main/java/com/trihydro/loggerkafkaconsumer/app/services/RsuService.java +++ b/logger-kafka-consumer/src/main/java/com/trihydro/loggerkafkaconsumer/app/services/RsuService.java @@ -26,7 +26,9 @@ public ArrayList getRsus() { // select all RSUs from RSU table rs = statement.executeQuery( - "select * from rsu inner join rsu_view on rsu.deviceid = rsu_view.deviceid order by milepost asc"); + "select rsu_id, ST_X(ST_AsText(geography)) as longitude, " + + "ST_Y(ST_AsText(geography)) as latitude, ipv4_address, primary_route, " + + "milepost from rsus order by milepost asc"); while (rs.next()) { WydotRsu rsu = new WydotRsu(); From 7d938efec376cb70c37714fadaff10347b0bbbdd Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 23 Jan 2025 14:48:51 -0700 Subject: [PATCH 042/168] Add geometry, bearing properties to WydotTim --- .../com/trihydro/library/model/WydotTim.java | 60 ++++++++++++++++++- .../controller/WydotTimBaseController.java | 42 +++++++------ .../controller/WydotTimRcController.java | 8 ++- .../controller/WydotTimRwController.java | 33 ++++++++-- 4 files changed, 118 insertions(+), 25 deletions(-) diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/model/WydotTim.java b/cv-data-service-library/src/main/java/com/trihydro/library/model/WydotTim.java index 5d03b0c4d..d2e03f251 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/model/WydotTim.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/model/WydotTim.java @@ -9,9 +9,9 @@ public class WydotTim { @ApiModelProperty(value = "Expected values are I, D, B", required = true) private String direction; - @ApiModelProperty(required = true) + @ApiModelProperty(required = false) private Coordinate startPoint; - @ApiModelProperty(required = true) + @ApiModelProperty(required = false) private Coordinate endPoint; @ApiModelProperty(value = "The common name for the selected route", required = true) private String route; @@ -19,6 +19,10 @@ public class WydotTim { private List itisCodes; @ApiModelProperty(required = true) private String clientId; + @ApiModelProperty(required = false) + protected List geometry; + @ApiModelProperty(required = false) + private Integer bearing; public WydotTim() { @@ -34,6 +38,16 @@ public WydotTim(WydotTim o) { if (o.itisCodes != null) this.itisCodes = new ArrayList<>(o.itisCodes); this.clientId = o.clientId; + if (o.geometry != null) { + this.geometry = new ArrayList<>(o.geometry); + // If geometry is present and has more than one point, set start and end points + if (o.geometry.size() > 1) { + this.startPoint = new Coordinate(o.geometry.get(0).getLatitude(), o.geometry.get(0).getLongitude()); + this.endPoint = new Coordinate(o.geometry.get(o.geometry.size() - 1).getLatitude(), o.geometry.get(o.geometry.size() - 1).getLongitude()); + } + } + if (o.bearing != null) + this.bearing = o.bearing; } public WydotTim copy() { @@ -87,4 +101,46 @@ public String getRoute() { public void setRoute(String route) { this.route = route; } + + public List getGeometry() { + return this.geometry; + } + + public void setGeometry(List geometry) { + this.geometry = geometry; + } + + public Integer getBearing() { + return this.bearing; + } + + public void setBearing(Integer bearing) { + this.bearing = bearing; + } + + public boolean isGeometryValid() { + if (this.geometry != null && this.geometry.size() > 0) { + for (Coordinate coord : this.geometry) { + if (!coord.isValid()) { + return false; + } + } + return true; + } else { + return false; + } + } + + public String getGeometryString() { + if (this.geometry!= null && this.geometry.size() > 0) { + StringBuilder sb = new StringBuilder(); + sb.append("["); + for (Coordinate coord : this.geometry) { + sb.append("{\"latitude\": ").append(coord.getLatitude()).append(", ").append("\"longitude\": ").append(coord.getLongitude()).append("}, "); + } + return sb.toString().trim(); + } else { + return ""; + } + } } \ No newline at end of file diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java index 276123c33..c645fcc93 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java @@ -215,11 +215,15 @@ protected ControllerResult validateInputRw(WydotTimRw tim) { && !tim.getDirection().equalsIgnoreCase("b")) { resultMessages.add("direction not supported"); } - if (tim.getStartPoint() == null || !tim.getStartPoint().isValid()) { - resultMessages.add("Invalid startPoint"); - } - if (tim.getEndPoint() == null || !tim.getEndPoint().isValid()) { - resultMessages.add("Invalid endPoint"); + + // if geometry isn't present check for start/end points + if (!tim.isGeometryValid()) { + if (tim.getStartPoint() == null || !tim.getStartPoint().isValid()) { + resultMessages.add("Invalid startPoint"); + } + if (tim.getEndPoint() == null || !tim.getEndPoint().isValid()) { + resultMessages.add("Invalid endPoint"); + } } if (tim.getHighway() == null) { resultMessages.add("Null value for highway"); @@ -320,12 +324,17 @@ protected ControllerResult validateInputRc(WydotTimRc tim) { && !tim.getDirection().equalsIgnoreCase("d") && !tim.getDirection().equalsIgnoreCase("b")) { resultMessages.add("direction not supported"); } - if (tim.getStartPoint() == null || !tim.getStartPoint().isValid()) { - resultMessages.add("Invalid startPoint"); - } - if (tim.getEndPoint() == null || !tim.getEndPoint().isValid()) { - resultMessages.add("Invalid endPoint"); + + // if geometry isn't present check for start/end points + if (!tim.isGeometryValid()) { + if (tim.getStartPoint() == null || !tim.getStartPoint().isValid()) { + resultMessages.add("Invalid startPoint"); + } + if (tim.getEndPoint() == null || !tim.getEndPoint().isValid()) { + resultMessages.add("Invalid endPoint"); + } } + if (tim.getRoute() == null) { resultMessages.add("Null value for route"); } @@ -642,6 +651,9 @@ protected void expireReduceCreateSendTims(WydotTim wydotTim, TimType timType, St var existingTims = activeTimService.getActiveTimsByClientIdDirection(wydotTim.getClientId(), timTypeId, wydotTim.getDirection()); + // Use wydotTimService to get all mileposts for the TIM + List milepostsAll = wydotTimService.getAllMilepostsForTim(wydotTim); + // Expire existing tims List existingTimIds = new ArrayList(); for (ActiveTim existingTim : existingTims) { @@ -649,9 +661,6 @@ protected void expireReduceCreateSendTims(WydotTim wydotTim, TimType timType, St } timGenerationHelper.expireTimAndResubmitToOde(existingTimIds); - // Get mileposts that will define the TIM's region - var milepostsAll = wydotTimService.getAllMilepostsForTim(wydotTim); - // Per J2735, NodeSetLL's must contain at least 2 nodes. ODE will fail to // PER-encode TIM if we supply less than 2. if (milepostsAll.size() < 2) { @@ -692,10 +701,9 @@ protected void createSendTims(WydotTim wydotTim, TimType timType, String startDa endPoint = new Coordinate(endMp.getLatitude(), endMp.getLongitude()); } - if (Arrays.asList(configuration.getRsuRoutes()).contains(wydotTim.getRoute())) { - // send TIM to RSUs - wydotTimService.sendTimToRsus(wydotTim, timToSend, regionNamePrev, timType, pk, endDateTime, endPoint); - } + // send TIM to RSUs + wydotTimService.sendTimToRsus(wydotTim, timToSend, regionNamePrev, timType, pk, endDateTime, endPoint); + // send TIM to SDW // remove rsus from TIM timToSend.getRequest().setRsus(null); diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRcController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRcController.java index 9e687fb40..a73d87f2c 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRcController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRcController.java @@ -72,6 +72,9 @@ public ResponseEntity createUpdateRoadConditionsTim(@RequestBody TimRcLi resultTim = validateInputRc(wydotTim); + // workaround for geometry start/end point population + WydotTimRc wydotTimRc = wydotTim.copy(); + if (resultTim.getResultMessages().size() > 0) { resultList.add(resultTim); errList.add(resultTim); @@ -79,7 +82,7 @@ public ResponseEntity createUpdateRoadConditionsTim(@RequestBody TimRcLi } // add TIM to list for processing later - timsToSend.add(wydotTim); + timsToSend.add(wydotTimRc); resultTim.getResultMessages().add("success"); resultList.add(resultTim); @@ -148,6 +151,9 @@ public ResponseEntity submitAllClearRoadConditionsTim(@RequestBody TimRc } String responseMessage = gson.toJson(resultList); + if (errList.size() > 0) { + utility.logWithDate("Failed to send TIMs: " + gson.toJson(errList), this.getClass()); + } return ResponseEntity.status(HttpStatus.OK).body(responseMessage); } diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java index 9754c98c3..91e6b111e 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java @@ -93,10 +93,12 @@ public ResponseEntity createRoadContructionTim(@RequestBody TimRwList ti makeDecreasingTims(wydotTim); } // else make one direction TIMs - else if (wydotTim.getDirection().equalsIgnoreCase("i")) + else if (wydotTim.getDirection().equalsIgnoreCase("i")) { makeIncreasingTims(wydotTim); - else + } + else { makeDecreasingTims(wydotTim); + } // compile result messages for user resultTim.getResultMessages().add("success"); @@ -161,6 +163,27 @@ private double getDBearingForRoute(String route) { return 0; } + private double getTimBearing(WydotTimRw wydotTim) { + if (wydotTim.getBearing() != null) { + switch (wydotTim.getBearing()) { + case 0: + return 180; + case 90: + return 270; + case 180: + return 0; + case 270: + return 90; + default: + return 0; + } + } else if (wydotTim.getDirection().equalsIgnoreCase("i")) { + return getIBearingForRoute(wydotTim.getRoute()); + } else { + return getDBearingForRoute(wydotTim.getRoute()); + } + } + public void makeIncreasingBufferTim(WydotTimRw wydotTim) { double bufferBefore = 0.000; @@ -169,7 +192,7 @@ public void makeIncreasingBufferTim(WydotTimRw wydotTim) { GlobalCoordinates startCoordinates = new GlobalCoordinates(wydotTim.getStartPoint().getLatitude().doubleValue(), wydotTim.getStartPoint().getLongitude().doubleValue()); GlobalCoordinates nextCoordinates = null; - double bearing = getIBearingForRoute(wydotTim.getRoute()); + double bearing = getTimBearing(wydotTim); GeodeticCalculator calculator = new GeodeticCalculator(); for (int i = 0; i < wydotTim.getBuffers().size(); i++) { @@ -213,7 +236,7 @@ public void makeDecreasingBufferTim(WydotTimRw wydotTim) { GlobalCoordinates startCoordinates = new GlobalCoordinates(wydotTim.getEndPoint().getLatitude().doubleValue(), wydotTim.getEndPoint().getLongitude().doubleValue()); GlobalCoordinates nextCoordinates = null; - double bearing = getDBearingForRoute(wydotTim.getRoute()); + double bearing = getTimBearing(wydotTim); GeodeticCalculator calculator = new GeodeticCalculator(); for (int i = 0; i < wydotTim.getBuffers().size(); i++) { @@ -313,4 +336,4 @@ public Collection getRoadConstructionTim() { return activeTims; } -} \ No newline at end of file +} From 70c638c504c5b67f24430fcc7ed0094d13c64690 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 23 Jan 2025 15:33:26 -0700 Subject: [PATCH 043/168] Add milepost cache for incoming TIMs with geometry --- .../controller/MilepostController.java | 82 +++++++++++++ .../library/helpers/TimGenerationHelper.java | 110 ++++++++++++++++-- .../library/model/MilepostCacheBody.java | 19 +++ .../library/service/MilepostService.java | 44 ++++++- .../library/service/WydotTimService.java | 46 +++++++- 5 files changed, 289 insertions(+), 12 deletions(-) create mode 100644 cv-data-service-library/src/main/java/com/trihydro/library/model/MilepostCacheBody.java diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/MilepostController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/MilepostController.java index 789f05b3f..317557c40 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/MilepostController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/MilepostController.java @@ -7,6 +7,7 @@ import java.sql.Statement; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.List; import java.util.stream.Collectors; @@ -18,6 +19,7 @@ import com.trihydro.library.model.Milepost; import com.trihydro.library.model.MilepostBuffer; import com.trihydro.library.model.WydotTim; +import com.trihydro.library.model.MilepostCacheBody; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; @@ -37,6 +39,7 @@ public class MilepostController extends BaseController { private MilepostService milepostService; + private final HashMap> milepostCache = new HashMap<>(); @Autowired public void InjectDependencies(MilepostService _milepostService) { @@ -308,6 +311,85 @@ public ResponseEntity> return ResponseEntity.ok(data); } + @RequestMapping(method = RequestMethod.POST, value="/set-milepost-cache") + public ResponseEntity setMilepostCache(@RequestBody MilepostCacheBody milepostCacheBody) { + + utility.logWithDate("Setting milepost cache for timID: " + milepostCacheBody.getTimID()); + + if (milepostCacheBody.getMileposts().size() == 0 || milepostCacheBody.getTimID() == null) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Invalid Request: please provide a valid milepost list and timID"); + } + if (milepostCache.containsKey(milepostCacheBody.getTimID())) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Milepost cache already exists for timID: " + milepostCacheBody.getTimID()); + } + milepostCache.put(milepostCacheBody.getTimID(), milepostCacheBody.getMileposts()); + return ResponseEntity.ok("Milepost cache set successfully for timID: " + milepostCacheBody.getTimID()); + } + + @RequestMapping(method = RequestMethod.GET, value="/get-milepost-cache/{timID}") + public ResponseEntity> getMilepostCacheByTimID(@PathVariable String timID) { + List mileposts = new ArrayList<>(); + + if (milepostCache.containsKey(timID)) { + mileposts = milepostCache.get(timID); + utility.logWithDate("Found " + mileposts.size() + " mileposts in cache for timID: " + timID); + return ResponseEntity.ok(milepostCache.get(timID)); + } + + return ResponseEntity.ok(mileposts); + } + + @RequestMapping(method = RequestMethod.DELETE, value="/delete-milepost-cache/{timID}") + public ResponseEntity deleteMilepostCache(@PathVariable String timID) { + utility.logWithDate("Deleting milepost cache for timID: " + timID); + + if (milepostCache.containsKey(timID)) { + milepostCache.remove(timID); + return ResponseEntity.ok("Milepost cache deleted successfully for timID: " + timID); + } + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Milepost cache not found for timID: " + timID); + } + + @RequestMapping(method = RequestMethod.GET, value="/clear-milepost-cache") + public ResponseEntity clearMilepostCache() { + utility.logWithDate("Clearing milepost cache"); + List timIDs = new ArrayList<>(milepostCache.keySet()); + Connection connection = null; + Statement statement = null; + ResultSet rs = null; + + try { + connection = dbInteractions.getConnectionPool(); + statement = connection.createStatement(); + rs = statement.executeQuery("SELECT client_id FROM active_tim WHERE marked_for_deletion = False"); + + // convert result to milepost objects + while (rs.next()) { + String tim_id = rs.getString("CLIENT_ID"); + if (!timIDs.contains(tim_id)) { + milepostCache.remove(tim_id); + } + } + } catch (SQLException e) { + e.printStackTrace(); + } finally { + try { + // close prepared statement + if (statement != null) + statement.close(); + // return connection back to pool + if (connection != null) + connection.close(); + // close result set + if (rs != null) + rs.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + return ResponseEntity.ok("Milepost cache cleared successfully"); + } + /** * Rewrite of getMilepostsByStartEndPoint used in testing to cut time on geojson * creation to test continuity diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/TimGenerationHelper.java b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/TimGenerationHelper.java index d763367f9..856257966 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/TimGenerationHelper.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/TimGenerationHelper.java @@ -314,7 +314,24 @@ private List getAllMps(WydotTim wydotTim) { utility.logWithDate("Fetching mileposts for regular TIM with client id: " + wydotTim.getClientId()); if (wydotTim.getEndPoint() != null) { - allMps = milepostService.getMilepostsByStartEndPointDirection(wydotTim); + if (wydotTim.getGeometry() != null && wydotTim.getGeometry().size() > 1) { + for (Coordinate coordinate : wydotTim.getGeometry()) { + Milepost milepost = new Milepost(); + milepost.setLatitude(coordinate.getLatitude()); + milepost.setLongitude(coordinate.getLongitude()); + milepost.setDirection(wydotTim.getDirection()); + milepost.setCommonName(wydotTim.getRoute()); + milepost.setMilepost(0.0); + allMps.add(milepost); + } + milepostService.setMilepostCache(allMps, wydotTim.getClientId()); + } else { + // Check to see if milepost array exists in cache + allMps = milepostService.getMilepostCache(wydotTim.getClientId()); + if (allMps.isEmpty()) { + allMps = milepostService.getMilepostsByStartEndPointDirection(wydotTim); + } + } utility.logWithDate(String.format("Found %d mileposts between %s and %s", allMps.size(), gson.toJson(wydotTim.getStartPoint()), gson.toJson(wydotTim.getEndPoint()))); } else { @@ -562,6 +579,77 @@ public List expireTimAndResubmitToOde(List activeTim return exceptions; } + /** + * Expires existing TIMs that utilize geometry instead of start/end points and resubmits them to the ODE + * + * @param activeTimId TIM to resubmit + * @param allMps List of all mileposts for the active TIM + * @return Errors that occurred while processing the request + */ + public List expireTimAndResubmitToOdeGeometry(Long activeTimID, List allMps) { + List exceptions = new ArrayList<>(); + if (activeTimID == null) { + utility.logWithDate("No active TIM found to resubmit to ODE. Returning...", TimGenerationHelper.class); + return exceptions; + } + + try { + var tum = activeTimService.getUpdateModelFromActiveTimId(activeTimID); + + if (tum == null) { + exceptions.add(new ResubmitTimException(activeTimID, "Failed to get Update Model from active tim")); + } + if (!isValidTim(tum)) { + exceptions.add(new ResubmitTimException(activeTimID, + "Failed to generate valid Update Model from active tim")); + } + + if (tum.getLaneWidth() == null) { + tum.setLaneWidth(config.getDefaultLaneWidth()); + } else { + // Database has lane width as cm, but ODE takes m + tum.setLaneWidth(tum.getLaneWidth().divide(BigDecimal.valueOf(100))); + } + + List reduced_mps; + if (allMps.size() < 2) { + String exMsg = String.format( + "Unable to resubmit TIM, less than 2 mileposts found for Active_Tim %d", + tum.getActiveTimId()); + utility.logWithDate(exMsg); + exceptions.add(new ResubmitTimException(activeTimID, exMsg)); + } + Milepost firstPoint = allMps.get(0); + Milepost secondPoint = allMps.get(1); + + // reduce the mileposts by removing straight away posts + var anchorMp = getAnchorPoint(firstPoint, secondPoint); + reduced_mps = milepostReduction.applyMilepostReductionAlgorithm(allMps, config.getPathDistanceLimit()); + + OdeTravelerInformationMessage tim = getTim(tum, reduced_mps, allMps, anchorMp, false, true); + if (tim == null) { + String exMsg = String.format("Failed to instantiate TIM for active_tim_id %d", + tum.getActiveTimId()); + utility.logWithDate(exMsg); + exceptions.add(new ResubmitTimException(activeTimID, exMsg)); + } + WydotTravelerInputData timToSend = new WydotTravelerInputData(); + timToSend.setTim(tim); + var extraEx = sendTim(timToSend, tum, activeTimID, reduced_mps); + activeTimService.markForDeletion(activeTimID); + if (!extraEx.isEmpty()) { + exceptions.addAll(extraEx); + } + } catch (Exception ex) { + exceptions.add(new ResubmitTimException(activeTimID, ex.getMessage())); + } + if (!exceptions.isEmpty()) { + utility.logWithDate("Errors occurred while resubmitting TIMs: " + gson.toJson(exceptions), + TimGenerationHelper.class); + } + return exceptions; + } + public boolean isValidTim(TimUpdateModel tum) { // start point @@ -684,9 +772,8 @@ private List sendTim(WydotTravelerInputData timToSend, Tim List reduced_mps) { List exceptions = new ArrayList<>(); // try to send to RSU if not a sat TIM and along route with RSUs - if (StringUtils.isBlank(tum.getSatRecordId()) - && Arrays.asList(config.getRsuRoutes()).contains(tum.getRoute())) { - var exMsg = updateAndSendRSU(timToSend, tum); + if (StringUtils.isBlank(tum.getSatRecordId())) { + var exMsg = updateAndSendRSU(timToSend, tum, reduced_mps); if (StringUtils.isNotBlank(exMsg)) { exceptions.add(new ResubmitTimException(activeTimId, exMsg)); } @@ -901,15 +988,24 @@ private String getBaseRegionName(TimUpdateModel aTim, String middle) { return regionName; } - private String updateAndSendRSU(WydotTravelerInputData timToSend, TimUpdateModel aTim) { + private String updateAndSendRSU(WydotTravelerInputData timToSend, TimUpdateModel aTim, List mileposts) { String exMsg = ""; List wydotRsus = rsuService.getFullRsusTimIsOn(aTim.getTimId()); List dbRsus = new ArrayList(); if (wydotRsus == null || wydotRsus.size() <= 0) { utility.logWithDate("RSUs not found to update db for active_tim_id " + aTim.getActiveTimId()); - dbRsus = rsuService.getRsusByLatLong(aTim.getDirection(), aTim.getStartPoint(), aTim.getEndPoint(), - aTim.getRoute()); + if (mileposts != null && mileposts.size() > 0) { + // use milepost geometry to find RSUs + List coords = new ArrayList(); + for (Milepost mp : mileposts) { + coords.add(new Coordinate(mp.getLatitude(), mp.getLongitude())); + } + dbRsus = rsuService.getRsusByGeometry(coords); + } else { + dbRsus = rsuService.getRsusByLatLong(aTim.getDirection(), aTim.getStartPoint(), aTim.getEndPoint(), + aTim.getRoute()); + } // if no RSUs found if (dbRsus.size() == 0) { diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/model/MilepostCacheBody.java b/cv-data-service-library/src/main/java/com/trihydro/library/model/MilepostCacheBody.java new file mode 100644 index 000000000..eabc3e1e0 --- /dev/null +++ b/cv-data-service-library/src/main/java/com/trihydro/library/model/MilepostCacheBody.java @@ -0,0 +1,19 @@ +package com.trihydro.library.model; + +import java.util.List; + +public class MilepostCacheBody { + private List mileposts; + private String timID; + + public MilepostCacheBody(List mileposts, String timID) { + this.mileposts = mileposts; + this.timID = timID; + } + public List getMileposts() { + return mileposts; + } + public String getTimID() { + return timID; + } +} \ No newline at end of file diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/service/MilepostService.java b/cv-data-service-library/src/main/java/com/trihydro/library/service/MilepostService.java index 15de8a472..36d14b519 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/service/MilepostService.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/service/MilepostService.java @@ -5,6 +5,7 @@ import com.trihydro.library.model.Milepost; import com.trihydro.library.model.MilepostBuffer; import com.trihydro.library.model.WydotTim; +import com.trihydro.library.model.MilepostCacheBody; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpEntity; @@ -40,4 +41,45 @@ public List getMilepostsByPointWithBuffer(MilepostBuffer milepostBuffe entity, responseType); return response.getBody(); } -} + + public String setMilepostCache(List mileposts, String timID) { + String url = String.format("%s/set-milepost-cache", config.getCvRestService()); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + MilepostCacheBody body = new MilepostCacheBody(mileposts, timID); + HttpEntity entity = new HttpEntity(body, headers); + ResponseEntity response = restTemplateProvider.GetRestTemplate().exchange(url, HttpMethod.POST, entity, + String.class); + return response.getBody(); + } + + public List getMilepostCache(String timID) { + String url = String.format("%s/get-milepost-cache/%s", config.getCvRestService(), timID); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + HttpEntity entity = new HttpEntity(null, headers); + ParameterizedTypeReference> responseType = new ParameterizedTypeReference>() {}; + ResponseEntity> response = restTemplateProvider.GetRestTemplate().exchange(url, HttpMethod.GET, + entity, responseType); + return response.getBody(); + } + + public String deleteMilepostCache(String timID) { + String url = String.format("%s/delete-milepost-cache/%s", config.getCvRestService(), timID); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + HttpEntity entity = new HttpEntity(null, headers); + ResponseEntity response = restTemplateProvider.GetRestTemplate().exchange(url, HttpMethod.DELETE, entity, + String.class); + return response.getBody(); + } + + public void clearMilepostCache() { + String url = String.format("%s/clear-milepost-cache/", config.getCvRestService()); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + HttpEntity entity = new HttpEntity(null, headers); + ParameterizedTypeReference responseType = new ParameterizedTypeReference() {}; + restTemplateProvider.GetRestTemplate().exchange(url, HttpMethod.GET, entity, responseType); + } +} \ No newline at end of file diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java b/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java index f1ab3b7ca..e9a21874b 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java @@ -159,9 +159,25 @@ public WydotTravelerInputData createTim(WydotTim wydotTim, String timTypeStr, St } public List getAllMilepostsForTim(WydotTim wydotTim) { - List milepostsAll = new ArrayList<>(); + List milepostsAll; - if (wydotTim.getEndPoint() != null && wydotTim.getEndPoint().getLatitude() != null + // get mileposts from cache if they exist + milepostsAll = milepostService.getMilepostCache(wydotTim.getClientId()); + if (milepostsAll != null && milepostsAll.size() > 0) { + return milepostsAll; + } + + if (wydotTim.getGeometry() != null && wydotTim.getGeometry().size() > 1) { + for (Coordinate coordinate : wydotTim.getGeometry()) { + Milepost milepost = new Milepost(); + milepost.setLatitude(coordinate.getLatitude()); + milepost.setLongitude(coordinate.getLongitude()); + milepost.setDirection(wydotTim.getDirection()); + milepost.setCommonName(wydotTim.getRoute()); + milepost.setMilepost(0.0); + milepostsAll.add(milepost); + } + } else if (wydotTim.getEndPoint() != null && wydotTim.getEndPoint().getLatitude() != null && wydotTim.getEndPoint().getLongitude() != null) { milepostsAll = milepostService.getMilepostsByStartEndPointDirection(wydotTim); } else { @@ -174,6 +190,11 @@ public List getAllMilepostsForTim(WydotTim wydotTim) { milepostsAll = milepostService.getMilepostsByPointWithBuffer(mpb); } + // cache mileposts + if (milepostsAll != null && !milepostsAll.isEmpty()) { + milepostService.setMilepostCache(milepostsAll, wydotTim.getClientId()); + } + return milepostsAll; } @@ -242,8 +263,17 @@ public void sendTimToRsus(WydotTim wydotTim, WydotTravelerInputData timToSend, S TimType timType, Integer pk, String endDateTime, Coordinate endPoint) { // FIND ALL RSUS TO SEND TO // TODO: should this query a graph db instead to follow with milepost? - List rsus = rsuService.getRsusByLatLong(wydotTim.getDirection(), wydotTim.getStartPoint(), endPoint, + + // if geometry exists, use it to find RSUs + List rsus = new ArrayList<>(); + + if (wydotTim.isGeometryValid() && wydotTim.getGeometry().size() > 1) { + rsus = rsuService.getRsusByGeometry(wydotTim.getGeometry()); + utility.logWithDate("Found " + rsus.size() + " RSUs by geometry"); + } else { + rsus = rsuService.getRsusByLatLong(wydotTim.getDirection(), wydotTim.getStartPoint(), endPoint, wydotTim.getRoute()); + } // if no RSUs found if (rsus.size() == 0) { @@ -259,7 +289,14 @@ public void sendTimToRsus(WydotTim wydotTim, WydotTravelerInputData timToSend, S odeRsu.setRsuIndex(rsu.getRsuIndex()); odeRsu.setRsuTarget(rsu.getRsuTarget()); - // rsuUsername, rsuPassword will take ODE defaults. + + if (rsu.getRsuUsername() != null) { + odeRsu.setRsuUsername(rsu.getRsuUsername()); + } + if (rsu.getRsuPassword() != null) { + odeRsu.setRsuPassword(rsu.getRsuPassword()); + } + odeRsu.setRsuRetries(rsu.getRsuRetries()); odeRsu.setRsuTimeout(rsu.getRsuTimeout()); @@ -393,6 +430,7 @@ public TimDeleteSummary deleteTimsFromRsusAndSdx(List activeTims) { } // delete active tim if (activeTimService.deleteActiveTim(activeTim.getActiveTimId())) { + milepostService.deleteMilepostCache(activeTim.getClientId()); returnValue.addSuccessfulRsuDeletions(activeTim.getActiveTimId()); } else { returnValue.addFailedActiveTimDeletions(activeTim.getActiveTimId()); From 429576bb362302eb3590fdf41ccbdf25ba73755d Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 23 Jan 2025 15:34:56 -0700 Subject: [PATCH 044/168] Update road work ITIS codes to set properly for TIMs --- .../odewrapper/helpers/SetItisCodes.java | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java index 54b0dca72..4186b6e17 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java @@ -284,7 +284,29 @@ public List getIncidentActions() { public List setItisCodesRw(WydotTim wydotTim) { - List items = new ArrayList(); + List items = new ArrayList<>(); + + if (wydotTim.getItisCodes() == null) { + return items; + } + + ItisCode code; + + for (String item : wydotTim.getItisCodes()) { + + Integer itisCode = Integer.valueOf(item); + + var alphaItis = getCustomAlphabetic(itisCode); + if (alphaItis != null) { + items.add(alphaItis); + continue; + } + + code = getItisCodes().stream().filter(x -> x.getItisCode().equals(itisCode)).findFirst().orElse(null); + + if (code != null) + items.add(code.getItisCode().toString()); + } items.add("1025"); From a28a7f658a0e2cb9f0b7563c7a5667dd023f8f26 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 23 Jan 2025 15:36:07 -0700 Subject: [PATCH 045/168] Add milepost cache clear call to CleanupActiveTims run method --- .../tasks/actions/CleanupActiveTims.java | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/cv-data-tasks/src/main/java/com/trihydro/tasks/actions/CleanupActiveTims.java b/cv-data-tasks/src/main/java/com/trihydro/tasks/actions/CleanupActiveTims.java index c64d53ee5..8cb056f03 100644 --- a/cv-data-tasks/src/main/java/com/trihydro/tasks/actions/CleanupActiveTims.java +++ b/cv-data-tasks/src/main/java/com/trihydro/tasks/actions/CleanupActiveTims.java @@ -17,51 +17,57 @@ import org.springframework.http.MediaType; import org.springframework.stereotype.Component; +import com.trihydro.library.service.MilepostService; + @Component public class CleanupActiveTims implements Runnable { private DataTasksConfiguration configuration; private Utility utility; private ActiveTimService activeTimService; private RestTemplateProvider restTemplateProvider; + private MilepostService milepostService; @Autowired public void InjectDependencies(DataTasksConfiguration _configuration, Utility _utility, - ActiveTimService _activeTimService, RestTemplateProvider _restTemplateProvider) { + ActiveTimService _activeTimService, RestTemplateProvider _restTemplateProvider, MilepostService _milepostService) { configuration = _configuration; utility = _utility; activeTimService = _activeTimService; restTemplateProvider = _restTemplateProvider; + milepostService = _milepostService; } + @Override public void run() { utility.logWithDate("Running...", this.getClass()); try { - List activeTims = new ArrayList(); - List tmp = null; + List activeTims = new ArrayList<>(); + List tmp; // select active tims missing ITIS codes tmp = activeTimService.getActiveTimsMissingItisCodes(); - if (tmp.size() > 0) { + if (tmp.isEmpty()) { + } else { utility.logWithDate("Found " + tmp.size() + " Active TIMs missing ITIS Codes", this.getClass()); activeTims.addAll(tmp); } // add active tims that weren't sent to the SDX or any RSUs tmp = activeTimService.getActiveTimsNotSent(); - if (tmp.size() > 0) { + if (!tmp.isEmpty()) { utility.logWithDate("Found " + tmp.size() + " Active TIMs that weren't distributed", this.getClass()); activeTims.addAll(tmp); } - if (activeTims.size() == 0) { + if (!activeTims.isEmpty()) { utility.logWithDate("Found 0 Active TIMs", this.getClass()); } // delete from rsus and the SDX HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); - HttpEntity entity = null; + HttpEntity entity; String activeTimJson; Gson gson = new Gson(); @@ -69,7 +75,7 @@ public void run() { for (ActiveTim activeTim : activeTims) { activeTimJson = gson.toJson(activeTim); - entity = new HttpEntity(activeTimJson, headers); + entity = new HttpEntity<>(activeTimJson, headers); utility.logWithDate( "CleanupActiveTims - Deleting ActiveTim: { activeTimId: " + activeTim.getActiveTimId() + " }", @@ -77,6 +83,10 @@ public void run() { restTemplateProvider.GetRestTemplate().exchange(configuration.getWrapperUrl() + "/delete-tim/", HttpMethod.DELETE, entity, String.class); } + + // clear the milepostService cache to ensure that the milepost data is up to date + utility.logWithDate("Deleting milepost cache", this.getClass()); + milepostService.clearMilepostCache(); } catch (Exception e) { e.printStackTrace(); // don't rethrow error, or the task won't be reran until the service is From c7c33d2cf64176be00bf7ae092e99ea8155320d3 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Fri, 24 Jan 2025 09:45:41 -0700 Subject: [PATCH 046/168] Add snmp username/password query instead of using config values --- .../rsudatacontroller/Application.java | 10 +- .../config/BasicConfiguration.java | 120 ++++++++++++++---- .../rsudatacontroller/service/RsuService.java | 92 +++++++++++++- .../main/resources/application-dev.properties | 9 +- 4 files changed, 201 insertions(+), 30 deletions(-) diff --git a/rsu-data-controller/src/main/java/com/trihydro/rsudatacontroller/Application.java b/rsu-data-controller/src/main/java/com/trihydro/rsudatacontroller/Application.java index 1f09d1159..c51193ac7 100644 --- a/rsu-data-controller/src/main/java/com/trihydro/rsudatacontroller/Application.java +++ b/rsu-data-controller/src/main/java/com/trihydro/rsudatacontroller/Application.java @@ -4,10 +4,18 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Import; +import com.trihydro.library.helpers.DbInteractions; +import com.trihydro.library.helpers.EmailHelper; +import com.trihydro.library.helpers.JavaMailSenderImplProvider; +import com.trihydro.library.helpers.SQLNullHandler; +import com.trihydro.rsudatacontroller.config.BasicConfiguration; + @SpringBootApplication -@Import({ Utility.class }) +@Import({ Utility.class, DbInteractions.class, SQLNullHandler.class, EmailHelper.class, JavaMailSenderImplProvider.class, }) +@EnableConfigurationProperties(BasicConfiguration.class) public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); diff --git a/rsu-data-controller/src/main/java/com/trihydro/rsudatacontroller/config/BasicConfiguration.java b/rsu-data-controller/src/main/java/com/trihydro/rsudatacontroller/config/BasicConfiguration.java index 1e4395f91..c4f78749f 100644 --- a/rsu-data-controller/src/main/java/com/trihydro/rsudatacontroller/config/BasicConfiguration.java +++ b/rsu-data-controller/src/main/java/com/trihydro/rsudatacontroller/config/BasicConfiguration.java @@ -1,18 +1,30 @@ package com.trihydro.rsudatacontroller.config; import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.stereotype.Component; -@Component -@ConfigurationProperties("config") -public class BasicConfiguration { +import com.trihydro.library.model.DbInteractionsProps; +import com.trihydro.library.model.EmailProps; + +@ConfigurationProperties +public class BasicConfiguration implements DbInteractionsProps, EmailProps { private int snmpRetries; private int snmpTimeoutSeconds; - private String snmpUserName; - private String snmpAuthPassphrase; private String snmpAuthProtocol; private String snmpSecurityLevel; + private String dbUrl; + private String dbUsername; + private String dbPassword; + + private int maximumPoolSize; + private int connectionTimeout; + + private String[] alertAddresses; + private String fromEmail; + private String environmentName; + private String mailHost; + private int mailPort; + public int getSnmpRetries() { return snmpRetries; } @@ -29,22 +41,6 @@ public void setSnmpTimeoutSeconds(int snmpTimeoutSeconds) { this.snmpTimeoutSeconds = snmpTimeoutSeconds; } - public String getSnmpUserName() { - return snmpUserName; - } - - public void setSnmpUserName(String snmpUserName) { - this.snmpUserName = snmpUserName; - } - - public String getSnmpAuthPassphrase() { - return snmpAuthPassphrase; - } - - public void setSnmpAuthPassphrase(String snmpAuthPassphrase) { - this.snmpAuthPassphrase = snmpAuthPassphrase; - } - public String getSnmpAuthProtocol() { return snmpAuthProtocol; } @@ -60,4 +56,84 @@ public String getSnmpSecurityLevel() { public void setSnmpSecurityLevel(String snmpSecurityLevel) { this.snmpSecurityLevel = snmpSecurityLevel; } + + public String getDbUrl() { + return dbUrl; + } + + public void setDbUrl(String dbUrl) { + this.dbUrl = dbUrl; + } + + public String getDbUsername() { + return dbUsername; + } + + public void setDbUsername(String dbUsername) { + this.dbUsername = dbUsername; + } + + public String getDbPassword() { + return dbPassword; + } + + public void setDbPassword(String dbPassword) { + this.dbPassword = dbPassword; + } + + public int getMaximumPoolSize() { + return maximumPoolSize; + } + + public void setMaximumPoolSize(int maximumPoolSize) { + this.maximumPoolSize = maximumPoolSize; + } + + public int getConnectionTimeout() { + return connectionTimeout; + } + + public void setConnectionTimeout(int connectionTimeout) { + this.connectionTimeout = connectionTimeout; + } + + public String[] getAlertAddresses() { + return alertAddresses; + } + + public void setAlertAddresses(String[] alertAddresses) { + this.alertAddresses = alertAddresses; + } + + public String getFromEmail() { + return fromEmail; + } + + public void setFromEmail(String fromEmail) { + this.fromEmail = fromEmail; + } + + public String getEnvironmentName() { + return environmentName; + } + + public void setEnvironmentName(String environmentName) { + this.environmentName = environmentName; + } + + public String getMailHost() { + return mailHost; + } + + public void setMailHost(String mailHost) { + this.mailHost = mailHost; + } + + public int getMailPort() { + return mailPort; + } + + public void setMailPort(int mailPort) { + this.mailPort = mailPort; + } } \ No newline at end of file diff --git a/rsu-data-controller/src/main/java/com/trihydro/rsudatacontroller/service/RsuService.java b/rsu-data-controller/src/main/java/com/trihydro/rsudatacontroller/service/RsuService.java index 1866b4fbf..d4c7864fd 100644 --- a/rsu-data-controller/src/main/java/com/trihydro/rsudatacontroller/service/RsuService.java +++ b/rsu-data-controller/src/main/java/com/trihydro/rsudatacontroller/service/RsuService.java @@ -3,6 +3,10 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -10,6 +14,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import com.trihydro.library.helpers.DbInteractions; import com.trihydro.library.helpers.Utility; import com.trihydro.rsudatacontroller.config.BasicConfiguration; import com.trihydro.rsudatacontroller.model.RsuTim; @@ -18,20 +23,26 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import us.dot.its.jpo.ode.plugin.RoadSideUnit.RSU; +import us.dot.its.jpo.ode.plugin.SnmpProtocol; + @Component public class RsuService { - private static final String oid_rsuSRMDeliveryStart = "1.0.15628.4.1.4.1.7"; + private static final String OID_FOUR_DOT_ONE_SRM_DELIVERY_START = "1.0.15628.4.1.4.1.7"; + private static final String OID_NTCIP_1218_DELIVERY_START = "1.3.6.1.4.1.1206.4.2.18.3.2.1.5"; private static final DateTimeFormatter rsuDateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); private ProcessFactory processFactory; private BasicConfiguration config; private Utility utility; + protected DbInteractions dbInteractions; @Autowired - public void InjectDependencies(ProcessFactory processFactory, BasicConfiguration config, Utility utility) { + public void InjectDependencies(ProcessFactory processFactory, BasicConfiguration config, DbInteractions _dbInteractions, Utility utility) { this.processFactory = processFactory; this.config = config; this.utility = utility; + this.dbInteractions = _dbInteractions; } /** @@ -42,10 +53,21 @@ public void InjectDependencies(ProcessFactory processFactory, BasicConfiguration * @throws Exception if unable to invoke command to perform SNMP communication */ public List getAllDeliveryStartTimes(String rsuIpv4Address) throws Exception { - Process p = processFactory.buildAndStartProcess("snmpwalk", "-v", "3", "-r", + Process p; + + RSU rsu = getRSU(rsuIpv4Address); + + if (rsu.getSnmpProtocol() == SnmpProtocol.FOURDOT1) { + p = processFactory.buildAndStartProcess("snmpwalk", "-v", "3", "-r", Integer.toString(config.getSnmpRetries()), "-t", Integer.toString(config.getSnmpTimeoutSeconds()), "-u", - config.getSnmpUserName(), "-l", config.getSnmpSecurityLevel(), "-a", config.getSnmpAuthProtocol(), "-A", - config.getSnmpAuthPassphrase(), rsuIpv4Address, oid_rsuSRMDeliveryStart); + rsu.getRsuUsername(), "-l", config.getSnmpSecurityLevel(), "-a", config.getSnmpAuthProtocol(), "-A", + rsu.getRsuPassword(), rsuIpv4Address, OID_FOUR_DOT_ONE_SRM_DELIVERY_START); + } else { + p = processFactory.buildAndStartProcess("snmpwalk", "-v", "3", "-r", + Integer.toString(config.getSnmpRetries()), "-t", Integer.toString(config.getSnmpTimeoutSeconds()), "-u", + rsu.getRsuUsername(), "-l", config.getSnmpSecurityLevel(), "-a", config.getSnmpAuthProtocol(), "-A", + rsu.getRsuPassword(), rsuIpv4Address, OID_NTCIP_1218_DELIVERY_START); + } String snmpWalkOutput = getProcessOutput(p); @@ -67,7 +89,7 @@ public List getAllDeliveryStartTimes(String rsuIpv4Address) throws Excep if (im.find() && hm.find()) { RsuTim tim = new RsuTim(); - tim.setIndex(Integer.parseInt(im.group(1))); + tim.setIndex(Integer.valueOf(im.group(1))); tim.setDeliveryStartTime(hexStringToDateTime(hm.group(1))); tims.add(tim); @@ -106,4 +128,62 @@ private String hexStringToDateTime(String hexString) { LocalDateTime date = LocalDateTime.of(year, month, day, hour, minute, 0); return date.format(rsuDateTimeFormatter); } + + private RSU getRSU(String rsuIpv4Address) throws Exception { + // Need to grab firmware type, username, password. + Connection connection = null; + Statement statement = null; + ResultSet rs = null; + RSU rsu = null; + + + try { + connection = dbInteractions.getConnectionPool(); + + statement = connection.createStatement(); + + // The inner subqueries leave us with a list of tim_ids that aren't associated + // with any valid itis codes. Select the active_tims with + // those tim_ids + String selectStatement = "select rc.username, rc.password, sp.nickname FROM rsus " + + "JOIN rsu_credentials AS rc " + // + "ON rsus.snmp_credential_id = rc.credential_id " + // + "JOIN snmp_protocols AS sp " + // + "ON rsus.snmp_protocol_id = sp.snmp_protocol_id " + // + "WHERE rsus.ipv4_address = '" + rsuIpv4Address + "'"; + + rs = statement.executeQuery(selectStatement); + + // parse resultSet + while (rs.next()) { + String rsuUsername = rs.getString("username"); + String rsuPassword = rs.getString("password"); + SnmpProtocol snmpProtocol = rs.getString("nickname").equals("NTCIP 1218") ? SnmpProtocol.NTCIP1218 : SnmpProtocol.FOURDOT1; + + rsu = new RSU(rsuIpv4Address, rsuUsername, rsuPassword, config.getSnmpRetries(), config.getSnmpTimeoutSeconds(), snmpProtocol); + } + + + + } catch (SQLException e) { + e.printStackTrace(); + return null; + } finally { + try { + // close prepared statement + if (statement != null) + statement.close(); + // return connection back to pool + if (connection != null) + connection.close(); + // close result set + if (rs != null) + rs.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + return rsu; + } } \ No newline at end of file diff --git a/rsu-data-controller/src/main/resources/application-dev.properties b/rsu-data-controller/src/main/resources/application-dev.properties index 68ed2d799..ca0c72b59 100644 --- a/rsu-data-controller/src/main/resources/application-dev.properties +++ b/rsu-data-controller/src/main/resources/application-dev.properties @@ -4,4 +4,11 @@ config.snmpTimeoutSeconds=5 config.snmpUserName=username config.snmpAuthPassphrase=password config.snmpAuthProtocol=SHA -config.snmpSecurityLevel=authNoPriv \ No newline at end of file +config.snmpSecurityLevel=authNoPriv + +dbUrl=jdbc:postgresql://localhost:5432/dbname?user=username +dbUsername=username +dbPassword=password + +maximumPoolSize=13 +connectionTimeout=300000 \ No newline at end of file From 718455585223f001904b56bc40c3d34a9a0264b1 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Fri, 24 Jan 2025 09:46:23 -0700 Subject: [PATCH 047/168] Unit testing updates --- .../controller/RsuControllerTest.java | 80 ++++++----------- .../helpers/TimGenerationHelperTest.java | 88 ++++++++----------- .../app/services/ActiveTimServiceTest.java | 3 +- .../app/services/RsuServiceTest.java | 15 ++-- .../odewrapper/CopyConstructorTest.java | 3 + 5 files changed, 73 insertions(+), 116 deletions(-) diff --git a/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/RsuControllerTest.java b/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/RsuControllerTest.java index 0eaeaa6a6..d2dcacb32 100644 --- a/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/RsuControllerTest.java +++ b/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/RsuControllerTest.java @@ -1,27 +1,26 @@ package com.trihydro.cvdatacontroller.controller; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - import java.sql.SQLException; import java.util.ArrayList; import java.util.List; -import com.trihydro.library.model.WydotRsu; -import com.trihydro.library.model.WydotRsuTim; - import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import com.trihydro.library.model.WydotRsu; +import com.trihydro.library.model.WydotRsuTim; + public class RsuControllerTest extends TestBase { @Test public void SelectAllRsus_SUCCESS() throws SQLException { // Arrange - String selectStatement = "select * from rsu inner join rsu_view on rsu.deviceid = rsu_view.deviceid order by milepost asc"; + String selectStatement = "select rsu_id, ST_X(ST_AsText(geography)) as longitude, ST_Y(ST_AsText(geography)) as latitude, ipv4_address, primary_route, milepost from rsus order by milepost asc"; // Act ResponseEntity> data = uut.SelectAllRsus(); @@ -33,7 +32,7 @@ public void SelectAllRsus_SUCCESS() throws SQLException { verify(mockRs).getString("IPV4_ADDRESS"); verify(mockRs).getBigDecimal("LATITUDE"); verify(mockRs).getBigDecimal("LONGITUDE"); - verify(mockRs).getString("ROUTE"); + verify(mockRs).getString("PRIMARY_ROUTE"); verify(mockRs).getDouble("MILEPOST"); verify(mockStatement).close(); verify(mockConnection).close(); @@ -43,7 +42,7 @@ public void SelectAllRsus_SUCCESS() throws SQLException { @Test public void SelectAllRsus_FAIL() throws SQLException { // Arrange - String selectStatement = "select * from rsu inner join rsu_view on rsu.deviceid = rsu_view.deviceid order by milepost asc"; + String selectStatement = "select rsu_id, ST_X(ST_AsText(geography)) as longitude, ST_Y(ST_AsText(geography)) as latitude, ipv4_address, primary_route, milepost from rsus order by milepost asc"; doThrow(new SQLException()).when(mockRs).getInt("RSU_ID"); // Act ResponseEntity> data = uut.SelectAllRsus(); @@ -56,49 +55,15 @@ public void SelectAllRsus_FAIL() throws SQLException { verify(mockRs).close(); } - @Test - public void SelectActiveRsus_SUCCESS() throws SQLException { - // Arrange - String selectStatement = "select rsu.*, rsu_view.latitude, rsu_view.longitude, rsu_view.ipv4_address from rsu inner join rsu_view on rsu.deviceid = rsu_view.deviceid where rsu_view.status = 'Existing'"; - - // Act - ResponseEntity> data = uut.SelectActiveRsus(); - - // Assert - Assertions.assertEquals(HttpStatus.OK, data.getStatusCode()); - verify(mockStatement).executeQuery(selectStatement); - verify(mockRs).getString("IPV4_ADDRESS"); - verify(mockRs).getBigDecimal("LATITUDE"); - verify(mockRs).getBigDecimal("LONGITUDE"); - verify(mockStatement).close(); - verify(mockConnection).close(); - verify(mockRs).close(); - } - - @Test - public void SelectActiveRsus_FAIL() throws SQLException { - // Arrange - String selectStatement = "select rsu.*, rsu_view.latitude, rsu_view.longitude, rsu_view.ipv4_address from rsu inner join rsu_view on rsu.deviceid = rsu_view.deviceid where rsu_view.status = 'Existing'"; - doThrow(new SQLException()).when(mockRs).getString("IPV4_ADDRESS"); - - // Act - ResponseEntity> data = uut.SelectActiveRsus(); - - // Assert - Assertions.assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, data.getStatusCode()); - verify(mockStatement).executeQuery(selectStatement); - verify(mockStatement).close(); - verify(mockConnection).close(); - verify(mockRs).close(); - } - @Test public void GetFullRsusTimIsOn_SUCCESS() throws SQLException { // Arrange Long timId = -1l; - String selectStatement = "select rsu.*, tim_rsu.rsu_index, rsu_view.latitude, rsu_view.longitude, rsu_view.ipv4_address "; - selectStatement += "from rsu inner join rsu_view on rsu.deviceid = rsu_view.deviceid "; - selectStatement += "inner join tim_rsu on tim_rsu.rsu_id = rsu.rsu_id where tim_rsu.tim_id = " + timId; + String selectStatement = "select rsus.rsu_id, rsu_credentials.username as update_username, " + + "rsu_credentials.password as update_password, ST_X(ST_AsText(rsus.geography)) as longitude, " + + "ST_Y(ST_AsText(rsus.geography)) as latitude, rsus.ipv4_address, tim_rsu.rsu_index from rsus " + + "inner join rsu_credentials on rsu_credentials.credential_id = rsus.credential_id inner join " + + "tim_rsu on tim_rsu.rsu_id = rsus.rsu_id where tim_rsu.tim_id = " + timId; // Act ResponseEntity> data = uut.GetFullRsusTimIsOn(timId); @@ -121,8 +86,11 @@ public void GetFullRsusTimIsOn_SUCCESS() throws SQLException { public void GetFullRsusTimIsOn_FAIL() throws SQLException { // Arrange Long timId = -1l; - String selectStatement = "select rsu.*, tim_rsu.rsu_index, rsu_view.latitude, rsu_view.longitude, rsu_view.ipv4_address from rsu inner join rsu_view on rsu.deviceid = rsu_view.deviceid inner join tim_rsu on tim_rsu.rsu_id = rsu.rsu_id where tim_rsu.tim_id = " - + timId; + String selectStatement = "select rsus.rsu_id, rsu_credentials.username as update_username, " + + "rsu_credentials.password as update_password, ST_X(ST_AsText(rsus.geography)) as longitude, " + + "ST_Y(ST_AsText(rsus.geography)) as latitude, rsus.ipv4_address, tim_rsu.rsu_index from rsus " + + "inner join rsu_credentials on rsu_credentials.credential_id = rsus.credential_id inner join " + + "tim_rsu on tim_rsu.rsu_id = rsus.rsu_id where tim_rsu.tim_id = " + timId; doThrow(new SQLException()).when(mockRs).getString("IPV4_ADDRESS"); // Act @@ -140,8 +108,9 @@ public void GetFullRsusTimIsOn_FAIL() throws SQLException { public void SelectRsusByRoute_SUCCESS() throws SQLException { // Arrange String route = "I80"; - String selectStatement = "select * from rsu inner join rsu_view on rsu.deviceid = rsu_view.deviceid where rsu_view.route like '%" - + route + "%' and rsu_view.status = 'Existing' order by milepost asc"; + String selectStatement = "select rsu_id, ST_X(ST_AsText(geography)) as longitude, " + + "ST_Y(ST_AsText(geography)) as latitude, ipv4_address, primary_route, milepost from rsus " + + "where primary_route like %'%" + route + "%'"; // Act ResponseEntity> data = uut.SelectRsusByRoute(route); @@ -163,8 +132,9 @@ public void SelectRsusByRoute_SUCCESS() throws SQLException { public void SelectRsusByRoute_FAIL() throws SQLException { // Arrange String route = "I80"; - String selectStatement = "select * from rsu inner join rsu_view on rsu.deviceid = rsu_view.deviceid where rsu_view.route like '%" - + route + "%' and rsu_view.status = 'Existing' order by milepost asc"; + String selectStatement = "select rsu_id, ST_X(ST_AsText(geography)) as longitude, " + + "ST_Y(ST_AsText(geography)) as latitude, ipv4_address, primary_route, milepost from rsus " + + "where primary_route like %'%" + route + "%'"; doThrow(new SQLException()).when(mockRs).getInt("RSU_ID"); // Act ResponseEntity> data = uut.SelectRsusByRoute(route); diff --git a/cv-data-service-library/src/test/java/com/trihydro/library/helpers/TimGenerationHelperTest.java b/cv-data-service-library/src/test/java/com/trihydro/library/helpers/TimGenerationHelperTest.java index c2904be6d..6a3badfd2 100644 --- a/cv-data-service-library/src/test/java/com/trihydro/library/helpers/TimGenerationHelperTest.java +++ b/cv-data-service-library/src/test/java/com/trihydro/library/helpers/TimGenerationHelperTest.java @@ -1,7 +1,6 @@ package com.trihydro.library.helpers; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.isA; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.times; @@ -16,7 +15,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.TimeZone; import com.google.gson.Gson; import com.trihydro.library.model.ActiveTim; @@ -44,8 +42,6 @@ import com.trihydro.library.service.SdwService; import com.trihydro.library.service.TimGenerationProps; -import org.junit.After; -import org.junit.Before; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -95,16 +91,6 @@ public class TimGenerationHelperTest { @Captor private ArgumentCaptor timCaptor; - @Before - public void setup() { - TimeZone.setDefault(TimeZone.getTimeZone("UTC")); - } - - @After - public void teardown() { - TimeZone.setDefault(TimeZone.getTimeZone(java.time.ZoneId.systemDefault())); - } - @Test public void resubmitToOde_EmptyList() { // Arrange @@ -170,6 +156,7 @@ public void resubmitToOde_NoMileposts() { verifyNoInteractions(mockDataFrameService, mockPathNodeXYService, mockRegionService, mockRsuService, mockOdeService, mockActiveTimHoldingService, mockSdwService); verify(mockMilepostService).getMilepostsByStartEndPointDirection(any()); + verify(mockMilepostService).getMilepostCache(any()); verifyNoMoreInteractions(mockMilepostService, mockMilepostReduction); } @@ -203,6 +190,7 @@ public void resubmitToOde_DataFrameException() { verify(mockMilepostService).getMilepostsByStartEndPointDirection(any()); verify(mockMilepostReduction).applyMilepostReductionAlgorithm(any(), any()); + verify(mockMilepostService).getMilepostCache(any()); verifyNoMoreInteractions(mockMilepostService, mockMilepostReduction, mockDataFrameService); } @@ -218,8 +206,6 @@ public void resubmitToOde_RsuException() { List mps = new ArrayList(); mps.add(new Milepost()); doReturn(mps).when(mockMilepostReduction).applyMilepostReductionAlgorithm(any(), any()); - String[] rsuRoutes = new String[] { "I 80" }; - doReturn(rsuRoutes).when(mockConfig).getRsuRoutes(); doReturn(new String[] { "1234" }).when(mockDataFrameService).getItisCodesForDataFrameId(any()); @@ -235,13 +221,14 @@ public void resubmitToOde_RsuException() { Assertions.assertEquals(new ResubmitTimException(activeTimId, exMsg), ex); verify(mockRsuService).getFullRsusTimIsOn(any()); - verify(mockRsuService).getRsusByLatLong(any(), any(), any(), any()); + verify(mockRsuService).getRsusByGeometry(any()); verify(mockDataFrameService).getItisCodesForDataFrameId(any()); verifyNoInteractions(mockPathNodeXYService, mockRegionService, mockOdeService, mockActiveTimHoldingService, mockSdwService); verify(mockMilepostService).getMilepostsByStartEndPointDirection(any()); verify(mockMilepostReduction).applyMilepostReductionAlgorithm(any(), any()); + verify(mockMilepostService).getMilepostCache(any()); verifyNoMoreInteractions(mockMilepostService, mockMilepostReduction, mockDataFrameService, mockRsuService); } @@ -257,8 +244,6 @@ public void resubmitToOde_RsuExistingSuccess() { List mps = new ArrayList(); mps.add(new Milepost()); doReturn(mps).when(mockMilepostReduction).applyMilepostReductionAlgorithm(any(), any()); - String[] rsuRoutes = new String[] { "I 80" }; - doReturn(rsuRoutes).when(mockConfig).getRsuRoutes(); List wydotRsus = new ArrayList<>(); var wydotRsuTim = new WydotRsuTim(); @@ -282,6 +267,7 @@ public void resubmitToOde_RsuExistingSuccess() { verify(mockMilepostService).getMilepostsByStartEndPointDirection(any()); verify(mockMilepostReduction).applyMilepostReductionAlgorithm(any(), any()); + verify(mockMilepostService).getMilepostCache(any()); verifyNoMoreInteractions(mockMilepostService, mockMilepostReduction, mockDataFrameService, mockRsuService, mockOdeService); } @@ -298,8 +284,6 @@ public void resubmitToOde_RsuNewFailTimQuery() { List mps = new ArrayList(); mps.add(new Milepost()); doReturn(mps).when(mockMilepostReduction).applyMilepostReductionAlgorithm(any(), any()); - String[] rsuRoutes = new String[] { "I 80" }; - doReturn(rsuRoutes).when(mockConfig).getRsuRoutes(); doReturn(new Coordinate(BigDecimal.valueOf(1), BigDecimal.valueOf(2))).when(mockUtility).calculateAnchorCoordinate(any(), any()); @@ -307,7 +291,7 @@ public void resubmitToOde_RsuNewFailTimQuery() { var rsu = new WydotRsu(); rsu.setRsuTarget("10.10.10.10"); dbRsus.add(rsu); - doReturn(dbRsus).when(mockRsuService).getRsusByLatLong(any(), any(), any(), any()); + doReturn(dbRsus).when(mockRsuService).getRsusByGeometry(any()); doReturn(new String[] { "1234" }).when(mockDataFrameService).getItisCodesForDataFrameId(any()); when(mockOdeService.submitTimQuery(isA(WydotRsu.class), isA(Integer.class))).thenReturn(null); @@ -323,13 +307,13 @@ public void resubmitToOde_RsuNewFailTimQuery() { Assertions.assertEquals(new ResubmitTimException(activeTimId, exMsg), ex); verify(mockRsuService).getFullRsusTimIsOn(any()); - verify(mockRsuService).getRsusByLatLong(any(), any(), any(), any()); verify(mockDataFrameService).getItisCodesForDataFrameId(any()); verify(mockOdeService).submitTimQuery(isA(WydotRsu.class), isA(Integer.class)); verifyNoInteractions(mockPathNodeXYService, mockRegionService, mockSdwService); verify(mockMilepostService).getMilepostsByStartEndPointDirection(any()); verify(mockMilepostReduction).applyMilepostReductionAlgorithm(any(), any()); + verify(mockMilepostService).getMilepostCache(any()); verifyNoMoreInteractions(mockMilepostService, mockMilepostReduction, mockDataFrameService, mockRsuService, mockOdeService, mockActiveTimHoldingService); } @@ -346,14 +330,12 @@ public void resubmitToOde_RsuNewFailIndices() { List mps = new ArrayList(); mps.add(new Milepost()); doReturn(mps).when(mockMilepostReduction).applyMilepostReductionAlgorithm(any(), any()); - String[] rsuRoutes = new String[] { "I 80" }; - doReturn(rsuRoutes).when(mockConfig).getRsuRoutes(); List dbRsus = new ArrayList<>(); var rsu = new WydotRsu(); rsu.setRsuTarget("10.10.10.10"); dbRsus.add(rsu); - doReturn(dbRsus).when(mockRsuService).getRsusByLatLong(any(), any(), any(), any()); + doReturn(dbRsus).when(mockRsuService).getRsusByGeometry(any()); doReturn(new String[] { "1234" }).when(mockDataFrameService).getItisCodesForDataFrameId(any()); when(mockOdeService.submitTimQuery(isA(WydotRsu.class), isA(Integer.class))).thenReturn(new TimQuery()); when(mockOdeService.findFirstAvailableIndexWithRsuIndex(any())).thenReturn(null); @@ -372,13 +354,14 @@ public void resubmitToOde_RsuNewFailIndices() { Assertions.assertEquals(new ResubmitTimException(activeTimId, exMsg), ex); verify(mockRsuService).getFullRsusTimIsOn(any()); - verify(mockRsuService).getRsusByLatLong(any(), any(), any(), any()); + verify(mockRsuService).getRsusByGeometry(any()); verify(mockRsuService).getActiveRsuTimIndexes(any()); verify(mockDataFrameService).getItisCodesForDataFrameId(any()); verify(mockOdeService).submitTimQuery(isA(WydotRsu.class), isA(Integer.class)); verify(mockActiveTimHoldingService).getActiveTimHoldingForRsu(any()); verifyNoInteractions(mockPathNodeXYService, mockRegionService, mockSdwService); + verify(mockMilepostService).getMilepostCache(any()); verify(mockMilepostService).getMilepostsByStartEndPointDirection(any()); verify(mockMilepostReduction).applyMilepostReductionAlgorithm(any(), any()); verifyNoMoreInteractions(mockMilepostService, mockMilepostReduction, mockDataFrameService, mockRsuService, @@ -397,14 +380,12 @@ public void resubmitToOde_RsuNewInsertFail() { List mps = new ArrayList(); mps.add(new Milepost()); doReturn(mps).when(mockMilepostReduction).applyMilepostReductionAlgorithm(any(), any()); - String[] rsuRoutes = new String[] { "I 80" }; - doReturn(rsuRoutes).when(mockConfig).getRsuRoutes(); List dbRsus = new ArrayList<>(); var rsu = new WydotRsu(); rsu.setRsuTarget("10.10.10.10"); dbRsus.add(rsu); - doReturn(dbRsus).when(mockRsuService).getRsusByLatLong(any(), any(), any(), any()); + doReturn(dbRsus).when(mockRsuService).getRsusByGeometry(any()); doReturn(new String[] { "1234" }).when(mockDataFrameService).getItisCodesForDataFrameId(any()); when(mockOdeService.submitTimQuery(isA(WydotRsu.class), isA(Integer.class))).thenReturn(new TimQuery()); when(mockOdeService.findFirstAvailableIndexWithRsuIndex(any())).thenReturn(1); @@ -423,7 +404,7 @@ public void resubmitToOde_RsuNewInsertFail() { Assertions.assertEquals(new ResubmitTimException(activeTimId, exMsg), ex); verify(mockRsuService).getFullRsusTimIsOn(any()); - verify(mockRsuService).getRsusByLatLong(any(), any(), any(), any()); + verify(mockRsuService).getRsusByGeometry(any()); verify(mockRsuService).getActiveRsuTimIndexes(any()); verify(mockDataFrameService).getItisCodesForDataFrameId(any()); verify(mockOdeService).submitTimQuery(isA(WydotRsu.class), isA(Integer.class)); @@ -432,6 +413,7 @@ public void resubmitToOde_RsuNewInsertFail() { verify(mockOdeService).sendNewTimToRsu(any()); verifyNoInteractions(mockPathNodeXYService, mockRegionService, mockSdwService); + verify(mockMilepostService).getMilepostCache(any()); verify(mockMilepostService).getMilepostsByStartEndPointDirection(any()); verify(mockMilepostReduction).applyMilepostReductionAlgorithm(any(), any()); verifyNoMoreInteractions(mockMilepostService, mockMilepostReduction, mockDataFrameService, mockRsuService, @@ -450,14 +432,12 @@ public void resubmitToOde_RsuNewSuccess() { List mps = new ArrayList(); mps.add(new Milepost()); doReturn(mps).when(mockMilepostReduction).applyMilepostReductionAlgorithm(any(), any()); - String[] rsuRoutes = new String[] { "I 80" }; - doReturn(rsuRoutes).when(mockConfig).getRsuRoutes(); List dbRsus = new ArrayList<>(); var rsu = new WydotRsu(); rsu.setRsuTarget("10.10.10.10"); dbRsus.add(rsu); - doReturn(dbRsus).when(mockRsuService).getRsusByLatLong(any(), any(), any(), any()); + doReturn(dbRsus).when(mockRsuService).getRsusByGeometry(any()); doReturn(new String[] { "1234" }).when(mockDataFrameService).getItisCodesForDataFrameId(any()); when(mockOdeService.submitTimQuery(isA(WydotRsu.class), isA(Integer.class))).thenReturn(new TimQuery()); when(mockOdeService.findFirstAvailableIndexWithRsuIndex(any())).thenReturn(1); @@ -470,7 +450,7 @@ public void resubmitToOde_RsuNewSuccess() { // Assert Assertions.assertEquals(0, exceptions.size()); verify(mockRsuService).getFullRsusTimIsOn(any()); - verify(mockRsuService).getRsusByLatLong(any(), any(), any(), any()); + verify(mockRsuService).getRsusByGeometry(any()); verify(mockRsuService).getActiveRsuTimIndexes(any()); verify(mockDataFrameService).getItisCodesForDataFrameId(any()); verify(mockOdeService).submitTimQuery(isA(WydotRsu.class), isA(Integer.class)); @@ -479,6 +459,7 @@ public void resubmitToOde_RsuNewSuccess() { verify(mockOdeService).sendNewTimToRsu(any()); verifyNoInteractions(mockPathNodeXYService, mockRegionService, mockSdwService); + verify(mockMilepostService).getMilepostCache(any()); verify(mockMilepostService).getMilepostsByStartEndPointDirection(any()); verify(mockMilepostReduction).applyMilepostReductionAlgorithm(any(), any()); verifyNoMoreInteractions(mockMilepostService, mockMilepostReduction, mockDataFrameService, mockRsuService, @@ -514,6 +495,7 @@ public void resubmitToOde_SdxNewFail() { verifyNoInteractions(mockPathNodeXYService); verify(mockMilepostService).getMilepostsByStartEndPointDirection(any()); + verify(mockMilepostService).getMilepostCache(any()); verify(mockMilepostReduction).applyMilepostReductionAlgorithm(any(), any()); verifyNoMoreInteractions(mockMilepostService, mockMilepostReduction, mockDataFrameService, mockRsuService, mockOdeService, mockActiveTimHoldingService); @@ -547,6 +529,7 @@ public void resubmitToOde_SdxNewSuccess() { verify(mockOdeService).updateTimOnSdw(any()); verify(mockMilepostService).getMilepostsByStartEndPointDirection(any()); + verify(mockMilepostService).getMilepostCache(any()); verify(mockMilepostReduction).applyMilepostReductionAlgorithm(any(), any()); verifyNoMoreInteractions(mockMilepostService, mockMilepostReduction, mockDataFrameService, mockRsuService, mockOdeService, mockActiveTimHoldingService); @@ -601,7 +584,6 @@ public void resubmitToOde_usesOldStartTime() { tum.setRoute("I 80"); tum.setSatRecordId("satRecordId"); tum.setStartDateTime(""); - TimeZone.setDefault(TimeZone.getTimeZone("UTC")); // Given a TIM with a durationTime of an hour var originalStartTime = Instant.parse("2021-01-01T00:00:00.000Z"); @@ -611,7 +593,7 @@ public void resubmitToOde_usesOldStartTime() { doReturn(new String[] { "1234" }).when(mockDataFrameService).getItisCodesForDataFrameId(any()); doReturn("").when(mockOdeService).updateTimOnSdw(any()); - doReturn(60).when(mockUtility).getMinutesDurationBetweenTwoDates(anyString(), anyString()); + doReturn(60).when(mockUtility).getMinutesDurationBetweenTwoDates("2021-01-01T00:00:00.000Z", "2021-01-01T01:00:00.000Z"); doReturn(new Coordinate(BigDecimal.valueOf(1), BigDecimal.valueOf(2))).when(mockUtility).calculateAnchorCoordinate(any(), any()); @@ -700,6 +682,7 @@ public void resubmitToOde_SdxExistingFail() { verify(mockMilepostService).getMilepostsByStartEndPointDirection(any()); verify(mockMilepostReduction).applyMilepostReductionAlgorithm(any(), any()); + verify(mockMilepostService).getMilepostCache(any()); verifyNoMoreInteractions(mockMilepostService, mockMilepostReduction, mockDataFrameService, mockRsuService, mockOdeService, mockActiveTimHoldingService); } @@ -731,6 +714,7 @@ public void resubmitToOde_SdxExistingSuccess() { verifyNoInteractions(mockPathNodeXYService); verify(mockMilepostService).getMilepostsByStartEndPointDirection(any()); + verify(mockMilepostService).getMilepostCache(any()); verify(mockMilepostReduction).applyMilepostReductionAlgorithm(any(), any()); verifyNoMoreInteractions(mockMilepostService, mockMilepostReduction, mockDataFrameService, mockRsuService, mockOdeService, mockActiveTimHoldingService); @@ -803,6 +787,7 @@ public void updateAndResubmitToOde_noMileposts() { verifyNoInteractions(mockDataFrameService, mockPathNodeXYService, mockRegionService, mockRsuService, mockOdeService, mockActiveTimHoldingService, mockSdwService); verify(mockMilepostService).getMilepostsByStartEndPointDirection(any()); + verify(mockMilepostService).getMilepostCache(any()); verifyNoMoreInteractions(mockMilepostService, mockMilepostReduction); } @@ -839,6 +824,7 @@ public void updateAndResubmitToOde_RsuNewTimFail_EndPointMps() { Assertions.assertEquals(new ResubmitTimException(activeTimId, exMsg), ex); verify(mockDataFrameService).getItisCodesForDataFrameId(any()); verify(mockMilepostService, times(2)).getMilepostsByStartEndPointDirection(any()); + verify(mockMilepostService, times(2)).getMilepostCache(any()); verify(mockMilepostReduction).applyMilepostReductionAlgorithm(any(), any()); verifyNoMoreInteractions(mockMilepostService, mockMilepostReduction, mockDataFrameService); verifyNoInteractions(mockPathNodeXYService, mockRegionService, mockSdwService, mockOdeService, @@ -874,6 +860,7 @@ public void updateAndResubmitToOde_RsuNewTimFail_EndTimeParse() { Assertions.assertEquals(new ResubmitTimException(activeTimId, exMsg), ex); verify(mockDataFrameService).getItisCodesForDataFrameId(any()); verify(mockMilepostService).getMilepostsByStartEndPointDirection(any()); + verify(mockMilepostService).getMilepostCache(any()); verify(mockMilepostReduction).applyMilepostReductionAlgorithm(any(), any()); verifyNoMoreInteractions(mockMilepostService, mockMilepostReduction, mockDataFrameService); verifyNoInteractions(mockPathNodeXYService, mockRegionService, mockSdwService, mockOdeService, @@ -913,6 +900,7 @@ public void updateAndResubmitToOde_RsuNewTimFail_StartPointMps() { Assertions.assertEquals(new ResubmitTimException(activeTimId, exMsg), ex); verify(mockDataFrameService).getItisCodesForDataFrameId(any()); verify(mockMilepostService, times(2)).getMilepostsByStartEndPointDirection(any()); + verify(mockMilepostService, times(2)).getMilepostCache(any()); verify(mockMilepostReduction).applyMilepostReductionAlgorithm(any(), any()); verifyNoMoreInteractions(mockMilepostService, mockMilepostReduction, mockDataFrameService); verifyNoInteractions(mockPathNodeXYService, mockRegionService, mockSdwService, mockOdeService, @@ -929,8 +917,6 @@ public void updateAndResubmitToOde_RsuNewTimSuccess_StartPoint() { List mps = new ArrayList(); mps.add(new Milepost()); doReturn(mps).when(mockMilepostReduction).applyMilepostReductionAlgorithm(any(), any()); - String[] rsuRoutes = new String[] { "I 80" }; - doReturn(rsuRoutes).when(mockConfig).getRsuRoutes(); doReturn(new String[] { "1234" }).when(mockDataFrameService).getItisCodesForDataFrameId(any()); doReturn(new Coordinate(BigDecimal.valueOf(1), BigDecimal.valueOf(2))).when(mockUtility).calculateAnchorCoordinate(any(), any()); @@ -946,7 +932,7 @@ public void updateAndResubmitToOde_RsuNewTimSuccess_StartPoint() { var rsu = new WydotRsu(); rsu.setRsuTarget("10.10.10.10"); dbRsus.add(rsu); - doReturn(dbRsus).when(mockRsuService).getRsusByLatLong(any(), any(), any(), any()); + doReturn(dbRsus).when(mockRsuService).getRsusByGeometry(any()); when(mockOdeService.submitTimQuery(isA(WydotRsu.class), isA(Integer.class))).thenReturn(new TimQuery()); when(mockOdeService.findFirstAvailableIndexWithRsuIndex(any())).thenReturn(1); @@ -956,7 +942,7 @@ public void updateAndResubmitToOde_RsuNewTimSuccess_StartPoint() { // Assert Assertions.assertEquals(0, exceptions.size()); verify(mockRsuService).getFullRsusTimIsOn(any()); - verify(mockRsuService).getRsusByLatLong(any(), any(), any(), any()); + verify(mockRsuService).getRsusByGeometry(any()); verify(mockRsuService).getActiveRsuTimIndexes(any()); verify(mockDataFrameService, times(2)).getItisCodesForDataFrameId(any()); verify(mockOdeService).submitTimQuery(isA(WydotRsu.class), isA(Integer.class)); @@ -966,6 +952,7 @@ public void updateAndResubmitToOde_RsuNewTimSuccess_StartPoint() { verifyNoInteractions(mockPathNodeXYService, mockRegionService, mockSdwService); verify(mockMilepostService, times(2)).getMilepostsByStartEndPointDirection(any()); + verify(mockMilepostService, times(2)).getMilepostCache(any()); verify(mockMilepostReduction, times(2)).applyMilepostReductionAlgorithm(any(), any()); verifyNoMoreInteractions(mockMilepostService, mockMilepostReduction, mockDataFrameService, mockRsuService, mockOdeService, mockActiveTimHoldingService); @@ -981,8 +968,6 @@ public void updateAndResubmitToOde_RsuNewTimSuccess_EndPoint() { List mps = new ArrayList(); mps.add(new Milepost()); doReturn(mps).when(mockMilepostReduction).applyMilepostReductionAlgorithm(any(), any()); - String[] rsuRoutes = new String[] { "I 80" }; - doReturn(rsuRoutes).when(mockConfig).getRsuRoutes(); doReturn(new String[] { "1234" }).when(mockDataFrameService).getItisCodesForDataFrameId(any()); var validationResults = getValidationResults(); @@ -996,7 +981,7 @@ public void updateAndResubmitToOde_RsuNewTimSuccess_EndPoint() { var rsu = new WydotRsu(); rsu.setRsuTarget("10.10.10.10"); dbRsus.add(rsu); - doReturn(dbRsus).when(mockRsuService).getRsusByLatLong(any(), any(), any(), any()); + doReturn(dbRsus).when(mockRsuService).getRsusByGeometry(any()); when(mockOdeService.submitTimQuery(isA(WydotRsu.class), isA(Integer.class))).thenReturn(new TimQuery()); when(mockOdeService.findFirstAvailableIndexWithRsuIndex(any())).thenReturn(1); @@ -1008,7 +993,7 @@ public void updateAndResubmitToOde_RsuNewTimSuccess_EndPoint() { // Assert Assertions.assertEquals(0, exceptions.size()); verify(mockRsuService).getFullRsusTimIsOn(any()); - verify(mockRsuService).getRsusByLatLong(any(), any(), any(), any()); + verify(mockRsuService).getRsusByGeometry(any()); verify(mockRsuService).getActiveRsuTimIndexes(any()); verify(mockDataFrameService, times(2)).getItisCodesForDataFrameId(any()); verify(mockOdeService).submitTimQuery(isA(WydotRsu.class), isA(Integer.class)); @@ -1018,6 +1003,7 @@ public void updateAndResubmitToOde_RsuNewTimSuccess_EndPoint() { verifyNoInteractions(mockPathNodeXYService, mockRegionService, mockSdwService); verify(mockMilepostService, times(2)).getMilepostsByStartEndPointDirection(any()); + verify(mockMilepostService, times(2)).getMilepostCache(any()); verify(mockMilepostReduction, times(2)).applyMilepostReductionAlgorithm(any(), any()); verifyNoMoreInteractions(mockMilepostService, mockMilepostReduction, mockDataFrameService, mockRsuService, mockOdeService, mockActiveTimHoldingService); @@ -1033,8 +1019,6 @@ public void updateAndResubmitToOde_RsuNewTimSuccess_EndTime() { List mps = new ArrayList(); mps.add(new Milepost()); doReturn(mps).when(mockMilepostReduction).applyMilepostReductionAlgorithm(any(), any()); - String[] rsuRoutes = new String[] { "I 80" }; - doReturn(rsuRoutes).when(mockConfig).getRsuRoutes(); doReturn(new String[] { "1234" }).when(mockDataFrameService).getItisCodesForDataFrameId(any()); var validationResults = getValidationResults(); @@ -1046,7 +1030,7 @@ public void updateAndResubmitToOde_RsuNewTimSuccess_EndTime() { var rsu = new WydotRsu(); rsu.setRsuTarget("10.10.10.10"); dbRsus.add(rsu); - doReturn(dbRsus).when(mockRsuService).getRsusByLatLong(any(), any(), any(), any()); + doReturn(dbRsus).when(mockRsuService).getRsusByGeometry(any()); when(mockOdeService.submitTimQuery(isA(WydotRsu.class), isA(Integer.class))).thenReturn(new TimQuery()); when(mockOdeService.findFirstAvailableIndexWithRsuIndex(any())).thenReturn(1); @@ -1058,7 +1042,7 @@ public void updateAndResubmitToOde_RsuNewTimSuccess_EndTime() { // Assert Assertions.assertEquals(0, exceptions.size()); verify(mockRsuService).getFullRsusTimIsOn(any()); - verify(mockRsuService).getRsusByLatLong(any(), any(), any(), any()); + verify(mockRsuService).getRsusByGeometry(any()); verify(mockRsuService).getActiveRsuTimIndexes(any()); verify(mockDataFrameService).getItisCodesForDataFrameId(any()); verify(mockOdeService).submitTimQuery(isA(WydotRsu.class), isA(Integer.class)); @@ -1068,6 +1052,7 @@ public void updateAndResubmitToOde_RsuNewTimSuccess_EndTime() { verifyNoInteractions(mockPathNodeXYService, mockRegionService, mockSdwService); verify(mockMilepostService).getMilepostsByStartEndPointDirection(any()); + verify(mockMilepostService).getMilepostCache(any()); verify(mockMilepostReduction).applyMilepostReductionAlgorithm(any(), any()); verifyNoMoreInteractions(mockMilepostService, mockMilepostReduction, mockDataFrameService, mockRsuService, mockOdeService, mockActiveTimHoldingService); @@ -1083,8 +1068,6 @@ public void updateAndResubmitToOde_RsuUpdateTimSuccess_ItisCodes() { List mps = new ArrayList(); mps.add(new Milepost()); doReturn(mps).when(mockMilepostReduction).applyMilepostReductionAlgorithm(any(), any()); - String[] rsuRoutes = new String[] { "I 80" }; - doReturn(rsuRoutes).when(mockConfig).getRsuRoutes(); doReturn(new String[] { "1234" }).when(mockDataFrameService).getItisCodesForDataFrameId(any()); var validationResults = getValidationResults(); @@ -1112,6 +1095,7 @@ public void updateAndResubmitToOde_RsuUpdateTimSuccess_ItisCodes() { verifyNoInteractions(mockPathNodeXYService, mockRegionService, mockSdwService); verify(mockMilepostService).getMilepostsByStartEndPointDirection(any()); + verify(mockMilepostService).getMilepostCache(any()); verify(mockMilepostReduction).applyMilepostReductionAlgorithm(any(), any()); verifyNoMoreInteractions(mockMilepostService, mockMilepostReduction, mockDataFrameService, mockRsuService, mockOdeService, mockActiveTimHoldingService); @@ -1248,4 +1232,4 @@ private ActiveTim getActiveTim() { tim.setActiveTimId(-1l); return tim; } -} \ No newline at end of file +} diff --git a/logger-kafka-consumer/src/test/java/com/trihydro/loggerkafkaconsumer/app/services/ActiveTimServiceTest.java b/logger-kafka-consumer/src/test/java/com/trihydro/loggerkafkaconsumer/app/services/ActiveTimServiceTest.java index 8fb77ec80..b8c2873cb 100644 --- a/logger-kafka-consumer/src/test/java/com/trihydro/loggerkafkaconsumer/app/services/ActiveTimServiceTest.java +++ b/logger-kafka-consumer/src/test/java/com/trihydro/loggerkafkaconsumer/app/services/ActiveTimServiceTest.java @@ -216,8 +216,7 @@ public void getActiveRsuTim_SUCCESS() throws SQLException { query += " atim.START_LATITUDE, atim.START_LONGITUDE, atim.END_LATITUDE, atim.END_LONGITUDE"; query += " from active_tim atim"; query += " inner join tim_rsu on atim.tim_id = tim_rsu.tim_id"; - query += " inner join rsu on tim_rsu.rsu_id = rsu.rsu_id"; - query += " inner join rsu_view on rsu.deviceid = rsu_view.deviceid"; + query += " inner join rsus on tim_rsu.rsu_id = rsus.rsu_id"; query += " where sat_record_id is null"; query += " and ipv4_address = 'ipv4Address' and client_id = 'clientId'"; query += " and atim.direction = 'direction'"; diff --git a/logger-kafka-consumer/src/test/java/com/trihydro/loggerkafkaconsumer/app/services/RsuServiceTest.java b/logger-kafka-consumer/src/test/java/com/trihydro/loggerkafkaconsumer/app/services/RsuServiceTest.java index 08558c2af..2163cf0e8 100644 --- a/logger-kafka-consumer/src/test/java/com/trihydro/loggerkafkaconsumer/app/services/RsuServiceTest.java +++ b/logger-kafka-consumer/src/test/java/com/trihydro/loggerkafkaconsumer/app/services/RsuServiceTest.java @@ -1,15 +1,14 @@ package com.trihydro.loggerkafkaconsumer.app.services; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.verify; - import java.sql.SQLException; import java.util.ArrayList; -import com.trihydro.library.model.WydotRsu; - import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.verify; + +import com.trihydro.library.model.WydotRsu; public class RsuServiceTest extends TestBase { @@ -23,7 +22,8 @@ public void getRsus_SUCCESS() throws SQLException { // Assert Assertions.assertEquals(1, data.size()); verify(mockStatement).executeQuery( - "select * from rsu inner join rsu_view on rsu.deviceid = rsu_view.deviceid order by milepost asc"); + "select rsu_id, ST_X(ST_AsText(geography)) as longitude, ST_Y(ST_AsText(geography)) " + + "as latitude, ipv4_address, primary_route, milepost from rsus order by milepost asc"); verify(mockRs).getInt("RSU_ID"); verify(mockRs).getString("IPV4_ADDRESS"); verify(mockRs).getBigDecimal("LATITUDE"); @@ -45,7 +45,8 @@ public void getRsus_FAIL() throws SQLException { // Assert Assertions.assertEquals(0, data.size()); verify(mockStatement).executeQuery( - "select * from rsu inner join rsu_view on rsu.deviceid = rsu_view.deviceid order by milepost asc"); + "select rsu_id, ST_X(ST_AsText(geography)) as longitude, ST_Y(ST_AsText(geography)) " + + "as latitude, ipv4_address, primary_route, milepost from rsus order by milepost asc"); verify(mockStatement).close(); verify(mockRs).close(); verify(mockConnection).close(); diff --git a/ode-wrapper/src/test/java/com/trihydro/odewrapper/CopyConstructorTest.java b/ode-wrapper/src/test/java/com/trihydro/odewrapper/CopyConstructorTest.java index d85bb1731..ab0386c36 100644 --- a/ode-wrapper/src/test/java/com/trihydro/odewrapper/CopyConstructorTest.java +++ b/ode-wrapper/src/test/java/com/trihydro/odewrapper/CopyConstructorTest.java @@ -4,6 +4,7 @@ import static org.junit.Assert.assertFalse; import java.math.BigDecimal; +import java.util.ArrayList; import java.util.Arrays; import com.google.gson.Gson; @@ -50,6 +51,8 @@ private void setBaseClassProps(WydotTim o) { o.setRoute("firstRoute"); o.setItisCodes(Arrays.asList("1", "2")); o.setClientId("firstClientId"); + o.setGeometry(new ArrayList()); + o.setBearing(0); } @Test From c07cbdbaa1b5a754f3191b829d00c9b446e65d92 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Fri, 24 Jan 2025 09:46:39 -0700 Subject: [PATCH 048/168] Remove unnecessary variables from sample.env --- sample.env | 2 -- 1 file changed, 2 deletions(-) diff --git a/sample.env b/sample.env index c38ff6d22..e6f753864 100644 --- a/sample.env +++ b/sample.env @@ -134,8 +134,6 @@ RSUCONTROLLER_CONFIG_SNMP_SECURITY_LEVEL=authNoPriv TASKS_CONFIG_ODE_URL=http://ode-url:8080 TASKS_CONFIG_CV_REST_SERVICE=https://ode-url:8888 TASKS_CONFIG_WRAPPER_URL=https://ode-url:7777 -TASKS_CONFIG_CV_REST_SERVICE_DEV=https://ode-url:8888 -# TASKS_CONFIG_CV_REST_SERVICE_PROD=https://ode.wyoroad.info:8888 TASKS_CONFIG_RSU_DATA_SERVICE_URL=http://ode-url:8898 # TASKS_CONFIG_TMDD_URL=https://tmdd-url # TASKS_CONFIG_TMDD_USER=support@example.com From 6b3b04b0fcf2c240ecc63589e8b507884583f435 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Fri, 24 Jan 2025 10:13:27 -0700 Subject: [PATCH 049/168] Fix ActiveTimController test with updated query --- .../controller/ActiveTimController.java | 1 + .../controller/ActiveTimControllerTest.java | 16 ++++++---------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java index 45119991d..205e332a9 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java @@ -533,6 +533,7 @@ public ResponseEntity> GetActiveTimIndicesByRsu(@PathVariable Stri selectStatement += " inner join tim on active_tim.tim_id = tim.tim_id"; selectStatement += " inner join tim_rsu on tim_rsu.tim_id = tim.tim_id"; selectStatement += " inner join rsus on rsus.rsu_id = tim_rsu.rsu_id"; + selectStatement += " where rsus.ipv4_address = '" + rsuTarget + "'"; rs = statement.executeQuery(selectStatement); diff --git a/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/ActiveTimControllerTest.java b/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/ActiveTimControllerTest.java index 304076420..f4fc50888 100644 --- a/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/ActiveTimControllerTest.java +++ b/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/ActiveTimControllerTest.java @@ -386,9 +386,8 @@ public void GetActiveTimIndicesByRsu_SUCCESS() throws SQLException { String selectStatement = "select tim_rsu.rsu_index from active_tim"; selectStatement += " inner join tim on active_tim.tim_id = tim.tim_id"; selectStatement += " inner join tim_rsu on tim_rsu.tim_id = tim.tim_id"; - selectStatement += " inner join rsu on rsu.rsu_id = tim_rsu.rsu_id"; - selectStatement += " inner join rsu_view on rsu.deviceid = rsu_view.deviceid"; - selectStatement += " where rsu_view.ipv4_address = '" + rsuTarget + "'"; + selectStatement += " inner join rsus on rsus.rsu_id = tim_rsu.rsu_id"; + selectStatement += " where rsus.ipv4_address = '" + rsuTarget + "'"; // Act ResponseEntity> data = uut.GetActiveTimIndicesByRsu(rsuTarget); @@ -409,9 +408,8 @@ public void GetActiveTimIndicesByRsu_FAIL() throws SQLException { String selectStatement = "select tim_rsu.rsu_index from active_tim"; selectStatement += " inner join tim on active_tim.tim_id = tim.tim_id"; selectStatement += " inner join tim_rsu on tim_rsu.tim_id = tim.tim_id"; - selectStatement += " inner join rsu on rsu.rsu_id = tim_rsu.rsu_id"; - selectStatement += " inner join rsu_view on rsu.deviceid = rsu_view.deviceid"; - selectStatement += " where rsu_view.ipv4_address = '" + rsuTarget + "'"; + selectStatement += " inner join rsus on rsus.rsu_id = tim_rsu.rsu_id"; + selectStatement += " where rsus.ipv4_address = '" + rsuTarget + "'"; doThrow(new SQLException()).when(mockRs).getInt("RSU_INDEX"); // Act @@ -929,8 +927,7 @@ public void GetActiveRsuTim_SUCCESS() throws SQLException { String ipv4Address = "10.0.0.1"; String query = "select * from active_tim"; query += " inner join tim_rsu on active_tim.tim_id = tim_rsu.tim_id"; - query += " inner join rsu on tim_rsu.rsu_id = rsu.rsu_id"; - query += " inner join rsu_view on rsu.deviceid = rsu_view.deviceid"; + query += " inner join rsus on tim_rsu.rsu_id = rsus.rsu_id"; query += " where ipv4_address = '" + ipv4Address + "' and client_id = '" + clientId; query += "' and active_tim.direction = '" + direction + "'"; @@ -968,8 +965,7 @@ public void GetActiveRsuTim_FAIL() throws SQLException { String ipv4Address = "10.0.0.1"; String query = "select * from active_tim"; query += " inner join tim_rsu on active_tim.tim_id = tim_rsu.tim_id"; - query += " inner join rsu on tim_rsu.rsu_id = rsu.rsu_id"; - query += " inner join rsu_view on rsu.deviceid = rsu_view.deviceid"; + query += " inner join rsus on tim_rsu.rsu_id = rsus.rsu_id"; query += " where ipv4_address = '" + ipv4Address + "' and client_id = '" + clientId; query += "' and active_tim.direction = '" + direction + "'"; doThrow(new SQLException()).when(mockStatement).executeQuery(query); From d3f0218ab4bba0dd92aa549780b25898312f4434 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 30 Jan 2025 07:42:52 -0700 Subject: [PATCH 050/168] Update jpo-ode packages to use latest release --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 524af503b..48cf34647 100644 --- a/pom.xml +++ b/pom.xml @@ -68,7 +68,7 @@ usdot.jpo.ode jpo-ode-core - 3.0.0 + 4.0.0 * @@ -79,7 +79,7 @@ usdot.jpo.ode jpo-ode-common - 3.0.0 + 4.0.0 * @@ -90,7 +90,7 @@ usdot.jpo.ode jpo-ode-plugins - 3.0.0 + 4.0.0 * @@ -101,7 +101,7 @@ usdot.jpo.ode jpo-ode-svcs - 3.0.0 + 4.0.0 * From 2a521d18a0d4bb1203a5f583fecafbbc20232d92 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 30 Jan 2025 12:17:47 -0700 Subject: [PATCH 051/168] Update KafkaFactory to include confluent cloud properties --- .../library/factory/KafkaFactory.java | 43 ++++++++++++++++--- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/factory/KafkaFactory.java b/cv-data-service-library/src/main/java/com/trihydro/library/factory/KafkaFactory.java index b8d1c1a79..2249ce392 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/factory/KafkaFactory.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/factory/KafkaFactory.java @@ -2,10 +2,9 @@ import java.util.Arrays; import java.util.List; +import java.util.Optional; import java.util.Properties; -import com.trihydro.library.helpers.Utility; - import org.apache.commons.lang3.StringUtils; import org.apache.kafka.clients.consumer.Consumer; import org.apache.kafka.clients.consumer.KafkaConsumer; @@ -14,13 +13,24 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import com.google.common.base.Strings; +import com.trihydro.library.helpers.Utility; + @Component public class KafkaFactory { - private Utility utility; + private final Utility utility; + private final String kafkaType; + private final Properties kafkaProperties; @Autowired - public KafkaFactory(Utility _utility) { + public KafkaFactory(Utility _utility) throws IllegalArgumentException { utility = _utility; + kafkaType = Optional.ofNullable(System.getenv("KAFKA_TYPE")).orElse("LOCAL"); + if ("CONFLUENT".equalsIgnoreCase(kafkaType)) { + kafkaProperties = addConfluentProperties(new Properties()); + } else { + kafkaProperties = new Properties(); + } } /** @@ -109,6 +119,8 @@ public Consumer createStringConsumer(String host, String consume props.put("max.poll.records", maxPollRecords.intValue()); } + props.putAll(kafkaProperties); + var consumer = new KafkaConsumer(props); consumer.subscribe(topics); @@ -131,6 +143,27 @@ public Producer createStringProducer(String host) { props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer"); - return new KafkaProducer(props); + props.putAll(kafkaProperties); + + return new KafkaProducer<>(props); + } + + private Properties addConfluentProperties(Properties props) { + String username = System.getenv("CONFLUENT_KEY"); + String password = System.getenv("CONFLUENT_SECRET"); + + if (Strings.isNullOrEmpty(username) || Strings.isNullOrEmpty(password)) { + throw new IllegalArgumentException("CONFLUENT_KEY and CONFLUENT_SECRET must be set in the environment"); + } + + String auth = "org.apache.kafka.common.security.plain.PlainLoginModule required " + + "username=\"" + username + "\" " + + "password=\"" + password + "\";"; + props.put("sasl.jaas.config", auth); + props.put("ssl.endpoint.identification.algorithm", "https"); + props.put("security.protocol", "SASL_SSL"); + props.put("sasl.mechanism", "PLAIN"); + + return props; } } \ No newline at end of file From a4aba6ed8447ea31fc4c62d23ddcbdec12dd0ad5 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 30 Jan 2025 12:19:08 -0700 Subject: [PATCH 052/168] Add CDOT deployment docker compose file --- docker-compose-cdot-deployment.yml | 212 +++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 docker-compose-cdot-deployment.yml diff --git a/docker-compose-cdot-deployment.yml b/docker-compose-cdot-deployment.yml new file mode 100644 index 000000000..428a356ed --- /dev/null +++ b/docker-compose-cdot-deployment.yml @@ -0,0 +1,212 @@ +services: + ode_wrapper: + build: ode-wrapper + restart: always + environment: + SERVER_PORT: ${WRAPPER_SERVER_PORT} + CONFIG_ODE_URL: ${WRAPPER_CONFIG_ODE_URL} + CONFIG_DB_URL: ${WRAPPER_CONFIG_DB_URL} + CONFIG_DB_USERNAME: ${WRAPPER_CONFIG_DB_USERNAME} + CONFIG_DB_PASSWORD: ${WRAPPER_CONFIG_DB_PASSWORD} + CONFIG_MAXIMUM_POOL_SIZE: ${WRAPPER_CONFIG_MAXIMUM_POOL_SIZE} + CONFIG_CONNECTION_TIMEOUT: ${WRAPPER_CONFIG_CONNECTION_TIMEOUT} + CONFIG_SDW_TTL: ${WRAPPER_CONFIG_SDW_TTL} + CONFIG_SDW_REST_URL: ${SDW_REST_URL} + CONFIG_SDW_API_KEY: ${SDW_API_KEY} + CONFIG_ALERT_ADDRESSES: ${WRAPPER_CONFIG_ALERT_ADDRESSES} + CONFIG_FROM_EMAIL: ${WRAPPER_CONFIG_FROM_EMAIL} + CONFIG_MAIL_HOST: ${MAIL_HOST} + CONFIG_MAIL_PORT: ${MAIL_PORT} + CONFIG_ENVIRONMENT_NAME: ${ENVIRONMENT_NAME} + CONFIG_DEFAULT_LANE_WIDTH: ${WRAPPER_CONFIG_DEFAULT_LANE_WIDTH} + CONFIG_CV_REST_SERVICE: ${WRAPPER_CONFIG_CV_REST_SERVICE} + CONFIG_HTTP_LOGGING_MAX_SIZE: ${WRAPPER_CONFIG_HTTP_LOGGING_MAX_SIZE} + CONFIG_RSU_ROUTES: ${WRAPPER_CONFIG_RSU_ROUTES} + CONFIG_POINT_INCIDENT_BUFFER_MILES: ${WRAPPER_CONFIG_POINT_INCIDENT_BUFFER_MILES} + ports: + - "7777:7777" + logging: + options: + max-size: "20m" + max-file: "3" + + cv-data-tasks: + build: cv-data-tasks + restart: always + environment: + CONFIG_ODE_URL: ${TASKS_CONFIG_ODE_URL} + CONFIG_CV_REST_SERVICE: ${TASKS_CONFIG_CV_REST_SERVICE} + CONFIG_RSU_DATA_SERVICE_URL: ${TASKS_CONFIG_RSU_DATA_SERVICE_URL} + CONFIG_WRAPPER_URL: ${TASKS_CONFIG_WRAPPER_URL} + CONFIG_MAIL_HOST: ${MAIL_HOST} + CONFIG_MAIL_PORT: ${MAIL_PORT} + CONFIG_ENVIRONMENT_NAME: ${ENVIRONMENT_NAME} + CONFIG_SDW_REST_URL: ${SDW_REST_URL} + CONFIG_SDW_API_KEY: ${SDW_API_KEY} + CONFIG_TMDD_URL: ${TASKS_CONFIG_TMDD_URL} + CONFIG_TMDD_USER: ${TASKS_CONFIG_TMDD_USER} + CONFIG_TMDD_PASSWORD: ${TASKS_CONFIG_TMDD_PASSWORD} + CONFIG_ALERT_ADDRESSES: ${TASKS_CONFIG_ALERT_ADDRESSES} + CONFIG_FROM_EMAIL: ${TASKS_CONFIG_FROM_EMAIL} + CONFIG_RUN_TMDD_VALIDATION: ${TASKS_CONFIG_RUN_TMDD_VALIDATION} + CONFIG_RUN_RSU_VALIDATION: ${TASKS_CONFIG_RUN_RSU_VALIDATION} + CONFIG_RSU_VALIDATION_DELAY_SECONDS: ${TASKS_CONFIG_RSU_VALIDATION_DELAY_SECONDS} + CONFIG_RSU_VAL_THREAD_POOL_SIZE: ${TASKS_CONFIG_RSU_VAL_THREAD_POOL_SIZE} + CONFIG_RSU_VAL_TIMEOUT_SECONDS: ${TASKS_CONFIG_RSU_VAL_TIMEOUT_SECONDS} + CONFIG_REMOVE_EXPIRED_PERIOD_MINUTES: ${TASKS_CONFIG_REMOVE_EXPIRED_PERIOD_MINUTES} + CONFIG_CLEANUP_PERIOD_MINUTES: ${TASKS_CONFIG_CLEANUP_PERIOD_MINUTES} + CONFIG_SDX_VALIDATION_PERIOD_MINUTES: ${TASKS_CONFIG_SDX_VALIDATION_PERIOD_MINUTES} + CONFIG_RSU_VALIDATION_PERIOD_MINUTES: ${TASKS_CONFIG_RSU_VALIDATION_PERIOD_MINUTES} + CONFIG_TMDD_VALIDATION_PERIOD_MINUTES: ${TASKS_CONFIG_TMDD_VALIDATION_PERIOD_MINUTES} + CONFIG_RETENTION_ENFORCEMENT_PERIOD_MINUTES: ${TASKS_CONFIG_RETENTION_ENFORCEMENT_PERIOD_MINUTES} + CONFIG_RETENTION_REMOVE_TIMS: ${TASKS_CONFIG_RETENTION_REMOVE_TIMS} + CONFIG_RETENTION_REMOVE_STATUS_LOGS: ${TASKS_CONFIG_RETENTION_REMOVE_STATUS_LOGS} + CONFIG_HSM_FUNCTIONALITY_MINUTES: ${TASKS_CONFIG_HSM_FUNCTIONALITY_MINUTES} + CONFIG_HSM_URL: ${TASKS_CONFIG_HSM_URL} + CONFIG_HSM_ERROR_EMAIL_FREQUENCY_MINUTES: ${TASKS_CONFIG_HSM_ERROR_EMAIL_FREQUENCY_MINUTES} + CONFIG_RUN_HSM_CHECK: ${TASKS_CONFIG_RUN_HSM_CHECK} + CONFIG_SDW_TTL: ${TASKS_CONFIG_SDW_TTL} + CONFIG_DEFAULT_LANE_WIDTH: ${TASKS_CONFIG_DEFAULT_LANE_WIDTH} + CONFIG_RSU_ROUTES: ${TASKS_CONFIG_RSU_ROUTES} + CONFIG_POINT_INCIDENT_BUFFER_MILES: ${TASKS_CONFIG_POINT_INCIDENT_BUFFER_MILES} + logging: + options: + max-size: "20m" + max-file: "3" + depends_on: + - ode_wrapper + - cv-data-controller + - rsu-data-controller + + tim-refresh: + build: tim-refresh + restart: always + environment: + CONFIG_ODE_URL: ${REFRESH_CONFIG_ODE_URL} + CONFIG_SDW_TTL: ${REFRESH_CONFIG_SDW_TTL} + CONFIG_CV_REST_SERVICE: ${REFRESH_CONFIG_CV_REST_SERVICE} + CONFIG_SDW_REST_URL: ${SDW_REST_URL} + CONFIG_SDW_API_KEY: ${SDW_API_KEY} + CONFIG_DEFAULT_LANE_WIDTH: ${REFRESH_CONFIG_DEFAULT_LANE_WIDTH} + CONFIG_RSU_ROUTES: ${REFRESH_CONFIG_RSU_ROUTES} + CONFIG_POINT_INCIDENT_BUFFER_MILES: ${REFRESH_CONFIG_POINT_INCIDENT_BUFFER_MILES} + CRON_EXPRESSION: ${REFRESH_CRON_EXPRESSION} + CONFIG_ALERT_ADDRESSES: ${REFRESH_CONFIG_ALERT_ADDRESSES} + CONFIG_FROM_EMAIL: ${REFRESH_CONFIG_FROM_EMAIL} + CONFIG_ENVIRONMENT_NAME: ${ENVIRONMENT_NAME} + CONFIG_MAIL_HOST: ${MAIL_HOST} + CONFIG_MAIL_PORT: ${MAIL_PORT} + logging: + options: + max-size: "20m" + max-file: "3" + + cv-data-controller: + build: cv-data-controller + restart: always + ports: + - "8888:8888" + environment: + SERVER_PORT: ${CONTROLLER_SERVER_PORT} + CONFIG_DB_URL: ${CONTROLLER_CONFIG_DB_URL} + CONFIG_DB_USERNAME: ${CONTROLLER_CONFIG_DB_USERNAME} + CONFIG_DB_PASSWORD: ${CONTROLLER_CONFIG_DB_PASSWORD} + CONFIG_MAXIMUM_POOL_SIZE: ${CONTROLLER_CONFIG_MAXIMUM_POOL_SIZE} + CONFIG_CONNECTION_TIMEOUT: ${CONTROLLER_CONFIG_CONNECTION_TIMEOUT} + CONFIG_ODE_URL: ${CONTROLLER_CONFIG_ODE_URL} + SPRING_DATA_NEO4J_URI: ${CONTROLLER_SPRING_DATA_NEO4J_URI} + CONFIG_ALERT_ADDRESSES: ${CONTROLLER_CONFIG_ALERT_ADDRESSES} + CONFIG_FROM_EMAIL: ${CONTROLLER_CONFIG_FROM_EMAIL} + CONFIG_ENVIRONMENT_NAME: ${ENVIRONMENT_NAME} + CONFIG_MAIL_HOST: ${MAIL_HOST} + CONFIG_MAIL_PORT: ${MAIL_PORT} + logging: + options: + max-size: "20m" + max-file: "3" + + rsu-data-controller: + build: rsu-data-controller + restart: always + ports: + - "8898:8898" + environment: + SERVER_PORT: ${RSUCONTROLLER_SERVER_PORT} + CONFIG_SNMP_RETRIES: ${RSUCONTROLLER_CONFIG_SNMP_RETRIES} + CONFIG_SNMP_TIMEOUT_SECONDS: ${RSUCONTROLLER_CONFIG_SNMP_TIMEOUT_SECONDS} + CONFIG_SNMP_USER_NAME: ${RSUCONTROLLER_CONFIG_SNMP_USER_NAME} + CONFIG_SNMP_AUTH_PASSPHRASE: ${RSUCONTROLLER_CONFIG_SNMP_AUTH_PASSPHRASE} + CONFIG_SNMP_AUTH_PROTOCOL: ${RSUCONTROLLER_CONFIG_SNMP_AUTH_PROTOCOL} + CONFIG_SNMP_SECURITY_LEVEL: ${RSUCONTROLLER_CONFIG_SNMP_SECURITY_LEVEL} + logging: + options: + max-size: "20m" + max-file: "3" + + tim_logger: + build: ode-data-logger + restart: always + environment: + KAFKA_HOST_SERVER: ${LOGGER_KAFKA_HOST_SERVER} + KAFKA_TYPE: ${KAFKA_TYPE} + CONFLUENT_KEY: ${CONFLUENT_KEY} + CONFLUENT_SECRET: ${CONFLUENT_SECRET} + ALERT_ADDRESSES: ${LOGGER_ALERT_ADDRESSES} + FROM_EMAIL: ${LOGGER_FROM_EMAIL} + ENVIRONMENT_NAME: ${ENVIRONMENT_NAME} + MAIL_HOST: ${MAIL_HOST} + MAIL_PORT: ${MAIL_PORT} + DEPOSIT_TOPIC: ${TIM_TOPIC} + DEPOSIT_GROUP: ${TIM_GROUP_ORACLE} + CV_REST_SERVICE: ${LOGGER_CV_REST_SERVICE} + PRODUCER_TOPIC: ${DBCONSUMER_DEPOSIT_TOPIC} + logging: + options: + max-size: "20m" + max-file: "3" + + logger-kafka-consumer: + build: logger-kafka-consumer + restart: always + environment: + DEPOSIT_GROUP: ${DBCONSUMER_DEPOSIT_GROUP} + DEPOSIT_TOPIC: ${DBCONSUMER_DEPOSIT_TOPIC} + KAFKA_HOST_SERVER: ${DBCONSUMER_KAFKA_HOST_SERVER} + KAFKA_TYPE: ${KAFKA_TYPE} + CONFLUENT_KEY: ${CONFLUENT_KEY} + CONFLUENT_SECRET: ${CONFLUENT_SECRET} + MAX_POLL_INTERVAL_MS: ${DBCONSUMER_MAX_POLL_INTERVAL_MS} + MAX_POLL_RECORDS: ${DBCONSUMER_MAX_POLL_RECORDS} + DB_URL: ${DBCONSUMER_DB_URL} + DB_USERNAME: ${DBCONSUMER_DB_USERNAME} + DB_PASSWORD: ${DBCONSUMER_DB_PASSWORD} + MAXIMUM_POOL_SIZE: ${DBCONSUMER_MAXIMUM_POOL_SIZE} + CONNECTION_TIMEOUT: ${DBCONSUMER_CONNECTION_TIMEOUT} + ALERT_ADDRESSES: ${DBCONSUMER_ALERT_ADDRESSES} + FROM_EMAIL: ${DBCONSUMER_FROM_EMAIL} + ENVIRONMENT_NAME: ${ENVIRONMENT_NAME} + MAIL_HOST: ${MAIL_HOST} + MAIL_PORT: ${MAIL_PORT} + logging: + options: + max-size: "20m" + max-file: "3" + + cert-expiration: + build: cert-expiration + restart: always + environment: + KAFKA_HOST_SERVER: ${LOGGER_KAFKA_HOST_SERVER} + ALERT_ADDRESSES: ${LOGGER_ALERT_ADDRESSES} + FROM_EMAIL: ${LOGGER_FROM_EMAIL} + ENVIRONMENT_NAME: ${ENVIRONMENT_NAME} + MAIL_HOST: ${MAIL_HOST} + MAIL_PORT: ${MAIL_PORT} + DEPOSIT_TOPIC: ${EXP_TOPIC} + DEPOSIT_GROUP: ${EXP_GROUP} + CV_REST_SERVICE: ${LOGGER_CV_REST_SERVICE} + PRODUCER_TOPIC: ${DBCONSUMER_DEPOSIT_TOPIC} + logging: + options: + max-size: "20m" + max-file: "3" \ No newline at end of file From be340d7cbbcabddcd30e798f7f364be98ac42a56 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 30 Jan 2025 14:31:23 -0700 Subject: [PATCH 053/168] Update RsuServiceTest to account for getRSU method --- .../rsudatacontroller/service/RsuService.java | 2 +- .../service/RsuServiceTest.java | 120 ++++++++++++++++-- 2 files changed, 108 insertions(+), 14 deletions(-) diff --git a/rsu-data-controller/src/main/java/com/trihydro/rsudatacontroller/service/RsuService.java b/rsu-data-controller/src/main/java/com/trihydro/rsudatacontroller/service/RsuService.java index d4c7864fd..11c9a8b8c 100644 --- a/rsu-data-controller/src/main/java/com/trihydro/rsudatacontroller/service/RsuService.java +++ b/rsu-data-controller/src/main/java/com/trihydro/rsudatacontroller/service/RsuService.java @@ -129,7 +129,7 @@ private String hexStringToDateTime(String hexString) { return date.format(rsuDateTimeFormatter); } - private RSU getRSU(String rsuIpv4Address) throws Exception { + RSU getRSU(String rsuIpv4Address) throws Exception { // Need to grab firmware type, username, password. Connection connection = null; Statement statement = null; diff --git a/rsu-data-controller/src/test/java/com/trihydro/rsudatacontroller/service/RsuServiceTest.java b/rsu-data-controller/src/test/java/com/trihydro/rsudatacontroller/service/RsuServiceTest.java index 7b6456c19..59315f567 100644 --- a/rsu-data-controller/src/test/java/com/trihydro/rsudatacontroller/service/RsuServiceTest.java +++ b/rsu-data-controller/src/test/java/com/trihydro/rsudatacontroller/service/RsuServiceTest.java @@ -2,23 +2,32 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.Statement; import java.util.List; +import com.trihydro.library.helpers.DbInteractions; import com.trihydro.library.helpers.Utility; import com.trihydro.rsudatacontroller.config.BasicConfiguration; import com.trihydro.rsudatacontroller.model.RsuTim; import com.trihydro.rsudatacontroller.process.ProcessFactory; +import us.dot.its.jpo.ode.plugin.RoadSideUnit.RSU; +import us.dot.its.jpo.ode.plugin.SnmpProtocol; + import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.ArgumentCaptor; @@ -26,6 +35,7 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; + @ExtendWith(MockitoExtension.class) public class RsuServiceTest { @Mock @@ -47,12 +57,9 @@ public class RsuServiceTest { @InjectMocks RsuService uut; - @BeforeEach public void initMocks() { when(mockConfig.getSnmpRetries()).thenReturn(0); when(mockConfig.getSnmpTimeoutSeconds()).thenReturn(10); - when(mockConfig.getSnmpUserName()).thenReturn("username"); - when(mockConfig.getSnmpAuthPassphrase()).thenReturn("passphrase"); when(mockConfig.getSnmpAuthProtocol()).thenReturn("protocol"); when(mockConfig.getSnmpSecurityLevel()).thenReturn("level"); } @@ -65,12 +72,15 @@ private void setupProcess() { public void getAllDeliveryStartTimes_success() throws Exception { // Arrange setupProcess(); + initMocks(); InputStream output = getInputStream("iso.0.15628.4.1.4.1.7.2 = Hex-STRING: 07 E4 03 14 11 3B", "iso.0.15628.4.1.4.1.7.3 = Hex-STRING: 07 E4 03 14 13 1E"); doReturn(output).when(mockProcess).getInputStream(); + RsuService spyUut = spy(uut); + doReturn(new RSU("0.0.0.0", "username", "password", 3, 10, SnmpProtocol.FOURDOT1)).when(spyUut).getRSU(any()); // Act - List results = uut.getAllDeliveryStartTimes("0.0.0.0"); + List results = spyUut.getAllDeliveryStartTimes("0.0.0.0"); // Assert Assertions.assertEquals(2, results.size()); @@ -80,7 +90,7 @@ public void getAllDeliveryStartTimes_success() throws Exception { Assertions.assertEquals("2020-03-20 19:30:00", results.get(1).getDeliveryStartTime()); Assertions.assertEquals( - "snmpwalk -v 3 -r 0 -t 10 -u username -l level -a protocol -A passphrase 0.0.0.0 1.0.15628.4.1.4.1.7", + "snmpwalk -v 3 -r 0 -t 10 -u username -l level -a protocol -A password 0.0.0.0 1.0.15628.4.1.4.1.7", String.join(" ", factoryArgs.getAllValues())); } @@ -88,11 +98,14 @@ public void getAllDeliveryStartTimes_success() throws Exception { public void getAllDeliveryStartTimes_single() throws Exception { // Arrange setupProcess(); + initMocks(); InputStream output = getInputStream("iso.0.15628.4.1.4.1.7.2 = Hex-STRING: 07 E4 03 14 11 3B "); doReturn(output).when(mockProcess).getInputStream(); + RsuService spyUut = spy(uut); + doReturn(new RSU("0.0.0.0", "username", "password", 3, 10, SnmpProtocol.FOURDOT1)).when(spyUut).getRSU(any()); // Act - List results = uut.getAllDeliveryStartTimes("0.0.0.0"); + List results = spyUut.getAllDeliveryStartTimes("0.0.0.0"); // Assert Assertions.assertEquals(1, results.size()); @@ -100,7 +113,7 @@ public void getAllDeliveryStartTimes_single() throws Exception { Assertions.assertEquals("2020-03-20 17:59:00", results.get(0).getDeliveryStartTime()); Assertions.assertEquals( - "snmpwalk -v 3 -r 0 -t 10 -u username -l level -a protocol -A passphrase 0.0.0.0 1.0.15628.4.1.4.1.7", + "snmpwalk -v 3 -r 0 -t 10 -u username -l level -a protocol -A password 0.0.0.0 1.0.15628.4.1.4.1.7", String.join(" ", factoryArgs.getAllValues())); } @@ -108,17 +121,20 @@ public void getAllDeliveryStartTimes_single() throws Exception { public void getAllDeliveryStartTimes_none() throws Exception { // Arrange setupProcess(); + initMocks(); InputStream output = getInputStream(""); doReturn(output).when(mockProcess).getInputStream(); + RsuService spyUut = spy(uut); + doReturn(new RSU("0.0.0.0", "username", "password", 3, 10, SnmpProtocol.FOURDOT1)).when(spyUut).getRSU(any()); // Act - List results = uut.getAllDeliveryStartTimes("0.0.0.0"); + List results = spyUut.getAllDeliveryStartTimes("0.0.0.0"); // Assert Assertions.assertEquals(0, results.size()); Assertions.assertEquals( - "snmpwalk -v 3 -r 0 -t 10 -u username -l level -a protocol -A passphrase 0.0.0.0 1.0.15628.4.1.4.1.7", + "snmpwalk -v 3 -r 0 -t 10 -u username -l level -a protocol -A password 0.0.0.0 1.0.15628.4.1.4.1.7", String.join(" ", factoryArgs.getAllValues())); } @@ -126,11 +142,14 @@ public void getAllDeliveryStartTimes_none() throws Exception { public void getAllDeliveryStartTimes_snmpTimeout() throws Exception { // Arrange setupProcess(); + initMocks(); InputStream output = getInputStream("snmpwalk: Timeout"); doReturn(output).when(mockProcess).getInputStream(); + RsuService spyUut = spy(uut); + doReturn(new RSU("0.0.0.0", "username", "password", 3, 10, SnmpProtocol.FOURDOT1)).when(spyUut).getRSU(any()); // Act - List results = uut.getAllDeliveryStartTimes("0.0.0.0"); + List results = spyUut.getAllDeliveryStartTimes("0.0.0.0"); // Assert Assertions.assertNull(results); @@ -142,21 +161,96 @@ public void getAllDeliveryStartTimes_throwsRuntimeException() throws Exception { // Arrange doThrow(new RuntimeException("unable to find snmpwalk command")).when(mockProcessFactory) .buildAndStartProcess(any()); + RsuService spyUut = spy(uut); + doReturn(new RSU("0.0.0.0", "username", "password", 3, 10, SnmpProtocol.FOURDOT1)).when(spyUut).getRSU(any()); // Act - Assertions.assertThrows(RuntimeException.class, () -> uut.getAllDeliveryStartTimes("0.0.0.0")); + Assertions.assertThrows(RuntimeException.class, () -> spyUut.getAllDeliveryStartTimes("0.0.0.0")); } @Test public void getAllDeliveryStartTimes_throwsIOException() throws Exception { // Arrange setupProcess(); + initMocks(); doThrow(new IOException("error occurred reading input stream")).when(mockInputStream).read(any(), anyInt(), anyInt()); doReturn(mockInputStream).when(mockProcess).getInputStream(); + RsuService spyUut = spy(uut); + doReturn(new RSU("0.0.0.0", "username", "password", 3, 10, SnmpProtocol.FOURDOT1)).when(spyUut).getRSU(any()); + + // Act + Assertions.assertThrows(IOException.class, () -> spyUut.getAllDeliveryStartTimes("0.0.0.0")); + } + + @Test + public void getRSU_Success() throws Exception { + // Arrange + String rsuIpv4Address = "192.168.1.1"; + String username = "testUser"; + String password = "testPass"; + String nickname = "NTCIP 1218"; + SnmpProtocol snmpProtocol = SnmpProtocol.NTCIP1218; + + Connection mockConnection = mock(Connection.class); + Statement mockStatement = mock(Statement.class); + ResultSet mockResultSet = mock(ResultSet.class); + RsuService spyUut = spy(uut); + DbInteractions mockDbInteractions = mock(DbInteractions.class); + + when(mockDbInteractions.getConnectionPool()).thenReturn(mockConnection); + when(mockConnection.createStatement()).thenReturn(mockStatement); + when(mockStatement.executeQuery(anyString())).thenReturn(mockResultSet); + when(mockResultSet.next()).thenReturn(true).thenReturn(false); + when(mockResultSet.getString("username")).thenReturn(username); + when(mockResultSet.getString("password")).thenReturn(password); + when(mockResultSet.getString("nickname")).thenReturn(nickname); + + spyUut.dbInteractions = mockDbInteractions; // Act - Assertions.assertThrows(IOException.class, () -> uut.getAllDeliveryStartTimes("0.0.0.0")); + RSU result = spyUut.getRSU(rsuIpv4Address); + + // Assert + Assertions.assertNotNull(result); + Assertions.assertEquals(rsuIpv4Address, result.getRsuTarget()); + Assertions.assertEquals(username, result.getRsuUsername()); + Assertions.assertEquals(password, result.getRsuPassword()); + Assertions.assertEquals(snmpProtocol, result.getSnmpProtocol()); + + verify(mockConnection).close(); + verify(mockStatement).close(); + verify(mockResultSet).close(); + } + + @Test + public void getRSU_NoResult() throws Exception { + // Arrange + String rsuIpv4Address = "192.168.1.1"; + + Connection mockConnection = mock(Connection.class); + Statement mockStatement = mock(Statement.class); + ResultSet mockResultSet = mock(ResultSet.class); + DbInteractions mockDbInteractions = mock(DbInteractions.class); + + RsuService spyUut = spy(uut); + + when(mockDbInteractions.getConnectionPool()).thenReturn(mockConnection); + when(mockConnection.createStatement()).thenReturn(mockStatement); + when(mockStatement.executeQuery(anyString())).thenReturn(mockResultSet); + when(mockResultSet.next()).thenReturn(false); + + spyUut.dbInteractions = mockDbInteractions; + + // Act + RSU result = spyUut.getRSU(rsuIpv4Address); + + // Assert + Assertions.assertNull(result); + + verify(mockConnection).close(); + verify(mockStatement).close(); + verify(mockResultSet).close(); } private InputStream getInputStream(String... lines) { From 71109b43678ca9d3f8b1fabfbeb55153b57aff5f Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 30 Jan 2025 21:14:00 -0700 Subject: [PATCH 054/168] Update KafkaFactory to use config properties for confluent --- .../library/factory/KafkaFactory.java | 40 ++++++++++++++++--- .../src/main/resources/application.properties | 3 ++ .../src/test/resources/application.properties | 6 ++- 3 files changed, 42 insertions(+), 7 deletions(-) create mode 100644 cv-data-service-library/src/main/resources/application.properties diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/factory/KafkaFactory.java b/cv-data-service-library/src/main/java/com/trihydro/library/factory/KafkaFactory.java index 2249ce392..e0ddca64d 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/factory/KafkaFactory.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/factory/KafkaFactory.java @@ -2,7 +2,6 @@ import java.util.Arrays; import java.util.List; -import java.util.Optional; import java.util.Properties; import org.apache.commons.lang3.StringUtils; @@ -11,21 +10,26 @@ import org.apache.kafka.clients.producer.KafkaProducer; import org.apache.kafka.clients.producer.Producer; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import com.google.common.base.Strings; import com.trihydro.library.helpers.Utility; @Component +@ConfigurationProperties("data-service-library.kafka") public class KafkaFactory { private final Utility utility; - private final String kafkaType; + private String kafkaType; + private String confluentKey; + private String confluentSecret; private final Properties kafkaProperties; @Autowired public KafkaFactory(Utility _utility) throws IllegalArgumentException { utility = _utility; - kafkaType = Optional.ofNullable(System.getenv("KAFKA_TYPE")).orElse("LOCAL"); + kafkaType = getKafkaType(); + if ("CONFLUENT".equalsIgnoreCase(kafkaType)) { kafkaProperties = addConfluentProperties(new Properties()); } else { @@ -148,9 +152,9 @@ public Producer createStringProducer(String host) { return new KafkaProducer<>(props); } - private Properties addConfluentProperties(Properties props) { - String username = System.getenv("CONFLUENT_KEY"); - String password = System.getenv("CONFLUENT_SECRET"); + Properties addConfluentProperties(Properties props) { + String username = getConfluentKey(); + String password = getConfluentSecret(); if (Strings.isNullOrEmpty(username) || Strings.isNullOrEmpty(password)) { throw new IllegalArgumentException("CONFLUENT_KEY and CONFLUENT_SECRET must be set in the environment"); @@ -166,4 +170,28 @@ private Properties addConfluentProperties(Properties props) { return props; } + + final String getKafkaType() { + return kafkaType; + } + + public String getConfluentKey() { + return confluentKey; + } + + public void setConfluentKey(String confluentKey) { + this.confluentKey = confluentKey; + } + + public String getConfluentSecret() { + return confluentSecret; + } + + public void setConfluentSecret(String confluentSecret) { + this.confluentSecret = confluentSecret; + } + + public void setKafkaType(String kafkaType) { + this.kafkaType = kafkaType; + } } \ No newline at end of file diff --git a/cv-data-service-library/src/main/resources/application.properties b/cv-data-service-library/src/main/resources/application.properties new file mode 100644 index 000000000..352a7edc2 --- /dev/null +++ b/cv-data-service-library/src/main/resources/application.properties @@ -0,0 +1,3 @@ +data-service-library.kafka.confluentKey=someKey +data-service-library.kafka.confluentSecret=someSecret +data-service-library.kafka.kafkaType=LOCAL \ No newline at end of file diff --git a/cv-data-service-library/src/test/resources/application.properties b/cv-data-service-library/src/test/resources/application.properties index 1cb73ae12..1283129c1 100644 --- a/cv-data-service-library/src/test/resources/application.properties +++ b/cv-data-service-library/src/test/resources/application.properties @@ -11,4 +11,8 @@ config.dbPassword=password config.maximumPoolSize=7 config.connectionTimeout=300000 config.env=test -config.sdwRestUrl=http://localhost:12230 \ No newline at end of file +config.sdwRestUrl=http://localhost:12230 + +data-service-library.kafka.confluentKey=testKey +data-service-library.kafka.confluentSecret=testSecret +data-service-library.kafka.kafkaType=LOCAL \ No newline at end of file From 1efacb6239a81959a7d08b4ce89f08157c94f6c6 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 30 Jan 2025 21:14:17 -0700 Subject: [PATCH 055/168] Add KafkaFactoryTest --- .../library/factory/KafkaFactoryTest.java | 127 ++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 cv-data-service-library/src/test/java/com/trihydro/library/factory/KafkaFactoryTest.java diff --git a/cv-data-service-library/src/test/java/com/trihydro/library/factory/KafkaFactoryTest.java b/cv-data-service-library/src/test/java/com/trihydro/library/factory/KafkaFactoryTest.java new file mode 100644 index 000000000..1e23a36e6 --- /dev/null +++ b/cv-data-service-library/src/test/java/com/trihydro/library/factory/KafkaFactoryTest.java @@ -0,0 +1,127 @@ +package com.trihydro.library.factory; + +import java.util.Arrays; +import java.util.List; +import java.util.Properties; + +import org.apache.kafka.clients.consumer.Consumer; +import org.apache.kafka.clients.producer.Producer; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import static org.mockito.ArgumentMatchers.anyString; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import org.mockito.junit.jupiter.MockitoExtension; + +import com.trihydro.library.helpers.Utility; + + +@ExtendWith(MockitoExtension.class) +public class KafkaFactoryTest { + + @Mock + private Utility utility; + + @InjectMocks + private KafkaFactory kafkaFactory; + + @Test + public void testCreateStringConsumerLocal() { + String host = "localhost:9092"; + String consumerGroup = "testGroup"; + String topic = "testTopic"; + + Consumer consumer = kafkaFactory.createStringConsumer(host, consumerGroup, topic); + + assertNotNull(consumer); + verify(utility).logWithDate(anyString()); + } + + @Test + public void testKafkaFactoryConstructorConfluentException() throws Exception { + KafkaFactory kafkaFactoryTest = new KafkaFactory(utility); + assertThrows(IllegalArgumentException.class, () -> { + kafkaFactoryTest.addConfluentProperties(new Properties()); + }); + } + + @Test + public void testKafkaFactoryConstructorConfluent() { + // Create a spy of KafkaFactory + KafkaFactory spyKafkaFactory = spy(new KafkaFactory(utility)); + + // Mock the getKafka() method + doReturn("testKey").when(spyKafkaFactory).getConfluentKey(); + doReturn("testSecret").when(spyKafkaFactory).getConfluentSecret(); + + Properties props = spyKafkaFactory.addConfluentProperties(new Properties()); + + assertNotNull(props); + assertEquals("org.apache.kafka.common.security.plain.PlainLoginModule required username=\"testKey\" password=\"testSecret\";", props.getProperty("sasl.jaas.config")); + assertEquals("https", props.getProperty("ssl.endpoint.identification.algorithm")); + assertEquals("SASL_SSL", props.getProperty("security.protocol")); + assertEquals("PLAIN", props.getProperty("sasl.mechanism")); + } + + @Test + public void testCreateStringConsumerWithProperties() { + String host = "localhost:9092"; + String consumerGroup = "testGroup"; + List topics = Arrays.asList("testTopic1", "testTopic2"); + Integer maxPollInterval = 300000; + Integer maxPollRecords = 500; + + Consumer consumer = kafkaFactory.createStringConsumer(host, consumerGroup, topics, maxPollInterval, maxPollRecords); + + assertNotNull(consumer); + verify(utility).logWithDate(anyString()); + } + + @Test + public void testCreateStringProducerLocal() { + String host = "localhost:9092"; + + Producer producer = kafkaFactory.createStringProducer(host); + + assertNotNull(producer); + } + + @Test + public void testCreateStringConsumerLocalWithInvalidHost() { + String host = ""; + String consumerGroup = "testGroup"; + String topic = "testTopic"; + + assertThrows(IllegalArgumentException.class, () -> { + kafkaFactory.createStringConsumer(host, consumerGroup, topic); + }); + } + + @Test + public void testCreateStringConsumerWithInvalidConsumerGroup() { + String host = "localhost:9092"; + String consumerGroup = ""; + String topic = "testTopic"; + + assertThrows(IllegalArgumentException.class, () -> { + kafkaFactory.createStringConsumer(host, consumerGroup, topic); + }); + } + + @Test + public void testCreateStringConsumerWithInvalidTopics() { + String host = "localhost:9092"; + String consumerGroup = "testGroup"; + List topics = Arrays.asList(); + + assertThrows(IllegalArgumentException.class, () -> { + kafkaFactory.createStringConsumer(host, consumerGroup, topics); + }); + } +} \ No newline at end of file From d1ac4a925c9c81114204033d80c64ace3886034f Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 30 Jan 2025 21:14:43 -0700 Subject: [PATCH 056/168] Update deployment file with config property variables --- docker-compose-cdot-deployment.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docker-compose-cdot-deployment.yml b/docker-compose-cdot-deployment.yml index 428a356ed..e330f65db 100644 --- a/docker-compose-cdot-deployment.yml +++ b/docker-compose-cdot-deployment.yml @@ -148,9 +148,9 @@ services: restart: always environment: KAFKA_HOST_SERVER: ${LOGGER_KAFKA_HOST_SERVER} - KAFKA_TYPE: ${KAFKA_TYPE} - CONFLUENT_KEY: ${CONFLUENT_KEY} - CONFLUENT_SECRET: ${CONFLUENT_SECRET} + DATA_SERVICE_LIBRARY_KAFKA_KAFKA_TYPE: ${KAFKA_TYPE} + DATA_SERVICE_LIBRARY_KAFKA_CONFLUENT_KEY: ${CONFLUENT_KEY} + DATA_SERVICE_LIBRARY_KAFKA_CONFLUENT_SECRET: ${CONFLUENT_SECRET} ALERT_ADDRESSES: ${LOGGER_ALERT_ADDRESSES} FROM_EMAIL: ${LOGGER_FROM_EMAIL} ENVIRONMENT_NAME: ${ENVIRONMENT_NAME} @@ -172,9 +172,9 @@ services: DEPOSIT_GROUP: ${DBCONSUMER_DEPOSIT_GROUP} DEPOSIT_TOPIC: ${DBCONSUMER_DEPOSIT_TOPIC} KAFKA_HOST_SERVER: ${DBCONSUMER_KAFKA_HOST_SERVER} - KAFKA_TYPE: ${KAFKA_TYPE} - CONFLUENT_KEY: ${CONFLUENT_KEY} - CONFLUENT_SECRET: ${CONFLUENT_SECRET} + DATA_SERVICE_LIBRARY_KAFKA_KAFKA_TYPE: ${KAFKA_TYPE} + DATA_SERVICE_LIBRARY_KAFKA_CONFLUENT_KEY: ${CONFLUENT_KEY} + DATA_SERVICE_LIBRARY_KAFKA_CONFLUENT_SECRET: ${CONFLUENT_SECRET} MAX_POLL_INTERVAL_MS: ${DBCONSUMER_MAX_POLL_INTERVAL_MS} MAX_POLL_RECORDS: ${DBCONSUMER_MAX_POLL_RECORDS} DB_URL: ${DBCONSUMER_DB_URL} From 88783bfc29476faa575cb902b9d45cb877f89ec2 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 30 Jan 2025 21:22:38 -0700 Subject: [PATCH 057/168] Update doNotUse values --- .../src/test/resources/broadcastTim_OdeOutput.json | 6 +++--- .../src/test/resources/sdxDecodeResponse.json | 2 +- .../src/test/resources/tim_construction.json | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/cv-data-service-library/src/test/resources/broadcastTim_OdeOutput.json b/cv-data-service-library/src/test/resources/broadcastTim_OdeOutput.json index bd4554e74..6558c2134 100644 --- a/cv-data-service-library/src/test/resources/broadcastTim_OdeOutput.json +++ b/cv-data-service-library/src/test/resources/broadcastTim_OdeOutput.json @@ -22,7 +22,7 @@ "urlB": "null", "dataframes": [ { - "doNotUse1": 1, + "doNotUse1": 0, "frameType": "advisory", "msgId": { "furtherInfoID": "CDEF" @@ -30,7 +30,7 @@ "startDateTime": "2018-03-15T21:18:46.719-07:00", "durationTime": 32000, "priority": 5, - "doNotUse2": 1, + "doNotUse2": 0, "regions": [ { "name": "westbound_I80_370.0_365.0_RSU-10.145.1.100_VSL", @@ -180,7 +180,7 @@ } ], "doNotUse4": 0, - "doNotUse3": 1, + "doNotUse3": 0, "content": "Advisory", "items": [ "268", diff --git a/cv-data-service-library/src/test/resources/sdxDecodeResponse.json b/cv-data-service-library/src/test/resources/sdxDecodeResponse.json index 9ca0bc47a..0ee50ee8c 100644 --- a/cv-data-service-library/src/test/resources/sdxDecodeResponse.json +++ b/cv-data-service-library/src/test/resources/sdxDecodeResponse.json @@ -1,4 +1,4 @@ { "messageType": "MessageFrame", - "decodedMessage": "3113469004null1414344751-1101051425111111111111111120194690043200051westbound_I80_39.9_53.31_SAT-4035A5DF_RC_LYMI80EGRAD00414344751-11010514253270000000011111100000-1048300445417415787-1101068786414338729-1048297813417401082-1101173822414302517-1048296846417313218-1101278808414263469-1048334156417231472-1101362065414212124-1048363596417151273-1048348231417067803-1101430219414153700-1101515051414095801-1048292665416990008-1101609734414047121-1048303785416903264-1101704290413998478-1048330081416818875-1101798529413950074-1048362115416736381-1048394037416654255-1101901550413914121-1102014424413891332-1048426742416569080-1102126907413868840-1048459137416484285-1102235582413840132-1048492892416400669-1102332568413793094-1048526150416318091-1048559229416236049-1102434259413752451-1102543983413731407-1048592545416153296-1102655116413714865-1048625771416070802-1102767179413702216-1048658799415988821-1102881705413689256-1048694127415905527-1048732305415821992-1102996201413671479-1103105581413647716-1048769216415741004-1103216030413622307-1048806392415659600-1103325763413587617-1048843990415577334-11033794134135705071158955907null" + "decodedMessage": "3113469004null0414344751-1101051425111111111111111120194690043200050westbound_I80_39.9_53.31_SAT-4035A5DF_RC_LYMI80EGRAD00414344751-11010514253270000000011111100000-1048300445417415787-1101068786414338729-1048297813417401082-1101173822414302517-1048296846417313218-1101278808414263469-1048334156417231472-1101362065414212124-1048363596417151273-1048348231417067803-1101430219414153700-1101515051414095801-1048292665416990008-1101609734414047121-1048303785416903264-1101704290413998478-1048330081416818875-1101798529413950074-1048362115416736381-1048394037416654255-1101901550413914121-1102014424413891332-1048426742416569080-1102126907413868840-1048459137416484285-1102235582413840132-1048492892416400669-1102332568413793094-1048526150416318091-1048559229416236049-1102434259413752451-1102543983413731407-1048592545416153296-1102655116413714865-1048625771416070802-1102767179413702216-1048658799415988821-1102881705413689256-1048694127415905527-1048732305415821992-1102996201413671479-1103105581413647716-1048769216415741004-1103216030413622307-1048806392415659600-1103325763413587617-1048843990415577334-11033794134135705070058955907null" } diff --git a/cv-data-service-library/src/test/resources/tim_construction.json b/cv-data-service-library/src/test/resources/tim_construction.json index 604df86df..0b721d01d 100644 --- a/cv-data-service-library/src/test/resources/tim_construction.json +++ b/cv-data-service-library/src/test/resources/tim_construction.json @@ -80,8 +80,8 @@ } }, "durationTime": 32000, - "doNotUse3": 1, - "doNotUse4": 1, + "doNotUse3": 0, + "doNotUse4": 0, "startYear": 2021, "msgId": { "roadSignID": { @@ -101,8 +101,8 @@ } }, "url": null, - "doNotUse1": 1, - "doNotUse2": 1, + "doNotUse1": 0, + "doNotUse2": 0, "frameType": { "advisory": "" }, "startTime": 89280 } From 7b697b96b47c0d9ee17bcce58b1c144acebd88e9 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Fri, 31 Jan 2025 14:56:47 -0700 Subject: [PATCH 058/168] Update RC TIM set ITIS codes to use ITIS code array, not advisory array --- .../odewrapper/helpers/SetItisCodes.java | 16 ++++++---- .../odewrapper/helpers/SetItisCodesTest.java | 32 +++++++++---------- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java index 4186b6e17..dacb12724 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java @@ -65,26 +65,28 @@ public List setItisCodesFromAdvisoryArray(WydotTimRc wydotTim) { public List setItisCodesRc(WydotTimRc wydotTim) { - List items = new ArrayList(); + List items = new ArrayList<>(); - if (wydotTim.getAdvisory() == null) { + if (wydotTim.getItisCodes() == null) { return items; } - ItisCode code = null; + ItisCode code; - for (Integer item : wydotTim.getAdvisory()) { + for (String item : wydotTim.getItisCodes()) { + + Integer itisCode = Integer.valueOf(item); - var alphaItis = getCustomAlphabetic(item); + var alphaItis = getCustomAlphabetic(itisCode); if (alphaItis != null) { items.add(alphaItis); continue; } // map "closed" itis code - if (item == 769) { + if (itisCode == 769) { code = getItisCodes().stream().filter(x -> x.getItisCode().equals(770)).findFirst().orElse(null); } else { - code = getItisCodes().stream().filter(x -> x.getItisCode().equals(item)).findFirst().orElse(null); + code = getItisCodes().stream().filter(x -> x.getItisCode().equals(itisCode)).findFirst().orElse(null); } if (code != null) diff --git a/ode-wrapper/src/test/java/com/trihydro/odewrapper/helpers/SetItisCodesTest.java b/ode-wrapper/src/test/java/com/trihydro/odewrapper/helpers/SetItisCodesTest.java index f8fffa1f4..2f9af1f7f 100644 --- a/ode-wrapper/src/test/java/com/trihydro/odewrapper/helpers/SetItisCodesTest.java +++ b/ode-wrapper/src/test/java/com/trihydro/odewrapper/helpers/SetItisCodesTest.java @@ -65,10 +65,10 @@ public void setItisCodesRc_numeric() { // Arrange setup(); WydotTimRc tim = new WydotTimRc(); - Integer[] itisCodes = new Integer[2]; - itisCodes[0] = 4868; - itisCodes[1] = 1309; - tim.setAdvisory(itisCodes); + ArrayList itisCodes = new ArrayList(); + itisCodes.add("4868"); + itisCodes.add("1309"); + tim.setItisCodes(itisCodes); // Act var result = uut.setItisCodesRc(tim); @@ -81,10 +81,10 @@ public void setItisCodesRc_nonExistent() { // Arrange setup(); WydotTimRc tim = new WydotTimRc(); - Integer[] itisCodes = new Integer[2]; - itisCodes[0] = 0; - itisCodes[1] = 13; - tim.setAdvisory(itisCodes); + ArrayList itisCodes = new ArrayList<>(); + itisCodes.add("0"); + itisCodes.add("13"); + tim.setItisCodes(itisCodes); // Act var result = uut.setItisCodesRc(tim); @@ -97,10 +97,10 @@ public void setItisCodesRc_translated() { // Arrange setup(); WydotTimRc tim = new WydotTimRc(); - Integer[] itisCodes = new Integer[2]; - itisCodes[0] = 4868; - itisCodes[1] = 769; - tim.setAdvisory(itisCodes); + ArrayList itisCodes = new ArrayList<>(); + itisCodes.add("4868"); + itisCodes.add("769"); + tim.setItisCodes(itisCodes); // Act var result = uut.setItisCodesRc(tim); @@ -114,10 +114,10 @@ public void setItisCodesRc_alphabetic() { // Arrange setup(); WydotTimRc tim = new WydotTimRc(); - Integer[] itisCodes = new Integer[2]; - itisCodes[0] = 4868; - itisCodes[1] = CustomItisEnum.blowOver.getValue(); - tim.setAdvisory(itisCodes); + ArrayList itisCodes = new ArrayList<>(); + itisCodes.add("4868"); + itisCodes.add(String.valueOf(CustomItisEnum.blowOver.getValue())); + tim.setItisCodes(itisCodes); // Act var result = uut.setItisCodesRc(tim); From 907ba23e45d5e50a27454fc62722979f5433a232 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 6 Feb 2025 09:22:09 -0700 Subject: [PATCH 059/168] Add logging_level_root to CDOT deployment docker-compose file --- docker-compose-cdot-deployment.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker-compose-cdot-deployment.yml b/docker-compose-cdot-deployment.yml index e330f65db..d3f291fdc 100644 --- a/docker-compose-cdot-deployment.yml +++ b/docker-compose-cdot-deployment.yml @@ -120,6 +120,7 @@ services: CONFIG_ENVIRONMENT_NAME: ${ENVIRONMENT_NAME} CONFIG_MAIL_HOST: ${MAIL_HOST} CONFIG_MAIL_PORT: ${MAIL_PORT} + LOGGING_LEVEL_ROOT: ${CONTROLLER_LOGGING_LEVEL_ROOT} logging: options: max-size: "20m" From 8e27cacef828c64eb67a0d62f167296b95295721 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 6 Feb 2025 09:38:32 -0700 Subject: [PATCH 060/168] Remove unused geometry string method --- .../java/com/trihydro/library/model/WydotTim.java | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/model/WydotTim.java b/cv-data-service-library/src/main/java/com/trihydro/library/model/WydotTim.java index d2e03f251..47a3ac896 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/model/WydotTim.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/model/WydotTim.java @@ -130,17 +130,4 @@ public boolean isGeometryValid() { return false; } } - - public String getGeometryString() { - if (this.geometry!= null && this.geometry.size() > 0) { - StringBuilder sb = new StringBuilder(); - sb.append("["); - for (Coordinate coord : this.geometry) { - sb.append("{\"latitude\": ").append(coord.getLatitude()).append(", ").append("\"longitude\": ").append(coord.getLongitude()).append("}, "); - } - return sb.toString().trim(); - } else { - return ""; - } - } } \ No newline at end of file From c4600a999bf79099d0f91436abcf22f674fdcd93 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 6 Feb 2025 09:52:47 -0700 Subject: [PATCH 061/168] Update comments --- .../com/trihydro/rsudatacontroller/service/RsuService.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/rsu-data-controller/src/main/java/com/trihydro/rsudatacontroller/service/RsuService.java b/rsu-data-controller/src/main/java/com/trihydro/rsudatacontroller/service/RsuService.java index 11c9a8b8c..0a035af89 100644 --- a/rsu-data-controller/src/main/java/com/trihydro/rsudatacontroller/service/RsuService.java +++ b/rsu-data-controller/src/main/java/com/trihydro/rsudatacontroller/service/RsuService.java @@ -130,7 +130,6 @@ private String hexStringToDateTime(String hexString) { } RSU getRSU(String rsuIpv4Address) throws Exception { - // Need to grab firmware type, username, password. Connection connection = null; Statement statement = null; ResultSet rs = null; @@ -141,10 +140,8 @@ RSU getRSU(String rsuIpv4Address) throws Exception { connection = dbInteractions.getConnectionPool(); statement = connection.createStatement(); - - // The inner subqueries leave us with a list of tim_ids that aren't associated - // with any valid itis codes. Select the active_tims with - // those tim_ids + + // select RSU username, password, and firmware type String selectStatement = "select rc.username, rc.password, sp.nickname FROM rsus " + "JOIN rsu_credentials AS rc " + // "ON rsus.snmp_credential_id = rc.credential_id " + // From c2616566f90d05ea203f0ca4236c9035eeb3c9ce Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 6 Feb 2025 10:27:20 -0700 Subject: [PATCH 062/168] Update TimGenerationHelperTest with changes to run locally --- .../trihydro/library/helpers/TimGenerationHelperTest.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cv-data-service-library/src/test/java/com/trihydro/library/helpers/TimGenerationHelperTest.java b/cv-data-service-library/src/test/java/com/trihydro/library/helpers/TimGenerationHelperTest.java index 6a3badfd2..cd2fc9eea 100644 --- a/cv-data-service-library/src/test/java/com/trihydro/library/helpers/TimGenerationHelperTest.java +++ b/cv-data-service-library/src/test/java/com/trihydro/library/helpers/TimGenerationHelperTest.java @@ -1,6 +1,7 @@ package com.trihydro.library.helpers; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.isA; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.times; @@ -15,6 +16,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.TimeZone; import com.google.gson.Gson; import com.trihydro.library.model.ActiveTim; @@ -584,6 +586,7 @@ public void resubmitToOde_usesOldStartTime() { tum.setRoute("I 80"); tum.setSatRecordId("satRecordId"); tum.setStartDateTime(""); + TimeZone.setDefault(TimeZone.getTimeZone("UTC")); // Given a TIM with a durationTime of an hour var originalStartTime = Instant.parse("2021-01-01T00:00:00.000Z"); @@ -593,7 +596,7 @@ public void resubmitToOde_usesOldStartTime() { doReturn(new String[] { "1234" }).when(mockDataFrameService).getItisCodesForDataFrameId(any()); doReturn("").when(mockOdeService).updateTimOnSdw(any()); - doReturn(60).when(mockUtility).getMinutesDurationBetweenTwoDates("2021-01-01T00:00:00.000Z", "2021-01-01T01:00:00.000Z"); + doReturn(60).when(mockUtility).getMinutesDurationBetweenTwoDates(anyString(), anyString()); doReturn(new Coordinate(BigDecimal.valueOf(1), BigDecimal.valueOf(2))).when(mockUtility).calculateAnchorCoordinate(any(), any()); From deca3b59b5f4570c478c0f0003a5b00aca6bdbe6 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 6 Feb 2025 13:58:37 -0700 Subject: [PATCH 063/168] Update cache clear logic --- .../controller/MilepostController.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/MilepostController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/MilepostController.java index 317557c40..9292b9e95 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/MilepostController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/MilepostController.java @@ -363,13 +363,17 @@ public ResponseEntity clearMilepostCache() { statement = connection.createStatement(); rs = statement.executeQuery("SELECT client_id FROM active_tim WHERE marked_for_deletion = False"); - // convert result to milepost objects + List activeTimIds = new ArrayList<>(); while (rs.next()) { String tim_id = rs.getString("CLIENT_ID"); - if (!timIDs.contains(tim_id)) { - milepostCache.remove(tim_id); - } + activeTimIds.add(tim_id); + } + // remove all active TIM IDs from the list of milepost cache TIM IDs + timIDs.removeAll(activeTimIds); + for (String timID : timIDs) { + milepostCache.remove(timID); } + } catch (SQLException e) { e.printStackTrace(); } finally { From c66ec5044bf0b3d1135ce06aa4f201be1e60167d Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Fri, 7 Mar 2025 12:57:50 -0700 Subject: [PATCH 064/168] Extract UpdateTimModel set properties into a new method, update TimUpdateModel declaration --- .../controller/ActiveTimController.java | 186 ++++++------------ 1 file changed, 64 insertions(+), 122 deletions(-) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java index 92fcc016d..4ed242070 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java @@ -73,7 +73,6 @@ public void InjectDependencies(TimDbTables _timDbTables, SQLNullHandler _sqlNull */ @RequestMapping(value = "/expiring", method = RequestMethod.GET, headers = "Accept=application/json") public ResponseEntity> GetExpiringActiveTims() { - TimUpdateModel activeTim = null; List activeTims = new ArrayList(); Connection connection = null; Statement statement = null; @@ -106,67 +105,7 @@ public ResponseEntity> GetExpiringActiveTims() { // convert to ActiveTim object while (rs.next()) { - activeTim = new TimUpdateModel(); - - // Active_Tim properties - activeTim.setActiveTimId(rs.getLong("ACTIVE_TIM_ID")); - activeTim.setTimId(rs.getLong("TIM_ID")); - activeTim.setDirection(rs.getString("DIRECTION")); - activeTim.setStartDateTime(rs.getString("TIM_START")); - activeTim.setEndDateTime(rs.getString("TIM_END")); - activeTim.setExpirationDateTime(rs.getString("EXPIRATION_DATE")); - activeTim.setSatRecordId(rs.getString("SAT_RECORD_ID")); - activeTim.setClientId(rs.getString("CLIENT_ID")); - activeTim.setRoute(rs.getString("ROUTE")); - - Coordinate startPoint = null; - Coordinate endPoint = null; - BigDecimal startLat = rs.getBigDecimal("START_LATITUDE"); - BigDecimal startLon = rs.getBigDecimal("START_LONGITUDE"); - if (!rs.wasNull()) { - startPoint = new Coordinate(startLat, startLon); - } - activeTim.setStartPoint(startPoint); - - BigDecimal endLat = rs.getBigDecimal("END_LATITUDE"); - BigDecimal endLon = rs.getBigDecimal("END_LONGITUDE"); - if (!rs.wasNull()) { - endPoint = new Coordinate(endLat, endLon); - } - activeTim.setEndPoint(endPoint); - - activeTim.setStartDate_Timestamp(rs.getTimestamp("TIM_START", UTCCalendar)); - activeTim.setEndDate_Timestamp(rs.getTimestamp("TIM_END", UTCCalendar)); - - // Tim properties - activeTim.setMsgCnt(rs.getInt("MSG_CNT")); - activeTim.setUrlB(rs.getString("URL_B")); - activeTim.setPacketId(rs.getString("PACKET_ID")); - - // Tim Type properties - activeTim.setTimTypeName(rs.getString("TIM_TYPE_NAME")); - activeTim.setTimTypeDescription(rs.getString("TIM_TYPE_DESCRIPTION")); - - // Region Properties - activeTim.setRegionId(rs.getInt("REGION_ID")); - activeTim.setAnchorLat(rs.getBigDecimal("ANCHOR_LAT")); - activeTim.setAnchorLong(rs.getBigDecimal("ANCHOR_LONG")); - - activeTim.setLaneWidth(rs.getBigDecimal("LANE_WIDTH")); - activeTim.setRegionDirection(rs.getString("REGION_DIRECTION")); - activeTim.setDirectionality(rs.getString("DIRECTIONALITY")); - activeTim.setClosedPath(rs.getBoolean("CLOSED_PATH")); - activeTim.setPathId(rs.getInt("PATH_ID")); - activeTim.setRegionDescription(rs.getString("REGION_DESCRIPTION")); - - // DataFrame properties - activeTim.setDataFrameId(rs.getInt("DATA_FRAME_ID")); - activeTim.setDurationTime(rs.getInt("DURATION_TIME")); - activeTim.setDoNotUse2((short) 0); // as of J2735 2020 this should be set to 0 and is ignored - activeTim.setDoNotUse1((short) 0); // as of J2735 2020 this should be set to 0 and is ignored - activeTim.setDoNotUse4((short) 0); // as of J2735 2020 this should be set to 0 and is ignored - activeTim.setDoNotUse3((short) 0); // as of J2735 2020 this should be set to 0 and is ignored - activeTim.setUrl(rs.getString("URL")); + var activeTim = setPropertiesForActiveTim(rs, new TimUpdateModel()); int frameTypeValue = rs.getInt("FRAME_TYPE"); if (!rs.wasNull() && frameTypeValue >= 0 && frameTypeValue < TravelerInfoType.values().length) { @@ -237,67 +176,8 @@ public ResponseEntity GetUpdateModelFromActiveTimId(@PathVariabl // convert to ActiveTim object while (rs.next()) { - activeTim = new TimUpdateModel(); - // Active_Tim properties - activeTim.setActiveTimId(rs.getLong("ACTIVE_TIM_ID")); - activeTim.setTimId(rs.getLong("TIM_ID")); - activeTim.setDirection(rs.getString("DIRECTION")); - activeTim.setStartDateTime(rs.getString("TIM_START")); - activeTim.setEndDateTime(rs.getString("TIM_END")); - activeTim.setExpirationDateTime(rs.getString("EXPIRATION_DATE")); - activeTim.setSatRecordId(rs.getString("SAT_RECORD_ID")); - activeTim.setClientId(rs.getString("CLIENT_ID")); - activeTim.setRoute(rs.getString("ROUTE")); - - Coordinate startPoint = null; - Coordinate endPoint = null; - BigDecimal startLat = rs.getBigDecimal("START_LATITUDE"); - BigDecimal startLon = rs.getBigDecimal("START_LONGITUDE"); - if (!rs.wasNull()) { - startPoint = new Coordinate(startLat, startLon); - } - activeTim.setStartPoint(startPoint); - - BigDecimal endLat = rs.getBigDecimal("END_LATITUDE"); - BigDecimal endLon = rs.getBigDecimal("END_LONGITUDE"); - if (!rs.wasNull()) { - endPoint = new Coordinate(endLat, endLon); - } - activeTim.setEndPoint(endPoint); - - activeTim.setStartDate_Timestamp(rs.getTimestamp("TIM_START", UTCCalendar)); - activeTim.setEndDate_Timestamp(rs.getTimestamp("TIM_END", UTCCalendar)); - - // Tim properties - activeTim.setMsgCnt(rs.getInt("MSG_CNT")); - activeTim.setUrlB(rs.getString("URL_B")); - activeTim.setPacketId(rs.getString("PACKET_ID")); - - // Tim Type properties - activeTim.setTimTypeName(rs.getString("TIM_TYPE_NAME")); - activeTim.setTimTypeDescription(rs.getString("TIM_TYPE_DESCRIPTION")); - - // Region Properties - activeTim.setRegionId(rs.getInt("REGION_ID")); - activeTim.setAnchorLat(rs.getBigDecimal("ANCHOR_LAT")); - activeTim.setAnchorLong(rs.getBigDecimal("ANCHOR_LONG")); - - activeTim.setLaneWidth(rs.getBigDecimal("LANE_WIDTH")); - activeTim.setRegionDirection(rs.getString("REGION_DIRECTION")); - activeTim.setDirectionality(rs.getString("DIRECTIONALITY")); - activeTim.setClosedPath(rs.getBoolean("CLOSED_PATH")); - activeTim.setPathId(rs.getInt("PATH_ID")); - activeTim.setRegionDescription(rs.getString("REGION_DESCRIPTION")); - - // DataFrame properties - activeTim.setDataFrameId(rs.getInt("DATA_FRAME_ID")); - activeTim.setDurationTime(rs.getInt("DURATION_TIME")); - activeTim.setDoNotUse2((short) 0); // as of J2735 2020 this should be set to 0 and is ignored - activeTim.setDoNotUse1((short) 0); // as of J2735 2020 this should be set to 0 and is ignored - activeTim.setDoNotUse4((short) 0); // as of J2735 2020 this should be set to 0 and is ignored - activeTim.setDoNotUse3((short) 0); // as of J2735 2020 this should be set to 0 and is ignored - activeTim.setUrl(rs.getString("URL")); + activeTim = setPropertiesForActiveTim(rs, new TimUpdateModel()); int frameTypeValue = rs.getInt("FRAME_TYPE"); if (!rs.wasNull() && frameTypeValue >= 0 && frameTypeValue < TravelerInfoType.values().length) { @@ -1593,4 +1473,66 @@ public ResponseEntity MarkForDeletion(@PathVariable Long activeTimId) { } return ResponseEntity.ok(success); } + + public TimUpdateModel setPropertiesForActiveTim(ResultSet rs, TimUpdateModel activeTim) throws SQLException { + activeTim.setActiveTimId(rs.getLong("ACTIVE_TIM_ID")); + activeTim.setTimId(rs.getLong("TIM_ID")); + activeTim.setDirection(rs.getString("DIRECTION")); + activeTim.setStartDateTime(rs.getString("TIM_START")); + activeTim.setEndDateTime(rs.getString("TIM_END")); + activeTim.setExpirationDateTime(rs.getString("EXPIRATION_DATE")); + activeTim.setSatRecordId(rs.getString("SAT_RECORD_ID")); + activeTim.setClientId(rs.getString("CLIENT_ID")); + activeTim.setRoute(rs.getString("ROUTE")); + + Coordinate startPoint = null; + Coordinate endPoint = null; + BigDecimal startLat = rs.getBigDecimal("START_LATITUDE"); + BigDecimal startLon = rs.getBigDecimal("START_LONGITUDE"); + if (!rs.wasNull()) { + startPoint = new Coordinate(startLat, startLon); + } + activeTim.setStartPoint(startPoint); + + BigDecimal endLat = rs.getBigDecimal("END_LATITUDE"); + BigDecimal endLon = rs.getBigDecimal("END_LONGITUDE"); + if (!rs.wasNull()) { + endPoint = new Coordinate(endLat, endLon); + } + activeTim.setEndPoint(endPoint); + + activeTim.setStartDate_Timestamp(rs.getTimestamp("TIM_START", UTCCalendar)); + activeTim.setEndDate_Timestamp(rs.getTimestamp("TIM_END", UTCCalendar)); + + // Tim properties + activeTim.setMsgCnt(rs.getInt("MSG_CNT")); + activeTim.setUrlB(rs.getString("URL_B")); + activeTim.setPacketId(rs.getString("PACKET_ID")); + + // Tim Type properties + activeTim.setTimTypeName(rs.getString("TIM_TYPE_NAME")); + activeTim.setTimTypeDescription(rs.getString("TIM_TYPE_DESCRIPTION")); + + // Region Properties + activeTim.setRegionId(rs.getInt("REGION_ID")); + activeTim.setAnchorLat(rs.getBigDecimal("ANCHOR_LAT")); + activeTim.setAnchorLong(rs.getBigDecimal("ANCHOR_LONG")); + + activeTim.setLaneWidth(rs.getBigDecimal("LANE_WIDTH")); + activeTim.setRegionDirection(rs.getString("REGION_DIRECTION")); + activeTim.setDirectionality(rs.getString("DIRECTIONALITY")); + activeTim.setClosedPath(rs.getBoolean("CLOSED_PATH")); + activeTim.setPathId(rs.getInt("PATH_ID")); + activeTim.setRegionDescription(rs.getString("REGION_DESCRIPTION")); + + // DataFrame properties + activeTim.setDataFrameId(rs.getInt("DATA_FRAME_ID")); + activeTim.setDurationTime(rs.getInt("DURATION_TIME")); + activeTim.setDoNotUse2((short) 0); // as of J2735 2020 this should be set to 0 and is ignored + activeTim.setDoNotUse1((short) 0); // as of J2735 2020 this should be set to 0 and is ignored + activeTim.setDoNotUse4((short) 0); // as of J2735 2020 this should be set to 0 and is ignored + activeTim.setDoNotUse3((short) 0); // as of J2735 2020 this should be set to 0 and is ignored + activeTim.setUrl(rs.getString("URL")); + return activeTim; + } } From 3816f143c008d43fa5bea3cf1ca39286fbf79104 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Fri, 7 Mar 2025 12:58:03 -0700 Subject: [PATCH 065/168] Update ode tags to 2025-q1 --- local-deployment/docker-compose.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/local-deployment/docker-compose.yml b/local-deployment/docker-compose.yml index b68e7e498..37ad144e7 100644 --- a/local-deployment/docker-compose.yml +++ b/local-deployment/docker-compose.yml @@ -36,7 +36,7 @@ services: entrypoint: ["/bin/sh", "kafka_init.sh"] ode: - image: usdotjpoode/jpo-ode:2024-q2 + image: usdotjpoode/jpo-ode:2025-q1 ports: - "8080:8080" - "9090:9090" @@ -70,7 +70,7 @@ services: max-file: "5" adm: - image: usdotjpoode/asn1_codec:2024-q2 + image: usdotjpoode/asn1_codec:2025-q1 environment: DOCKER_HOST_IP: ${DOCKER_HOST_IP} ACM_CONFIG_FILE: adm.properties @@ -88,7 +88,7 @@ services: restart: on-failure aem: - image: usdotjpoode/asn1_codec:2024-q2 + image: usdotjpoode/asn1_codec:2025-q1 environment: DOCKER_HOST_IP: ${DOCKER_HOST_IP} ACM_CONFIG_FILE: aem.properties @@ -107,7 +107,7 @@ services: # Note: the SDX does not accept unsigned data, so this is commented out for now # sdw_depositor: - # image: usdotjpoode/jpo-sdw-depositor:2024-q2 + # image: usdotjpoode/jpo-sdw-depositor:2025-q1 # environment: # DOCKER_HOST_IP: ${DOCKER_HOST_IP} # SDW_EMAIL_LIST: test@gmail.com From df786446d96dbb35ea089e8ebbfc9bae305bc7cc Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Wed, 12 Mar 2025 14:18:58 -0600 Subject: [PATCH 066/168] Remove unused resubmit method --- .../library/helpers/TimGenerationHelper.java | 71 ------------------- 1 file changed, 71 deletions(-) diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/TimGenerationHelper.java b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/TimGenerationHelper.java index 856257966..ff0489b29 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/TimGenerationHelper.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/TimGenerationHelper.java @@ -579,77 +579,6 @@ public List expireTimAndResubmitToOde(List activeTim return exceptions; } - /** - * Expires existing TIMs that utilize geometry instead of start/end points and resubmits them to the ODE - * - * @param activeTimId TIM to resubmit - * @param allMps List of all mileposts for the active TIM - * @return Errors that occurred while processing the request - */ - public List expireTimAndResubmitToOdeGeometry(Long activeTimID, List allMps) { - List exceptions = new ArrayList<>(); - if (activeTimID == null) { - utility.logWithDate("No active TIM found to resubmit to ODE. Returning...", TimGenerationHelper.class); - return exceptions; - } - - try { - var tum = activeTimService.getUpdateModelFromActiveTimId(activeTimID); - - if (tum == null) { - exceptions.add(new ResubmitTimException(activeTimID, "Failed to get Update Model from active tim")); - } - if (!isValidTim(tum)) { - exceptions.add(new ResubmitTimException(activeTimID, - "Failed to generate valid Update Model from active tim")); - } - - if (tum.getLaneWidth() == null) { - tum.setLaneWidth(config.getDefaultLaneWidth()); - } else { - // Database has lane width as cm, but ODE takes m - tum.setLaneWidth(tum.getLaneWidth().divide(BigDecimal.valueOf(100))); - } - - List reduced_mps; - if (allMps.size() < 2) { - String exMsg = String.format( - "Unable to resubmit TIM, less than 2 mileposts found for Active_Tim %d", - tum.getActiveTimId()); - utility.logWithDate(exMsg); - exceptions.add(new ResubmitTimException(activeTimID, exMsg)); - } - Milepost firstPoint = allMps.get(0); - Milepost secondPoint = allMps.get(1); - - // reduce the mileposts by removing straight away posts - var anchorMp = getAnchorPoint(firstPoint, secondPoint); - reduced_mps = milepostReduction.applyMilepostReductionAlgorithm(allMps, config.getPathDistanceLimit()); - - OdeTravelerInformationMessage tim = getTim(tum, reduced_mps, allMps, anchorMp, false, true); - if (tim == null) { - String exMsg = String.format("Failed to instantiate TIM for active_tim_id %d", - tum.getActiveTimId()); - utility.logWithDate(exMsg); - exceptions.add(new ResubmitTimException(activeTimID, exMsg)); - } - WydotTravelerInputData timToSend = new WydotTravelerInputData(); - timToSend.setTim(tim); - var extraEx = sendTim(timToSend, tum, activeTimID, reduced_mps); - activeTimService.markForDeletion(activeTimID); - if (!extraEx.isEmpty()) { - exceptions.addAll(extraEx); - } - } catch (Exception ex) { - exceptions.add(new ResubmitTimException(activeTimID, ex.getMessage())); - } - if (!exceptions.isEmpty()) { - utility.logWithDate("Errors occurred while resubmitting TIMs: " + gson.toJson(exceptions), - TimGenerationHelper.class); - } - return exceptions; - } - public boolean isValidTim(TimUpdateModel tum) { // start point From 11f73c77fe62b1de8818877ae1ac36b6f1a077ff Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Wed, 12 Mar 2025 16:00:13 -0600 Subject: [PATCH 067/168] Remove unnecessary doNotUse references --- .../cvdatacontroller/controller/ActiveTimController.java | 4 ---- .../cvdatacontroller/controller/DataFrameController.java | 8 -------- .../com/trihydro/library/helpers/CreateBaseTimUtil.java | 4 ---- .../com/trihydro/library/helpers/JsonToJavaConverter.java | 4 ---- .../com/trihydro/library/helpers/TimGenerationHelper.java | 4 ---- 5 files changed, 24 deletions(-) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java index 4ed242070..9b029a016 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java @@ -1528,10 +1528,6 @@ public TimUpdateModel setPropertiesForActiveTim(ResultSet rs, TimUpdateModel act // DataFrame properties activeTim.setDataFrameId(rs.getInt("DATA_FRAME_ID")); activeTim.setDurationTime(rs.getInt("DURATION_TIME")); - activeTim.setDoNotUse2((short) 0); // as of J2735 2020 this should be set to 0 and is ignored - activeTim.setDoNotUse1((short) 0); // as of J2735 2020 this should be set to 0 and is ignored - activeTim.setDoNotUse4((short) 0); // as of J2735 2020 this should be set to 0 and is ignored - activeTim.setDoNotUse3((short) 0); // as of J2735 2020 this should be set to 0 and is ignored activeTim.setUrl(rs.getString("URL")); return activeTim; } diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/DataFrameController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/DataFrameController.java index f97cdf101..2c8c3950b 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/DataFrameController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/DataFrameController.java @@ -111,8 +111,6 @@ public ResponseEntity AddDataFrame(@RequestBody DataFrame dFrame, @PathVar for (String col : timDbTables.getDataFrameTable()) { if (col.equals("TIM_ID")) { sqlNullHandler.setLongOrNull(preparedStatement, fieldNum, timId); - } else if (col.equals("SSP_TIM_RIGHTS")) { - sqlNullHandler.setShortOrNull(preparedStatement, fieldNum, dFrame.getDoNotUse1()); } else if (col.equals("FRAME_TYPE")) { Integer ordinal = null; if (dFrame.getFrameType() != null) { @@ -123,12 +121,6 @@ public ResponseEntity AddDataFrame(@RequestBody DataFrame dFrame, @PathVar sqlNullHandler.setIntegerOrNull(preparedStatement, fieldNum, dFrame.getDurationTime()); } else if (col.equals("PRIORITY")) { sqlNullHandler.setIntegerOrNull(preparedStatement, fieldNum, dFrame.getPriority()); - } else if (col.equals("SSP_LOCATION_RIGHTS")) { - sqlNullHandler.setShortOrNull(preparedStatement, fieldNum, dFrame.getDoNotUse2()); - } else if (col.equals("SSP_MSG_TYPES")) { - sqlNullHandler.setShortOrNull(preparedStatement, fieldNum, dFrame.getDoNotUse4()); - } else if (col.equals("SSP_MSG_CONTENT")) { - sqlNullHandler.setShortOrNull(preparedStatement, fieldNum, dFrame.getDoNotUse3()); } else if (col.equals("CONTENT")) { sqlNullHandler.setStringOrNull(preparedStatement, fieldNum, dFrame.getContent()); } else if (col.equals("URL")) { diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CreateBaseTimUtil.java b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CreateBaseTimUtil.java index 68afd2472..52174c1f5 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CreateBaseTimUtil.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CreateBaseTimUtil.java @@ -59,10 +59,6 @@ public WydotTravelerInputData buildTim(WydotTim wydotTim, TimGenerationProps gen // set TIM Properties OdeTravelerInformationMessage.DataFrame dataFrame = new OdeTravelerInformationMessage.DataFrame(); - dataFrame.setDoNotUse1((short) 0); // as of J2735 2020 this should be set to 0 and is ignored - dataFrame.setDoNotUse2((short) 0); // as of J2735 2020 this should be set to 0 and is ignored - dataFrame.setDoNotUse3((short) 0); // as of J2735 2020 this should be set to 0 and is ignored - dataFrame.setDoNotUse4((short) 0); // as of J2735 2020 this should be set to 0 and is ignored // set TIM TimeStamp and StartDateTime to current time in UTC String nowAsISO = Instant.now().toString(); diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/JsonToJavaConverter.java b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/JsonToJavaConverter.java index 0b72b4f69..f251459c0 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/JsonToJavaConverter.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/JsonToJavaConverter.java @@ -536,8 +536,6 @@ else if (sequenceArrNode.get("item").get("text") != null) JsonNode startTimeNode = travelerDataFrame.get("startTime"); JsonNode durationNode = travelerDataFrame.get("durationTime"); JsonNode priorityNode = travelerDataFrame.get("priority"); - JsonNode doNotUse2Node = travelerDataFrame.get("doNotUse2"); - JsonNode doNotUse1Node = travelerDataFrame.get("doNotUse1"); LocalDate now = LocalDate.now(); LocalDate firstDay = now.with(firstDayOfYear()); @@ -555,8 +553,6 @@ else if (sequenceArrNode.get("item").get("text") != null) dataFrame.setStartDateTime(startDate.toString() + "Z"); dataFrame.setDurationTime(durationNode.asInt()); dataFrame.setPriority(priorityNode.asInt()); - dataFrame.setDoNotUse2((short) doNotUse2Node.asInt()); - dataFrame.setDoNotUse1((short) doNotUse1Node.asInt()); tim.setMsgCnt(timNode.get("msgCnt").asInt()); diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/TimGenerationHelper.java b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/TimGenerationHelper.java index 74a5972d9..116a6da1a 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/TimGenerationHelper.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/TimGenerationHelper.java @@ -739,13 +739,9 @@ private DataFrame getDataFrame(TimUpdateModel aTim, Milepost anchor, boolean res // DataFrame DataFrame df = new DataFrame(); - df.setDoNotUse1(aTim.getDoNotUse1()); df.setFrameType(aTim.getFrameType()); df.setMsgId(msgId); df.setPriority(5);// 0-7, 0 being least important, 7 being most - df.setDoNotUse2(aTim.getDoNotUse2()); - df.setDoNotUse4(aTim.getDoNotUse4()); - df.setDoNotUse3(aTim.getDoNotUse3()); if (aTim.getDfContent() != null) df.setContent(aTim.getDfContent().getStringValue()); df.setUrl(aTim.getUrl()); From 6578b21044aa54fc64fcc43591099733c8b7c804 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 13 Mar 2025 08:08:03 -0600 Subject: [PATCH 068/168] Update direction calculation, convertTmcTimTopicToJson methods to handle 2025-q1 OdeTimJson format --- .../library/helpers/JsonToJavaConverter.java | 214 +++++++++--------- 1 file changed, 110 insertions(+), 104 deletions(-) diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/JsonToJavaConverter.java b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/JsonToJavaConverter.java index f251459c0..124dc1c9e 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/JsonToJavaConverter.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/JsonToJavaConverter.java @@ -1,14 +1,17 @@ package com.trihydro.library.helpers; -import static java.time.temporal.TemporalAdjusters.firstDayOfYear; - import java.io.IOException; import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; +import static java.time.temporal.TemporalAdjusters.firstDayOfYear; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; +import java.util.Map; + +import org.springframework.stereotype.Component; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationFeature; @@ -17,8 +20,6 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import com.trihydro.library.model.ContentEnum; -import org.springframework.stereotype.Component; - import us.dot.its.jpo.ode.model.OdeLogMetadata; import us.dot.its.jpo.ode.model.OdeMsgMetadata.GeneratedBy; import us.dot.its.jpo.ode.model.OdeRequestMsgMetadata; @@ -30,7 +31,6 @@ import us.dot.its.jpo.ode.plugin.SnmpProtocol; import us.dot.its.jpo.ode.plugin.j2735.J2735SpecialVehicleExtensions; import us.dot.its.jpo.ode.plugin.j2735.J2735SupplementalVehicleExtensions; -import us.dot.its.jpo.ode.plugin.j2735.J2735VehicleSafetyExtensions; 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.OdeTravelerInformationMessage.DataFrame.Region; @@ -242,7 +242,17 @@ else if (reverse != null) } if (regionDirectionNode != null) { - region.setDirection(mapper.treeToValue(regionDirectionNode, String.class)); + var direction = ""; + Iterator> fields = regionDirectionNode.fields(); + while (fields.hasNext()) { + Map.Entry field = fields.next(); + var directionBool = field.getValue().toString(); + if ("true".equals(directionBool)) + direction += "1"; + else + direction += "0"; + } + region.setDirection(direction); } JsonNode descriptionNode = regionNode.get("description"); @@ -266,7 +276,7 @@ public OdeTimPayload convertTimPayloadJsonToJava(String value) { try { OdeTravelerInformationMessage.DataFrame[] dataFrames = new OdeTravelerInformationMessage.DataFrame[1]; OdeTravelerInformationMessage.DataFrame dataFrame = new OdeTravelerInformationMessage.DataFrame(); - List regions = new ArrayList(); + List regions = new ArrayList<>(); // JsonNode payloadNode = JsonUtils.getJsonNode(value, "payload"); JsonNode timNode = JsonUtils.getJsonNode(value, "payload").get("data").get("MessageFrame").get("value") @@ -390,10 +400,10 @@ public OdeTravelerInformationMessage.DataFrame.Region.Path GetPathData(JsonNode if (nodesNode == null) return null; - JsonNode nodeXYArrNode = isXy ? nodesNode.get("NodeXY") : nodesNode.get("NodeLL"); + JsonNode nodeXYArrNode = isXy ? nodesNode.get("NodeXY") : nodesNode; OdeTravelerInformationMessage.DataFrame.Region.Path path = new OdeTravelerInformationMessage.DataFrame.Region.Path(); - List nodeXYs = new ArrayList(); - OdeTravelerInformationMessage.NodeXY nodeXY = new OdeTravelerInformationMessage.NodeXY(); + List nodeXYs = new ArrayList<>(); + OdeTravelerInformationMessage.NodeXY nodeXY; if (nodeXYArrNode.isArray()) { for (final JsonNode objNode : nodeXYArrNode) { @@ -470,123 +480,119 @@ public OdeTimPayload convertTmcTimTopicJsonToJava(String value) { OdeTimPayload odeTimPayload = null; try { - OdeTravelerInformationMessage.DataFrame[] dataFrames = new OdeTravelerInformationMessage.DataFrame[1]; + List dataFrames = new ArrayList<>(); OdeTravelerInformationMessage.DataFrame dataFrame = new OdeTravelerInformationMessage.DataFrame(); - List regions = new ArrayList(); - - // JsonNode timNode = JsonUtils.getJsonNode(value, - // "payload").get("data").get("MessageFrame").get("value") - // .get("TravelerInformation"); - JsonNode timNode = JsonUtils.getJsonNode(value, "payload").findValue("TravelerInformation"); - JsonNode travelerDataFrame = timNode.findValue("TravelerDataFrame"); - - JsonNode sequenceArrNode = null; - JsonNode contentNode = travelerDataFrame.get("content"); - if (contentNode.has(ContentEnum.advisory.getStringValue())) { - sequenceArrNode = contentNode.get(ContentEnum.advisory.getStringValue()).get("SEQUENCE"); - dataFrame.setContent(ContentEnum.advisory.getStringValue()); - } else if (contentNode.has(ContentEnum.speedLimit.getStringValue())) { - sequenceArrNode = contentNode.get(ContentEnum.speedLimit.getStringValue()).get("SEQUENCE"); - dataFrame.setContent(ContentEnum.speedLimit.getStringValue()); - } else if (contentNode.has(ContentEnum.exitService.getStringValue())) { - sequenceArrNode = contentNode.get(ContentEnum.exitService.getStringValue()).get("SEQUENCE"); - dataFrame.setContent(ContentEnum.exitService.getStringValue()); - } else if (contentNode.has(ContentEnum.genericSign.getStringValue())) { - sequenceArrNode = contentNode.get(ContentEnum.genericSign.getStringValue()).get("SEQUENCE"); - dataFrame.setContent(ContentEnum.genericSign.getStringValue()); - } else if (contentNode.has(ContentEnum.workZone.getStringValue())) { - sequenceArrNode = contentNode.get(ContentEnum.workZone.getStringValue()).get("SEQUENCE"); - dataFrame.setContent(ContentEnum.workZone.getStringValue()); - } - - List itemsList = new ArrayList(); - String item = null; - if (sequenceArrNode != null && sequenceArrNode.isArray()) { - for (final JsonNode objNode : sequenceArrNode) { - if (objNode.get("item").get("itis") != null) - item = mapper.treeToValue(objNode.get("item").get("itis"), String.class); - else if (objNode.get("item").get("text") != null) - item = mapper.treeToValue(objNode.get("item").get("text"), String.class); + List regions = new ArrayList<>(); - itemsList.add(item); - } - } - - // ADD NON ARRAY ELEMENT - if (sequenceArrNode != null && !sequenceArrNode.isArray()) { - if (sequenceArrNode.get("item").get("itis") != null) - item = mapper.treeToValue(sequenceArrNode.get("item").get("itis"), String.class); - else if (sequenceArrNode.get("item").get("text") != null) - item = mapper.treeToValue(sequenceArrNode.get("item").get("text"), String.class); - - itemsList.add(item); - } - - // TravelerInfoType.valueOf(); - JsonNode frameTypeNode = travelerDataFrame.get("frameType"); - if (frameTypeNode != null) { - if (frameTypeNode.fieldNames().hasNext()) { - TravelerInfoType frameType = TravelerInfoType.valueOf(frameTypeNode.fieldNames().next()); - if (frameType != null) { - dataFrame.setFrameType(frameType); - } - } + OdeTravelerInformationMessage tim = new OdeTravelerInformationMessage(); + JsonNode timNode = JsonUtils.getJsonNode(value, "payload").findValue("data"); + tim.setMsgCnt(timNode.get("msgCnt").asInt()); + JsonNode packetIDNode = timNode.get("packetID"); + if (packetIDNode != null) { + tim.setPacketID(packetIDNode.asText()); } - JsonNode startTimeNode = travelerDataFrame.get("startTime"); - JsonNode durationNode = travelerDataFrame.get("durationTime"); - JsonNode priorityNode = travelerDataFrame.get("priority"); - LocalDate now = LocalDate.now(); LocalDate firstDay = now.with(firstDayOfYear()); - OdeTravelerInformationMessage tim = new OdeTravelerInformationMessage(); - JsonNode timeStampNode = timNode.get("timeStamp"); if (timeStampNode != null) { LocalDateTime timeStampDate = firstDay.atStartOfDay().plus(timeStampNode.asInt(), ChronoUnit.MINUTES); tim.setTimeStamp(timeStampDate.toString() + "Z"); } - LocalDateTime startDate = firstDay.atStartOfDay().plus(startTimeNode.asInt(), ChronoUnit.MINUTES); + JsonNode travelerDataFrameArray = timNode.findValue("dataFrames"); + for (final JsonNode travelerDataFrame : travelerDataFrameArray) { + JsonNode sequenceArrNode = null; + JsonNode contentNode = travelerDataFrame.get("content"); + if (contentNode.has(ContentEnum.advisory.getStringValue())) { + sequenceArrNode = contentNode.get("advisory"); + dataFrame.setContent(ContentEnum.advisory.getStringValue()); + } else if (contentNode.has(ContentEnum.speedLimit.getStringValue())) { + sequenceArrNode = contentNode.get("speedLimit"); + dataFrame.setContent(ContentEnum.speedLimit.getStringValue()); + } else if (contentNode.has(ContentEnum.exitService.getStringValue())) { + sequenceArrNode = contentNode.get("exitService"); + dataFrame.setContent(ContentEnum.exitService.getStringValue()); + } else if (contentNode.has(ContentEnum.genericSign.getStringValue())) { + sequenceArrNode = contentNode.get("genericSign"); + dataFrame.setContent(ContentEnum.genericSign.getStringValue()); + } else if (contentNode.has(ContentEnum.workZone.getStringValue())) { + sequenceArrNode = contentNode.get("workZone"); + dataFrame.setContent(ContentEnum.workZone.getStringValue()); + } - dataFrame.setStartDateTime(startDate.toString() + "Z"); - dataFrame.setDurationTime(durationNode.asInt()); - dataFrame.setPriority(priorityNode.asInt()); + List itemsList = new ArrayList<>(); + String item = null; + if (sequenceArrNode != null && sequenceArrNode.isArray()) { + for (final JsonNode objNode : sequenceArrNode) { + if (objNode.get("item").get("itis") != null) + item = mapper.treeToValue(objNode.get("item").get("itis"), String.class); + else if (objNode.get("item").get("text") != null) + item = mapper.treeToValue(objNode.get("item").get("text"), String.class); + if (!itemsList.contains(item)) + itemsList.add(item); + } + } - tim.setMsgCnt(timNode.get("msgCnt").asInt()); + // ADD NON ARRAY ELEMENT + if (sequenceArrNode != null && !sequenceArrNode.isArray()) { + if (sequenceArrNode.get("item").get("itis") != null) + item = mapper.treeToValue(sequenceArrNode.get("item").get("itis"), String.class); + else if (sequenceArrNode.get("item").get("text") != null) + item = mapper.treeToValue(sequenceArrNode.get("item").get("text"), String.class); - JsonNode packetIDNode = timNode.get("packetID"); - if (packetIDNode != null) { - tim.setPacketID(packetIDNode.asText()); - } + itemsList.add(item); + } - String[] items = new String[itemsList.size()]; - items = itemsList.toArray(items); + // TravelerInfoType.valueOf(); + JsonNode frameTypeNode = travelerDataFrame.get("frameType"); + if (frameTypeNode != null) { + if (frameTypeNode.fieldNames().hasNext()) { + TravelerInfoType frameType = TravelerInfoType.valueOf(frameTypeNode.fieldNames().next()); + if (frameType != null) { + dataFrame.setFrameType(frameType); + } + } + } - JsonNode geographicalPathNode = travelerDataFrame.findValue("GeographicalPath"); + JsonNode startTimeNode = travelerDataFrame.get("startTime"); + JsonNode durationNode = travelerDataFrame.get("durationTime"); + JsonNode priorityNode = travelerDataFrame.get("priority"); - // geographicalPathNode may be an object or an array; if it is an object, treat - // it as a region - if (geographicalPathNode.isObject()) { - // single region - JsonNode regionNode = geographicalPathNode; - Region region = getRegion(regionNode); - regions.add(region); - } else if (geographicalPathNode.isArray()) { - // multiple regions - for (final JsonNode regionNode : geographicalPathNode) { + LocalDateTime startDate = firstDay.atStartOfDay().plus(startTimeNode.asInt(), ChronoUnit.MINUTES); + + dataFrame.setStartDateTime(startDate.toString() + "Z"); + dataFrame.setDurationTime(durationNode.asInt()); + dataFrame.setPriority(priorityNode.asInt()); + + String[] items = new String[itemsList.size()]; + items = itemsList.toArray(items); + + JsonNode geographicalPathNode = travelerDataFrame.findValue("regions"); + + // geographicalPathNode may be an object or an array; if it is an object, treat + // it as a region + if (geographicalPathNode.isObject()) { + // single region + JsonNode regionNode = geographicalPathNode; Region region = getRegion(regionNode); regions.add(region); + } else if (geographicalPathNode.isArray()) { + // multiple regions + for (final JsonNode regionNode : geographicalPathNode) { + Region region = getRegion(regionNode); + regions.add(region); + } + } else { + System.out.println("warning: geographicalPathNode is not an object or an array"); } - } else { - System.out.println("warning: geographicalPathNode is not an object or an array"); - } - dataFrame.setRegions(regions.toArray(new OdeTravelerInformationMessage.DataFrame.Region[regions.size()])); - dataFrame.setItems(items); - dataFrames[0] = dataFrame; - tim.setDataframes(dataFrames); + dataFrame.setRegions(regions.toArray(OdeTravelerInformationMessage.DataFrame.Region[]::new)); + dataFrame.setItems(items); + dataFrames.add(dataFrame); + } + tim.setDataframes(dataFrames.toArray(OdeTravelerInformationMessage.DataFrame[]::new)); odeTimPayload = new OdeTimPayload(); odeTimPayload.setData(tim); } catch (IOException e) { From 7c24bfd52319f09117ded9c286abfedf9ac9ddb9 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 13 Mar 2025 08:08:10 -0600 Subject: [PATCH 069/168] Remove unused imports --- .../com/trihydro/library/helpers/JsonToJavaConverterTest.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/cv-data-service-library/src/test/java/com/trihydro/library/helpers/JsonToJavaConverterTest.java b/cv-data-service-library/src/test/java/com/trihydro/library/helpers/JsonToJavaConverterTest.java index 131c96bc0..e89ca7501 100644 --- a/cv-data-service-library/src/test/java/com/trihydro/library/helpers/JsonToJavaConverterTest.java +++ b/cv-data-service-library/src/test/java/com/trihydro/library/helpers/JsonToJavaConverterTest.java @@ -7,8 +7,6 @@ import java.nio.file.Path; import java.nio.file.Paths; -import com.fasterxml.jackson.databind.JsonNode; - import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -22,8 +20,6 @@ import us.dot.its.jpo.ode.model.ReceivedMessageDetails; import us.dot.its.jpo.ode.model.RxSource; import us.dot.its.jpo.ode.model.SerialId; -import us.dot.its.jpo.ode.plugin.j2735.J2735SupplementalVehicleExtensions; -import us.dot.its.jpo.ode.plugin.j2735.J2735VehicleSafetyExtensions; 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.OdeTravelerInformationMessage.DataFrame.Region.Circle; From cf2b871a0c4a0d477f74c3408d00027bd789312b Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 13 Mar 2025 08:08:27 -0600 Subject: [PATCH 070/168] Update construction test data to match OdeTimJson new format --- .../src/test/resources/tim_construction.json | 196 +++++----- .../tim_construction_MultipleRegions.json | 337 ++++++++++-------- 2 files changed, 299 insertions(+), 234 deletions(-) diff --git a/cv-data-service-library/src/test/resources/tim_construction.json b/cv-data-service-library/src/test/resources/tim_construction.json index 0b721d01d..8385e897d 100644 --- a/cv-data-service-library/src/test/resources/tim_construction.json +++ b/cv-data-service-library/src/test/resources/tim_construction.json @@ -28,90 +28,116 @@ "odeTimStartDateTime": "2021-03-04T00:00:00.000Z", "odeReceivedAt": "2021-03-23T18:24:18.438Z" }, - "payload": { - "data": { - "MessageFrame": { - "messageId": 31, - "value": { - "TravelerInformation": { - "timeStamp": 117744, - "packetID": "59CE5322A49CED33CB", - "urlB": null, - "dataFrames": { - "TravelerDataFrame": { - "regions": { - "GeographicalPath": { - "closedPath": { "false": "" }, - "anchor": { "lat": 417732928, "long": -1071000312 }, - "name": "I_I 80_SAT-BC1AC5E4_RW_24869%BUFF0-0", - "laneWidth": 5000, - "directionality": { "both": "" }, - "description": { - "path": { - "offset": { - "ll": { - "nodes": { - "NodeLL": [ - { "delta": { "node-LL1": { "lon": 0, "lat": 0 } } }, - { - "delta": { - "node-LL4": { "lon": 115529, "lat": -16624 } - } - }, - { - "delta": { - "node-LL4": { "lon": 39044, "lat": 1521 } - } - }, - { - "delta": { - "node-LL4": { "lon": 56228, "lat": 11450 } - } - } - ] - } + "payload": { + "data": { + "msgCnt": 1, + "timeStamp": 117744, + "packetID": "59CE5322A49CED33CB", + "urlB": "null", + "dataFrames": [ + { + "doNotUse1": 0, + "frameType": "advisory", + "msgId": { + "roadSignID": { + "position": { "lat": 417732928, "long": -1071000312 }, + "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" + } + }, + "durationTime": 32000, + "startYear": 2021, + "startTime": 89280, + "priority": 5, + "doNotUse2": 0, + "regions": [ + { + "name": "I_I 80_SAT-BC1AC5E4_RW_24869%BUFF0-0", + "id": { + "region": 0, + "id": 0 + }, + "anchor": { "lat": 417732928, "long": -1071000312 }, + "laneWidth": 5000, + "directionality": "both", + "closedPath": false, + "direction": { + "from000-0to022-5degrees": false, + "from022-5to045-0degrees": false, + "from045-0to067-5degrees": false, + "from067-5to090-0degrees": true, + "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": { + "path": { + "scale": 0, + "offset": { + "ll": { + "nodes": [ + { "delta": { "node-LL1": { "lon": 0, "lat": 0 } } }, + { + "delta": { + "node-LL4": { "lon": 115529, "lat": -16624 } } }, - "scale": 0 - } - }, - "id": { "id": 0, "region": 0 }, - "direction": "0001100000000000" - } - }, - "durationTime": 32000, - "doNotUse3": 0, - "doNotUse4": 0, - "startYear": 2021, - "msgId": { - "roadSignID": { - "viewAngle": 1111111111111111, - "mutcdCode": { "warning": "" }, - "position": { "lat": 417732928, "long": -1071000312 } - } - }, - "priority": 5, - "content": { - "workZone": { - "SEQUENCE": [ - { "item": { "itis": 1537 } }, - { "item": { "itis": 12554 } }, - { "item": { "itis": 8728 } } - ] - } - }, - "url": null, - "doNotUse1": 0, - "doNotUse2": 0, - "frameType": { "advisory": "" }, - "startTime": 89280 - } - }, - "msgCnt": 1 - } - } - } - }, - "dataType": "TravelerInformation" - } -} + { + "delta": { + "node-LL4": { "lon": 39044, "lat": 1521 } + } + }, + { + "delta": { + "node-LL4": { "lon": 56228, "lat": 11450 } + } + } + ] + } + } + } + } + } + ], + "doNotUse3": 0, + "doNotUse4": 0, + "content": { + "workZone": [ + { "item": { "itis": 1537 } }, + { "item": { "itis": 12554 } }, + { "item": { "itis": 8728 } } + ] + }, + "url": "null" + } + ] + }, + "dataType": "us.dot.its.jpo.ode.plugin.j2735.travelerinformation.TravelerInformation" + } +} \ No newline at end of file diff --git a/cv-data-service-library/src/test/resources/tim_construction_MultipleRegions.json b/cv-data-service-library/src/test/resources/tim_construction_MultipleRegions.json index 2d04c77a7..2b0d145ab 100644 --- a/cv-data-service-library/src/test/resources/tim_construction_MultipleRegions.json +++ b/cv-data-service-library/src/test/resources/tim_construction_MultipleRegions.json @@ -1,157 +1,196 @@ { - "metadata": { - "request": { - "ode": { "verb": "POST", "version": 3 }, - "sdw": { - "recordId": "BC1AC5E4", - "serviceRegion": { - "nwCorner": { "latitude": 41.77329283, "longitude": -107.1000312 }, - "seCorner": { "latitude": 41.77163046, "longitude": -107.07895106 } - }, - "ttl": "oneyear" - } - }, - "recordGeneratedBy": "TMC", - "schemaVersion": 6, - "payloadType": "us.dot.its.jpo.ode.model.OdeTimPayload", - "odePacketID": "59CE5322A49CED33CB", - "serialId": { - "recordId": 0, - "serialNumber": 917, - "streamId": "9fa59341-9cab-403e-8306-6876238e9fda", - "bundleSize": 1, - "bundleId": 917 + "metadata": { + "request": { + "ode": { "verb": "POST", "version": 3 }, + "sdw": { + "recordId": "BC1AC5E4", + "serviceRegion": { + "nwCorner": { "latitude": 41.77329283, "longitude": -107.1000312 }, + "seCorner": { "latitude": 41.77163046, "longitude": -107.07895106 } }, - "sanitized": false, - "recordGeneratedAt": "2021-03-23T18:24:18.410648Z", - "maxDurationTime": 32000, - "odeTimStartDateTime": "2021-03-04T00:00:00.000Z", - "odeReceivedAt": "2021-03-23T18:24:18.438Z" + "ttl": "oneyear" + } + }, + "recordGeneratedBy": "TMC", + "schemaVersion": 6, + "payloadType": "us.dot.its.jpo.ode.model.OdeTimPayload", + "odePacketID": "59CE5322A49CED33CB", + "serialId": { + "recordId": 0, + "serialNumber": 917, + "streamId": "9fa59341-9cab-403e-8306-6876238e9fda", + "bundleSize": 1, + "bundleId": 917 }, - "payload": { - "data": { - "MessageFrame": { - "messageId": 31, - "value": { - "TravelerInformation": { - "timeStamp": 117744, - "packetID": "59CE5322A49CED33CB", - "urlB": null, - "dataFrames": { - "TravelerDataFrame": { - "regions": { - "GeographicalPath": [ - { - "closedPath": { "false": "" }, - "anchor": { "lat": 417732928, "long": -1071000312 }, - "name": "I_I 80_SAT-BC1AC5E4_RW_24869%BUFF0-0", - "laneWidth": 5000, - "directionality": { "both": "" }, - "description": { - "path": { - "offset": { - "ll": { - "nodes": { - "NodeLL": [ - { "delta": { "node-LL1": { "lon": 0, "lat": 0 } } }, - { - "delta": { - "node-LL4": { "lon": 115529, "lat": -16624 } - } - }, - { - "delta": { - "node-LL4": { "lon": 39044, "lat": 1521 } - } - }, - { - "delta": { - "node-LL4": { "lon": 56228, "lat": 11450 } - } - } - ] - } - } - }, - "scale": 0 - } - }, - "id": { "id": 0, "region": 0 }, - "direction": "0001100000000000" - }, - { - "closedPath": { "false": "" }, - "anchor": { "lat": 417732928, "long": -1071000312 }, - "name": "I_I 80_SAT-BC1AC5E4_RW_24869%BUFF0-0", - "laneWidth": 5000, - "directionality": { "both": "" }, - "description": { - "path": { - "offset": { - "ll": { - "nodes": { - "NodeLL": [ - { "delta": { "node-LL1": { "lon": 0, "lat": 0 } } }, - { - "delta": { - "node-LL4": { "lon": 115529, "lat": -16624 } - } - }, - { - "delta": { - "node-LL4": { "lon": 39044, "lat": 1521 } - } - }, - { - "delta": { - "node-LL4": { "lon": 56228, "lat": 11450 } - } - } - ] - } - } - }, - "scale": 0 - } - }, - "id": { "id": 0, "region": 0 }, - "direction": "0001100000000000" - } - ] - }, - "durationTime": 32000, - "doNotUse3": 1, - "doNotUse4": 1, - "startYear": 2021, - "msgId": { - "roadSignID": { - "viewAngle": 1111111111111111, - "mutcdCode": { "warning": "" }, - "position": { "lat": 417732928, "long": -1071000312 } - } - }, - "priority": 5, - "content": { - "workZone": { - "SEQUENCE": [ - { "item": { "itis": 1537 } }, - { "item": { "itis": 12554 } }, - { "item": { "itis": 8728 } } - ] - } - }, - "url": null, - "doNotUse1": 1, - "doNotUse2": 1, - "frameType": { "advisory": "" }, - "startTime": 89280 - } + "sanitized": false, + "recordGeneratedAt": "2021-03-23T18:24:18.410648Z", + "maxDurationTime": 32000, + "odeTimStartDateTime": "2021-03-04T00:00:00.000Z", + "odeReceivedAt": "2021-03-23T18:24:18.438Z" + }, + "payload": { + "data": { + "msgCnt": 1, + "timeStamp": 117744, + "packetID": "59CE5322A49CED33CB", + "urlB": "null", + "dataFrames": [ + { + "doNotUse1": 0, + "frameType": "advisory", + "msgId": { + "roadSignID": { + "position": { "lat": 417732928, "long": -1071000312 }, + "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" + } + }, + "durationTime": 32000, + "startYear": 2021, + "startTime": 89280, + "priority": 5, + "doNotUse2": 0, + "regions": [ + { + "closedPath": false, + "anchor": { "lat": 417732928, "long": -1071000312 }, + "name": "I_I 80_SAT-BC1AC5E4_RW_24869%BUFF0-0", + "laneWidth": 5000, + "directionality": "both", + "description": { + "path": { + "offset": { + "ll": { + "nodes": [ + { "delta": { "node-LL1": { "lon": 0, "lat": 0 } } }, + { + "delta": { + "node-LL4": { "lon": 115529, "lat": -16624 } + } + }, + { + "delta": { + "node-LL4": { "lon": 39044, "lat": 1521 } + } }, - "msgCnt": 1 + { + "delta": { + "node-LL4": { "lon": 56228, "lat": 11450 } + } + } + ] } + }, + "scale": 0 } + }, + "id": { "id": 0, "region": 0 }, + "direction": { + "from000-0to022-5degrees": false, + "from022-5to045-0degrees": false, + "from045-0to067-5degrees": false, + "from067-5to090-0degrees": true, + "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 + } + }, + { + "id": { + "region": 0, + "id": 0 + }, + "anchor": { "lat": 417732928, "long": -1071000312 }, + "name": "I_I 80_SAT-BC1AC5E4_RW_24869%BUFF0-0", + "laneWidth": 5000, + "directionality": "both", + "closedPath": false, + "direction": { + "from000-0to022-5degrees": false, + "from022-5to045-0degrees": false, + "from045-0to067-5degrees": false, + "from067-5to090-0degrees": true, + "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": { + "path": { + "scale": 0, + "offset": { + "ll": { + "nodes": [ + { "delta": { "node-LL1": { "lon": 0, "lat": 0 } } }, + { + "delta": { + "node-LL4": { "lon": 115529, "lat": -16624 } + } + }, + { + "delta": { + "node-LL4": { "lon": 39044, "lat": 1521 } + } + }, + { + "delta": { + "node-LL4": { "lon": 56228, "lat": 11450 } + } + } + ] + } + } + } + } } - }, - "dataType": "TravelerInformation" - } + ], + "doNotUse3": 0, + "doNotUse4": 0, + "content": { + "workZone": [ + { "item": { "itis": 1537 } }, + { "item": { "itis": 12554 } }, + { "item": { "itis": 8728 } } + ] + }, + "url": "null" + } + ] + }, + "dataType": "us.dot.its.jpo.ode.plugin.j2735.travelerinformation.TravelerInformation" + } } From 79f21e8dd06c30d312bc58d6f86f8186577814ae Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 13 Mar 2025 08:08:42 -0600 Subject: [PATCH 071/168] Updating parking test data to match updated OdeTimJson format --- .../src/test/resources/tim_parking.json | 179 +++++----- .../tim_parking_MultipleRegions.json | 322 ++++++++++-------- 2 files changed, 281 insertions(+), 220 deletions(-) diff --git a/cv-data-service-library/src/test/resources/tim_parking.json b/cv-data-service-library/src/test/resources/tim_parking.json index a4c3ad27f..519b60e3b 100644 --- a/cv-data-service-library/src/test/resources/tim_parking.json +++ b/cv-data-service-library/src/test/resources/tim_parking.json @@ -29,84 +29,105 @@ "odeReceivedAt": "2021-03-23T19:20:48.177Z" }, "payload": { - "data": { - "MessageFrame": { - "messageId": 31, - "value": { - "TravelerInformation": { - "timeStamp": 117800, - "packetID": "AE394DB5A033905B26", - "urlB": null, - "dataFrames": { - "TravelerDataFrame": { - "regions": { - "GeographicalPath": { - "closedPath": { "false": "" }, - "anchor": { "lat": 410985067, "long": -1051331761 }, - "name": "I_I 80_SAT-1AF9F730_P_68-0", - "laneWidth": 5000, - "directionality": { "both": "" }, - "description": { - "path": { - "offset": { - "ll": { - "nodes": { - "NodeLL": [ - { "delta": { "node-LL1": { "lon": 0, "lat": 0 } } }, - { - "delta": { - "node-LL5": { "lon": 133699, "lat": 163 } - } - }, - { - "delta": { - "node-LL4": { "lon": 56885, "lat": -5703 } - } - } - ] - } - } + "data": { + "msgCnt": 1, + "timeStamp": 117800, + "packetID": "AE394DB5A033905B26", + "urlB": null, + "dataFrames": [ + { + "doNotUse1": 0, + "frameType": "advisory", + "msgId": { + "roadSignID": { + "position": { "lat": 417732928, "long": -1071000312 }, + "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" + } + }, + "durationTime": 32000, + "startYear": 2021, + "startTime": 89280, + "priority": 5, + "doNotUse2": 0, + "regions": [ + { + "name": "I_I 25_SAT-A5FB00B7_VSL_V004988-0", + "id": { + "region": 0, + "id": 0 + }, + "anchor": { "lat": 417732928, "long": -1071000312 }, + "laneWidth": 5000, + "directionality": "both", + "closedPath": false, + "direction": { + "from000-0to022-5degrees": false, + "from022-5to045-0degrees": false, + "from045-0to067-5degrees": false, + "from067-5to090-0degrees": true, + "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": { + "path": { + "scale": 0, + "offset": { + "ll": { + "nodes": [ + { "node-LL1": { "lon": 0, "lat": 0 } }, + { + "node-LL5": { "lon": 133699, "lat": 163 } }, - "scale": 0 - } - }, - "id": { "id": 0, "region": 0 }, - "direction": "0001100000000000" - } - }, - "durationTime": 120, - "doNotUse3": 1, - "doNotUse4": 1, - "startYear": 2021, - "msgId": { - "roadSignID": { - "viewAngle": 1111111111111111, - "mutcdCode": { "warning": "" }, - "position": { "lat": 410985067, "long": -1051331761 } - } - }, - "priority": 5, - "content": { - "exitService": { - "SEQUENCE": [ - { "item": { "itis": 4104 } }, - { "item": { "itis": 11794 } }, - { "item": { "text": 345 } } - ] - } - }, - "url": null, - "doNotUse1": 1, - "doNotUse2": 1, - "frameType": { "advisory": "" }, - "startTime": 117800 - } - }, - "msgCnt": 1 - } - } - } - }, - "dataType": "TravelerInformation" - } + { + "node-LL4": { "lon": 56885, "lat": -5703 } + } ] + } + } + } + } + } + ], + "doNotUse3": 0, + "doNotUse4": 0, + "content": { + "exitService": [ + { "item": { "itis": 4104 } }, + { "item": { "itis": 11794 } }, + { "item": { "text": 345 } } + ] + }, + "url": "null" + } + ] + }, + "dataType": "us.dot.its.jpo.ode.plugin.j2735.travelerinformation.TravelerInformation" + } } diff --git a/cv-data-service-library/src/test/resources/tim_parking_MultipleRegions.json b/cv-data-service-library/src/test/resources/tim_parking_MultipleRegions.json index ed2a9ce79..594adfcc4 100644 --- a/cv-data-service-library/src/test/resources/tim_parking_MultipleRegions.json +++ b/cv-data-service-library/src/test/resources/tim_parking_MultipleRegions.json @@ -1,147 +1,187 @@ { - "metadata": { - "request": { - "ode": { "verb": "POST", "version": 3 }, - "sdw": { - "recordId": "1AF9F730", - "serviceRegion": { - "nwCorner": { "latitude": 41.09852308, "longitude": -105.13317609 }, - "seCorner": { "latitude": 41.09795279, "longitude": -105.11411777 } - }, - "ttl": "oneday" - } - }, - "recordGeneratedBy": "TMC", - "schemaVersion": 6, - "payloadType": "us.dot.its.jpo.ode.model.OdeTimPayload", - "odePacketID": "AE394DB5A033905B26", - "serialId": { - "recordId": 0, - "serialNumber": 922, - "streamId": "9fa59341-9cab-403e-8306-6876238e9fda", - "bundleSize": 1, - "bundleId": 922 + "metadata": { + "request": { + "ode": { "verb": "POST", "version": 3 }, + "sdw": { + "recordId": "1AF9F730", + "serviceRegion": { + "nwCorner": { "latitude": 41.09852308, "longitude": -105.13317609 }, + "seCorner": { "latitude": 41.09795279, "longitude": -105.11411777 } }, - "sanitized": false, - "recordGeneratedAt": "2021-03-23T19:20:48.130840Z", - "maxDurationTime": 120, - "odeTimStartDateTime": "2021-03-23T19:20:47.118Z", - "odeReceivedAt": "2021-03-23T19:20:48.177Z" + "ttl": "oneday" + } + }, + "recordGeneratedBy": "TMC", + "schemaVersion": 6, + "payloadType": "us.dot.its.jpo.ode.model.OdeTimPayload", + "odePacketID": "AE394DB5A033905B26", + "serialId": { + "recordId": 0, + "serialNumber": 922, + "streamId": "9fa59341-9cab-403e-8306-6876238e9fda", + "bundleSize": 1, + "bundleId": 922 }, - "payload": { - "data": { - "MessageFrame": { - "messageId": 31, - "value": { - "TravelerInformation": { - "timeStamp": 117800, - "packetID": "AE394DB5A033905B26", - "urlB": null, - "dataFrames": { - "TravelerDataFrame": { - "regions": { - "GeographicalPath": [ - { - "closedPath": { "false": "" }, - "anchor": { "lat": 410985067, "long": -1051331761 }, - "name": "I_I 80_SAT-1AF9F730_P_68-0", - "laneWidth": 5000, - "directionality": { "both": "" }, - "description": { - "path": { - "offset": { - "ll": { - "nodes": { - "NodeLL": [ - { "delta": { "node-LL1": { "lon": 0, "lat": 0 } } }, - { - "delta": { - "node-LL5": { "lon": 133699, "lat": 163 } - } - }, - { - "delta": { - "node-LL4": { "lon": 56885, "lat": -5703 } - } - } - ] - } - } - }, - "scale": 0 - } - }, - "id": { "id": 0, "region": 0 }, - "direction": "0001100000000000" - }, - { - "closedPath": { "false": "" }, - "anchor": { "lat": 410985067, "long": -1051331761 }, - "name": "I_I 80_SAT-1AF9F730_P_68-0", - "laneWidth": 5000, - "directionality": { "both": "" }, - "description": { - "path": { - "offset": { - "ll": { - "nodes": { - "NodeLL": [ - { "delta": { "node-LL1": { "lon": 0, "lat": 0 } } }, - { - "delta": { - "node-LL5": { "lon": 133699, "lat": 163 } - } - }, - { - "delta": { - "node-LL4": { "lon": 56885, "lat": -5703 } - } - } - ] - } - } - }, - "scale": 0 - } - }, - "id": { "id": 0, "region": 0 }, - "direction": "0001100000000000" - } - ] - }, - "durationTime": 120, - "doNotUse3": 1, - "doNotUse4": 1, - "startYear": 2021, - "msgId": { - "roadSignID": { - "viewAngle": 1111111111111111, - "mutcdCode": { "warning": "" }, - "position": { "lat": 410985067, "long": -1051331761 } - } - }, - "priority": 5, - "content": { - "exitService": { - "SEQUENCE": [ - { "item": { "itis": 4104 } }, - { "item": { "itis": 11794 } }, - { "item": { "text": 345 } } - ] - } - }, - "url": null, - "doNotUse1": 1, - "doNotUse2": 1, - "frameType": { "advisory": "" }, - "startTime": 117800 - } - }, - "msgCnt": 1 + "sanitized": false, + "recordGeneratedAt": "2021-03-23T19:20:48.130840Z", + "maxDurationTime": 120, + "odeTimStartDateTime": "2021-03-23T19:20:47.118Z", + "odeReceivedAt": "2021-03-23T19:20:48.177Z" + }, + "payload": { + "data": { + "timeStamp": 117800, + "packetID": "AE394DB5A033905B26", + "urlB": null, + "dataFrames": [ + { + "regions": [ + { + "closedPath": false, + "anchor": { "lat": 410985067, "long": -1051331761 }, + "name": "I_I 80_SAT-1AF9F730_P_68-0", + "laneWidth": 5000, + "directionality": "both", + "description": { + "path": { + "offset": { + "ll": { + "nodes": [ + { + "delta": { "node-LL1": { "lon": 0, "lat": 0 } } + }, + { + "delta": { + "node-LL5": { "lon": 133699, "lat": 163 } + } + }, + { + "delta": { + "node-LL4": { "lon": 56885, "lat": -5703 } + } + } + ] + } + }, + "scale": 0 } + }, + "id": { "id": 0, "region": 0 }, + "direction": { + "from000-0to022-5degrees": false, + "from022-5to045-0degrees": false, + "from045-0to067-5degrees": false, + "from067-5to090-0degrees": true, + "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 } - } - }, - "dataType": "TravelerInformation" - } + }, + { + "closedPath": "false", + "anchor": { "lat": 410985067, "long": -1051331761 }, + "name": "I_I 80_SAT-1AF9F730_P_68-0", + "laneWidth": 5000, + "directionality": "both", + "description": { + "path": { + "offset": { + "ll": { + "nodes": [ + { + "delta": { "node-LL1": { "lon": 0, "lat": 0 } } + }, + { + "delta": { + "node-LL5": { "lon": 133699, "lat": 163 } + } + }, + { + "delta": { + "node-LL4": { "lon": 56885, "lat": -5703 } + } + } + ] + } + }, + "scale": 0 + } + }, + "id": { "id": 0, "region": 0 }, + "direction": { + "from000-0to022-5degrees": false, + "from022-5to045-0degrees": false, + "from045-0to067-5degrees": false, + "from067-5to090-0degrees": true, + "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 + } + } + ], + "durationTime": 120, + "doNotUse3": 0, + "doNotUse4": 0, + "startYear": 2021, + "msgId": { + "roadSignID": { + "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", + "position": { "lat": 410985067, "long": -1051331761 } + } + }, + "priority": 5, + "content": { + "exitService": [ + { "item": { "itis": 4104 } }, + { "item": { "itis": 11794 } }, + { "item": { "text": 345 } } + ] + }, + "url": "null", + "doNotUse1": 0, + "doNotUse2": 0, + "frameType": "advisory", + "startTime": 117800 + } + ], + "msgCnt": 1 + }, + "dataType": "TravelerInformation" + } } From 065bf6badc8e7c68692821f303d38beec01c29ca Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 13 Mar 2025 08:08:58 -0600 Subject: [PATCH 072/168] Update VSL testing data to match OdeTimJson new format --- .../src/test/resources/tim_vsl.json | 214 +++++++------ .../resources/tim_vsl_MultipleRegions.json | 284 ++++++++++-------- 2 files changed, 283 insertions(+), 215 deletions(-) diff --git a/cv-data-service-library/src/test/resources/tim_vsl.json b/cv-data-service-library/src/test/resources/tim_vsl.json index 25bafd26a..fde8dd0cb 100644 --- a/cv-data-service-library/src/test/resources/tim_vsl.json +++ b/cv-data-service-library/src/test/resources/tim_vsl.json @@ -1,102 +1,126 @@ { - "metadata": { - "request": { - "ode": { "verb": "POST", "version": 3 }, - "sdw": { - "recordId": "A5FB00B7", - "serviceRegion": { - "nwCorner": { "latitude": 42.8616018, "longitude": -106.3393164 }, - "seCorner": { "latitude": 42.8616018, "longitude": -106.3393164 } - }, - "ttl": "oneyear" - } - }, - "recordGeneratedBy": "TMC", - "schemaVersion": 6, - "payloadType": "us.dot.its.jpo.ode.model.OdeTimPayload", - "odePacketID": "FCEAC42FC4F3A9E274", - "serialId": { - "recordId": 0, - "serialNumber": 5745, - "streamId": "28dcab17-fb6b-4df5-8139-6cf59e5d64c5", - "bundleSize": 1, - "bundleId": 5745 + "metadata": { + "request": { + "ode": { "verb": "POST", "version": 3 }, + "sdw": { + "recordId": "A5FB00B7", + "serviceRegion": { + "nwCorner": { "latitude": 42.8616018, "longitude": -106.3393164 }, + "seCorner": { "latitude": 42.8616018, "longitude": -106.3393164 } }, - "sanitized": false, - "recordGeneratedAt": "2021-03-22T08:41:37.953583Z", - "maxDurationTime": 32000, - "odeTimStartDateTime": "2021-03-22T08:41:36.848Z", - "odeReceivedAt": "2021-03-22T08:41:38.108Z" + "ttl": "oneyear" + } + }, + "recordGeneratedBy": "TMC", + "schemaVersion": 6, + "payloadType": "us.dot.its.jpo.ode.model.OdeTimPayload", + "odePacketID": "FCEAC42FC4F3A9E274", + "serialId": { + "recordId": 0, + "serialNumber": 5745, + "streamId": "28dcab17-fb6b-4df5-8139-6cf59e5d64c5", + "bundleSize": 1, + "bundleId": 5745 }, - "payload": { - "data": { - "MessageFrame": { - "messageId": 31, - "value": { - "TravelerInformation": { - "timeStamp": 115721, - "packetID": "FCEAC42FC4F3A9E274", - "urlB": null, - "dataFrames": { - "TravelerDataFrame": { - "regions": { - "GeographicalPath": { - "closedPath": { "false": "" }, - "anchor": { "lat": 428605724, "long": -1063379489 }, - "name": "I_I 25_SAT-A5FB00B7_VSL_V004988-0", - "laneWidth": 5000, - "directionality": { "both": "" }, - "description": { - "path": { - "offset": { - "ll": { - "nodes": { - "NodeLL": { - "delta": { "node-LL3": { "lon": -13675, "lat": 10295 } } - } - } - } - }, - "scale": 0 - } - }, - "id": { "id": 0, "region": 0 }, - "direction": "0000000000000010" - } - }, - "durationTime": 32000, - "doNotUse3": 1, - "doNotUse4": 1, - "startYear": 2021, - "msgId": { - "roadSignID": { - "viewAngle": 1111111111111111, - "mutcdCode": { "regulatory": "" }, - "position": { "lat": 428605724, "long": -1063379489 } - } - }, - "priority": 5, - "content": { - "speedLimit": { - "SEQUENCE": [ - { "item": { "itis": 268 } }, - { "item": { "itis": 12604 } }, - { "item": { "itis": 8720 } } - ] - } - }, - "url": null, - "doNotUse1": 1, - "doNotUse2": 1, - "frameType": { "roadSignage": "" }, - "startTime": 115721 - } - }, - "msgCnt": 1 + "sanitized": false, + "recordGeneratedAt": "2021-03-22T08:41:37.953583Z", + "maxDurationTime": 32000, + "odeTimStartDateTime": "2021-03-22T08:41:36.848Z", + "odeReceivedAt": "2021-03-22T08:41:38.108Z" + }, + "payload": { + "data": { + "msgCnt": 1, + "timeStamp": 115721, + "packetID": "FCEAC42FC4F3A9E274", + "urlB": "null", + "dataFrames": [ + { + "doNotUse1": 0, + "frameType": "advisory", + "msgId": { + "roadSignID": { + "position": { "lat": 417732928, "long": -1071000312 }, + "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" + } + }, + "durationTime": 32000, + "startYear": 2021, + "startTime": 89280, + "priority": 5, + "doNotUse2": 0, + "regions": [ + { + "name": "I_I 25_SAT-A5FB00B7_VSL_V004988-0", + "id": { + "region": 0, + "id": 0 + }, + "anchor": { "lat": 417732928, "long": -1071000312 }, + "laneWidth": 5000, + "directionality": "both", + "closedPath": false, + "direction": { + "from000-0to022-5degrees": false, + "from022-5to045-0degrees": false, + "from045-0to067-5degrees": false, + "from067-5to090-0degrees": true, + "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": { + "path": { + "scale": 0, + "offset": { + "ll": { + "nodes": [{ "node-LL3": { "lon": -13675, "lat": 10295 } }] } + } } + } } - }, - "dataType": "TravelerInformation" - } + ], + "doNotUse3": 0, + "doNotUse4": 0, + "content": { + "speedLimit": [ + { "item": { "itis": 268 } }, + { "item": { "itis": 12604 } }, + { "item": { "itis": 8720 } } + ] + }, + "url": "null" + } + ] + }, + "dataType": "us.dot.its.jpo.ode.plugin.j2735.travelerinformation.TravelerInformation" + } } diff --git a/cv-data-service-library/src/test/resources/tim_vsl_MultipleRegions.json b/cv-data-service-library/src/test/resources/tim_vsl_MultipleRegions.json index fe99be538..e8220debf 100644 --- a/cv-data-service-library/src/test/resources/tim_vsl_MultipleRegions.json +++ b/cv-data-service-library/src/test/resources/tim_vsl_MultipleRegions.json @@ -1,127 +1,171 @@ { - "metadata": { - "request": { - "ode": { "verb": "POST", "version": 3 }, - "sdw": { - "recordId": "A5FB00B7", - "serviceRegion": { - "nwCorner": { "latitude": 42.8616018, "longitude": -106.3393164 }, - "seCorner": { "latitude": 42.8616018, "longitude": -106.3393164 } - }, - "ttl": "oneyear" - } - }, - "recordGeneratedBy": "TMC", - "schemaVersion": 6, - "payloadType": "us.dot.its.jpo.ode.model.OdeTimPayload", - "odePacketID": "FCEAC42FC4F3A9E274", - "serialId": { - "recordId": 0, - "serialNumber": 5745, - "streamId": "28dcab17-fb6b-4df5-8139-6cf59e5d64c5", - "bundleSize": 1, - "bundleId": 5745 + "metadata": { + "request": { + "ode": { "verb": "POST", "version": 3 }, + "sdw": { + "recordId": "A5FB00B7", + "serviceRegion": { + "nwCorner": { "latitude": 42.8616018, "longitude": -106.3393164 }, + "seCorner": { "latitude": 42.8616018, "longitude": -106.3393164 } }, - "sanitized": false, - "recordGeneratedAt": "2021-03-22T08:41:37.953583Z", - "maxDurationTime": 32000, - "odeTimStartDateTime": "2021-03-22T08:41:36.848Z", - "odeReceivedAt": "2021-03-22T08:41:38.108Z" + "ttl": "oneyear" + } }, - "payload": { - "data": { - "MessageFrame": { - "messageId": 31, - "value": { - "TravelerInformation": { - "timeStamp": 115721, - "packetID": "FCEAC42FC4F3A9E274", - "urlB": null, - "dataFrames": { - "TravelerDataFrame": { - "regions": { - "GeographicalPath": [ - { - "closedPath": { "false": "" }, - "anchor": { "lat": 428605724, "long": -1063379489 }, - "name": "I_I 25_SAT-A5FB00B7_VSL_V004988-0", - "laneWidth": 5000, - "directionality": { "both": "" }, - "description": { - "path": { - "offset": { - "ll": { - "nodes": { - "NodeLL": { - "delta": { "node-LL3": { "lon": -13675, "lat": 10295 } } - } - } - } - }, - "scale": 0 - } - }, - "id": { "id": 0, "region": 0 }, - "direction": "0000000000000010" - }, - { - "closedPath": { "false": "" }, - "anchor": { "lat": 428605724, "long": -1063379489 }, - "name": "I_I 25_SAT-A5FB00B7_VSL_V004988-0", - "laneWidth": 5000, - "directionality": { "both": "" }, - "description": { - "path": { - "offset": { - "ll": { - "nodes": { - "NodeLL": { - "delta": { "node-LL3": { "lon": -13675, "lat": 10295 } } - } - } - } - }, - "scale": 0 - } - }, - "id": { "id": 0, "region": 0 }, - "direction": "0000000000000010" - } - ] - }, - "durationTime": 32000, - "doNotUse3": 1, - "doNotUse4": 1, - "startYear": 2021, - "msgId": { - "roadSignID": { - "viewAngle": 1111111111111111, - "mutcdCode": { "regulatory": "" }, - "position": { "lat": 428605724, "long": -1063379489 } - } - }, - "priority": 5, - "content": { - "speedLimit": { - "SEQUENCE": [ - { "item": { "itis": 268 } }, - { "item": { "itis": 12604 } }, - { "item": { "itis": 8720 } } - ] - } - }, - "url": null, - "doNotUse1": 1, - "doNotUse2": 1, - "frameType": { "roadSignage": "" }, - "startTime": 115721 - } - }, - "msgCnt": 1 + "recordGeneratedBy": "TMC", + "schemaVersion": 6, + "payloadType": "us.dot.its.jpo.ode.model.OdeTimPayload", + "odePacketID": "FCEAC42FC4F3A9E274", + "serialId": { + "recordId": 0, + "serialNumber": 5745, + "streamId": "28dcab17-fb6b-4df5-8139-6cf59e5d64c5", + "bundleSize": 1, + "bundleId": 5745 + }, + "sanitized": false, + "recordGeneratedAt": "2021-03-22T08:41:37.953583Z", + "maxDurationTime": 32000, + "odeTimStartDateTime": "2021-03-22T08:41:36.848Z", + "odeReceivedAt": "2021-03-22T08:41:38.108Z" + }, + "payload": { + "data": { + "timeStamp": 115721, + "packetID": "FCEAC42FC4F3A9E274", + "urlB": "null", + "dataFrames": [ + { + "regions": [ + { + "closedPath": "false", + "anchor": { "lat": 428605724, "long": -1063379489 }, + "name": "I_I 25_SAT-A5FB00B7_VSL_V004988-0", + "laneWidth": 5000, + "directionality": "both", + "description": { + "path": { + "offset": { + "ll": { + "nodes": [ + { + "delta": { + "node-LL3": { "lon": -13675, "lat": 10295 } + } + } + ] + } + }, + "scale": 0 + } + }, + "id": { "id": 0, "region": 0 }, + "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 + } + }, + { + "closedPath": "false", + "anchor": { "lat": 428605724, "long": -1063379489 }, + "name": "I_I 25_SAT-A5FB00B7_VSL_V004988-0", + "laneWidth": 5000, + "directionality": "both", + "description": { + "path": { + "offset": { + "ll": { + "nodes": [ + { + "delta": { + "node-LL3": { "lon": -13675, "lat": 10295 } + } + } + ] } + }, + "scale": 0 } + }, + "id": { "id": 0, "region": 0 }, + "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 + } } - }, - "dataType": "TravelerInformation" - } + ], + "durationTime": 32000, + "doNotUse3": 1, + "doNotUse4": 1, + "startYear": 2021, + "msgId": { + "roadSignID": { + "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": "regulatory", + "position": { "lat": 428605724, "long": -1063379489 } + } + }, + "priority": 5, + "content": { + "speedLimit": [ + { "item": { "itis": 268 } }, + { "item": { "itis": 12604 } }, + { "item": { "itis": 8720 } } + ] + }, + "url": "null", + "doNotUse1": 0, + "doNotUse2": 0, + "frameType": "roadSignage", + "startTime": 115721 + } + ], + "msgCnt": 1 + }, + "dataType": "us.dot.its.jpo.ode.plugin.j2735.travelerinformation.TravelerInformation" + } } From 328e7d5ec556b0d147cfa466fff35333f514d8e5 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 13 Mar 2025 08:09:22 -0600 Subject: [PATCH 073/168] Update odeTim testing files to match OdeTimJson new format --- .../resources/TIM_odeTimStartDateTime.json | 587 +++++++++--------- .../src/test/resources/TIM_odeTim_Rsus.json | 485 ++++++++------- 2 files changed, 551 insertions(+), 521 deletions(-) diff --git a/logger-kafka-consumer/src/test/resources/TIM_odeTimStartDateTime.json b/logger-kafka-consumer/src/test/resources/TIM_odeTimStartDateTime.json index ed7c8f1ef..4b66fec03 100644 --- a/logger-kafka-consumer/src/test/resources/TIM_odeTimStartDateTime.json +++ b/logger-kafka-consumer/src/test/resources/TIM_odeTimStartDateTime.json @@ -1,294 +1,309 @@ { - "metadata": { - "request": { - "ode": { - "verb": "POST", - "version": 3 - }, - "sdw": { - "recordId": "047D5D92", - "serviceRegion": { - "nwCorner": { - "latitude": 42.0423655, - "longitude": -110.65625591 - }, - "seCorner": { - "latitude": 41.80934153, - "longitude": -110.53481503 - } - }, - "ttl": "oneyear" - } + "metadata": { + "request": { + "ode": { + "verb": "POST", + "version": 3 + }, + "sdw": { + "recordId": "047D5D92", + "serviceRegion": { + "nwCorner": { + "latitude": 42.0423655, + "longitude": -110.65625591 + }, + "seCorner": { + "latitude": 41.80934153, + "longitude": -110.53481503 + } }, - "recordGeneratedBy": "TMC", - "schemaVersion": 6, - "payloadType": "us.dot.its.jpo.ode.model.OdeTimPayload", - "odePacketID": "1D6FCDA23022F235E6", - "serialId": { - "recordId": 0, - "serialNumber": 39887, - "streamId": "9a4b7448-d26a-41f9-a80d-97f3ac8c1dd7", - "bundleSize": 1, - "bundleId": 39887 - }, - "sanitized": false, - "recordGeneratedAt": "2020-11-11T07:34:05.151191Z", - "maxDurationTime": 32000, - "odeTimStartDateTime": "2020-11-11T07:36:53.035Z", - "odeReceivedAt": "2020-11-11T07:34:05.220Z" + "ttl": "oneyear" + } + }, + "recordGeneratedBy": "TMC", + "schemaVersion": 6, + "payloadType": "us.dot.its.jpo.ode.model.OdeTimPayload", + "odePacketID": "1D6FCDA23022F235E6", + "serialId": { + "recordId": 0, + "serialNumber": 39887, + "streamId": "9a4b7448-d26a-41f9-a80d-97f3ac8c1dd7", + "bundleSize": 1, + "bundleId": 39887 }, - "payload": { - "data": { - "MessageFrame": { - "messageId": 31, - "value": { - "TravelerInformation": { - "timeStamp": 454054, - "packetID": "1D6FCDA23022F235E6", - "urlB": null, - "dataFrames": { - "TravelerDataFrame": { - "regions": { - "GeographicalPath": { - "closedPath": { - "false": "" - }, - "anchor": { - "lat": 418082518, - "long": -1105341319 - }, - "name": "I_WY 233_SAT-047D5D92_RC_KEMWYO233B", - "laneWidth": 32700, - "directionality": { - "both": "" - }, - "description": { - "path": { - "offset": { - "ll": { - "nodes": { - "NodeLL": [ - { - "delta": { - "node-LL3": { - "lon": -8338, - "lat": 10897 - } - } - }, - { - "delta": { - "node-LL5": { - "lon": 1507, - "lat": 169431 - } - } - }, - { - "delta": { - "node-LL5": { - "lon": -260004, - "lat": 152391 - } - } - }, - { - "delta": { - "node-LL5": { - "lon": -30606, - "lat": 230849 - } - } - }, - { - "delta": { - "node-LL4": { - "lon": -116741, - "lat": 76938 - } - } - }, - { - "delta": { - "node-LL5": { - "lon": -237069, - "lat": 63754 - } - } - }, - { - "delta": { - "node-LL4": { - "lon": -110373, - "lat": 80674 - } - } - }, - { - "delta": { - "node-LL5": { - "lon": -139739, - "lat": 122423 - } - } - }, - { - "delta": { - "node-LL5": { - "lon": -14891, - "lat": 173179 - } - } - }, - { - "delta": { - "node-LL4": { - "lon": -15201, - "lat": 51728 - } - } - }, - { - "delta": { - "node-LL5": { - "lon": -207792, - "lat": 174741 - } - } - }, - { - "delta": { - "node-LL5": { - "lon": -81993, - "lat": 147705 - } - } - }, - { - "delta": { - "node-LL4": { - "lon": 26456, - "lat": 68121 - } - } - }, - { - "delta": { - "node-LL4": { - "lon": 58918, - "lat": 74751 - } - } - }, - { - "delta": { - "node-LL4": { - "lon": -56248, - "lat": 74095 - } - } - }, - { - "delta": { - "node-LL5": { - "lon": -10762, - "lat": 220792 - } - } - }, - { - "delta": { - "node-LL4": { - "lon": -5356, - "lat": 70780 - } - } - }, - { - "delta": { - "node-LL4": { - "lon": 41398, - "lat": 125487 - } - } - }, - { - "delta": { - "node-LL4": { - "lon": 36074, - "lat": 63967 - } - } - }, - { - "delta": { - "node-LL5": { - "lon": -12787, - "lat": 188434 - } - } - } - ] - } - } - }, - "scale": 0 - } - }, - "id": { - "id": 0, - "region": 0 - }, - "direction": 1110000000001111 - } - }, - "durationTime": 32000, - "doNotUse3": 1, - "doNotUse4": 1, - "startYear": 2020, - "msgId": { - "roadSignID": { - "viewAngle": 1111111111111111, - "mutcdCode": { - "warning": "" - }, - "position": { - "lat": 418082518, - "long": -1105341319 - } - } - }, - "priority": 5, - "content": { - "advisory": { - "SEQUENCE": [ - { - "item": { - "itis": 5906 - } - }, - { - "item": { - "itis": 4868 - } - } - ] - } - }, - "url": null, - "doNotUse1": 1, - "doNotUse2": 1, - "frameType": { - "advisory": "" - }, - "startTime": 454054 + "sanitized": false, + "recordGeneratedAt": "2020-11-11T07:34:05.151191Z", + "maxDurationTime": 32000, + "odeTimStartDateTime": "2020-11-11T07:36:53.035Z", + "odeReceivedAt": "2020-11-11T07:34:05.220Z" + }, + "payload": { + "data": { + "timeStamp": 454054, + "packetID": "1D6FCDA23022F235E6", + "urlB": "null", + "dataFrames": [ + { + "regions": { + "GeographicalPath": { + "closedPath": "false", + "anchor": { + "lat": 418082518, + "long": -1105341319 + }, + "name": "I_WY 233_SAT-047D5D92_RC_KEMWYO233B", + "laneWidth": 32700, + "directionality": "both", + "description": { + "path": { + "offset": { + "ll": { + "nodes": [ + { + "delta": { + "node-LL3": { + "lon": -8338, + "lat": 10897 + } + } + }, + { + "delta": { + "node-LL5": { + "lon": 1507, + "lat": 169431 + } + } + }, + { + "delta": { + "node-LL5": { + "lon": -260004, + "lat": 152391 + } + } + }, + { + "delta": { + "node-LL5": { + "lon": -30606, + "lat": 230849 + } + } + }, + { + "delta": { + "node-LL4": { + "lon": -116741, + "lat": 76938 + } + } + }, + { + "delta": { + "node-LL5": { + "lon": -237069, + "lat": 63754 + } + } + }, + { + "delta": { + "node-LL4": { + "lon": -110373, + "lat": 80674 + } + } + }, + { + "delta": { + "node-LL5": { + "lon": -139739, + "lat": 122423 + } + } + }, + { + "delta": { + "node-LL5": { + "lon": -14891, + "lat": 173179 + } + } + }, + { + "delta": { + "node-LL4": { + "lon": -15201, + "lat": 51728 + } + } + }, + { + "delta": { + "node-LL5": { + "lon": -207792, + "lat": 174741 + } } - }, - "msgCnt": 16 + }, + { + "delta": { + "node-LL5": { + "lon": -81993, + "lat": 147705 + } + } + }, + { + "delta": { + "node-LL4": { + "lon": 26456, + "lat": 68121 + } + } + }, + { + "delta": { + "node-LL4": { + "lon": 58918, + "lat": 74751 + } + } + }, + { + "delta": { + "node-LL4": { + "lon": -56248, + "lat": 74095 + } + } + }, + { + "delta": { + "node-LL5": { + "lon": -10762, + "lat": 220792 + } + } + }, + { + "delta": { + "node-LL4": { + "lon": -5356, + "lat": 70780 + } + } + }, + { + "delta": { + "node-LL4": { + "lon": 41398, + "lat": 125487 + } + } + }, + { + "delta": { + "node-LL4": { + "lon": 36074, + "lat": 63967 + } + } + }, + { + "delta": { + "node-LL5": { + "lon": -12787, + "lat": 188434 + } + } + } + ] } + }, + "scale": 0 } + }, + "id": { + "id": 0, + "region": 0 + }, + "direction": { + "from000-0to022-5degrees": true, + "from022-5to045-0degrees": true, + "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": true, + "from292-5to315-0degrees": true, + "from315-0to337-5degrees": true, + "from337-5to360-0degrees": true + } } - }, - "dataType": "TravelerInformation" + }, + "durationTime": 32000, + "doNotUse3": 0, + "doNotUse4": 0, + "startYear": 2020, + "msgId": { + "roadSignID": { + "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", + "position": { + "lat": 418082518, + "long": -1105341319 + } + } + }, + "priority": 5, + "content": { + "advisory": [ + { + "item": { + "itis": 5906 + } + }, + { + "item": { + "itis": 4868 + } + } + ] + }, + "url": null, + "doNotUse1": 0, + "doNotUse2": 0, + "frameType": "advisory", + "startTime": 454054 + } + ], + "msgCnt": 16 } -} \ No newline at end of file + }, + "dataType": "us.dot.its.jpo.ode.plugin.j2735.travelerinformation.TravelerInformation" +} diff --git a/logger-kafka-consumer/src/test/resources/TIM_odeTim_Rsus.json b/logger-kafka-consumer/src/test/resources/TIM_odeTim_Rsus.json index 798566907..1c0e0c33b 100644 --- a/logger-kafka-consumer/src/test/resources/TIM_odeTim_Rsus.json +++ b/logger-kafka-consumer/src/test/resources/TIM_odeTim_Rsus.json @@ -1,244 +1,259 @@ { - "metadata": { - "maxDurationTime": 32000, - "odePacketID": "257559968DC2308890", - "odeReceivedAt": "2020-12-14T23:36:41.490Z", - "odeTimStartDateTime": "2020-12-14T23:36:40.718Z", - "payloadType": "us.dot.its.jpo.ode.model.OdeTimPayload", - "recordGeneratedAt": "2020-12-14T23:36:40.965947Z", - "recordGeneratedBy": "TMC", - "request": { - "ode": { - "verb": "PUT", - "version": 3 - }, - "rsus": { - "rsus": { - "rsuIndex": 53, - "rsuRetries": 3, - "rsuTarget": "10.145.12.27", - "rsuTimeout": 5000 - } - }, - "snmp": { - "channel": 178, - "deliverystart": "2020-12-14T23:36:40.718Z", - "deliverystop": "2021-01-06T04:56Z", - "enable": 1, - "interval": 2, - "mode": 1, - "msgid": 31, - "rsuid": 83, - "status": 4 - } - }, - "sanitized": false, - "schemaVersion": 6, - "serialId": { - "bundleId": 2965, - "bundleSize": 1, - "recordId": 0, - "serialNumber": 2965, - "streamId": "78804150-9fa0-4f73-b490-54c507ebc52b" + "metadata": { + "maxDurationTime": 32000, + "odePacketID": "257559968DC2308890", + "odeReceivedAt": "2020-12-14T23:36:41.490Z", + "odeTimStartDateTime": "2020-12-14T23:36:40.718Z", + "payloadType": "us.dot.its.jpo.ode.model.OdeTimPayload", + "recordGeneratedAt": "2020-12-14T23:36:40.965947Z", + "recordGeneratedBy": "TMC", + "request": { + "ode": { + "verb": "PUT", + "version": 3 + }, + "rsus": { + "rsus": { + "rsuIndex": 53, + "rsuRetries": 3, + "rsuTarget": "10.145.12.27", + "rsuTimeout": 5000 } + }, + "snmp": { + "channel": 178, + "deliverystart": "2020-12-14T23:36:40.718Z", + "deliverystop": "2021-01-06T04:56Z", + "enable": 1, + "interval": 2, + "mode": 1, + "msgid": 31, + "rsuid": 83, + "status": 4 + } }, - "payload": { - "data": { - "MessageFrame": { - "messageId": 31, - "value": { - "TravelerInformation": { - "dataFrames": { - "TravelerDataFrame": { - "content": { - "advisory": { - "SEQUENCE": { - "item": { - "itis": 4871 - } - } - } - }, - "durationTime": 32000, - "frameType": { - "advisory": "" - }, - "msgId": { - "roadSignID": { - "mutcdCode": { - "warning": "" - }, - "position": { - "lat": 412696444, - "long": -1054796709 - }, - "viewAngle": 1111111111111111 - } - }, - "priority": 5, - "regions": { - "GeographicalPath": { - "anchor": { - "lat": 412696444, - "long": -1054796709 - }, - "closedPath": { - "false": "" - }, - "description": { - "path": { - "offset": { - "ll": { - "nodes": { - "NodeLL": [ - { - "delta": { - "node-LL3": { - "lat": -10830, - "lon": 12710 - } - } - }, - { - "delta": { - "node-LL3": { - "lat": -20785, - "lon": 26578 - } - } - }, - { - "delta": { - "node-LL3": { - "lat": -6698, - "lon": 16897 - } - } - }, - { - "delta": { - "node-LL4": { - "lat": -5448, - "lon": 56865 - } - } - }, - { - "delta": { - "node-LL3": { - "lat": -14806, - "lon": 32584 - } - } - }, - { - "delta": { - "node-LL3": { - "lat": -15537, - "lon": 32086 - } - } - }, - { - "delta": { - "node-LL4": { - "lat": -18878, - "lon": 51470 - } - } - }, - { - "delta": { - "node-LL4": { - "lat": -55342, - "lon": 88538 - } - } - }, - { - "delta": { - "node-LL3": { - "lat": -23750, - "lon": 21609 - } - } - }, - { - "delta": { - "node-LL4": { - "lat": -117938, - "lon": 73050 - } - } - }, - { - "delta": { - "node-LL4": { - "lat": -56861, - "lon": 14308 - } - } - }, - { - "delta": { - "node-LL3": { - "lat": -28664, - "lon": -2927 - } - } - }, - { - "delta": { - "node-LL4": { - "lat": -41129, - "lon": -17876 - } - } - }, - { - "delta": { - "node-LL3": { - "lat": -14462, - "lon": 667 - } - } - } - ] - } - } - }, - "scale": 0 - } - }, - "direction": "0000111110000000", - "directionality": { - "both": "" - }, - "id": { - "id": 0, - "region": 0 - }, - "laneWidth": 5000, - "name": "I_I 80_RSU-10.145.12.27_RC_test-t-12" - } - }, - "doNotUse2": 1, - "doNotUse3": 1, - "doNotUse4": 1, - "doNotUse1": 1, - "startTime": 502536, - "startYear": 2020, - "url": null + "sanitized": false, + "schemaVersion": 6, + "serialId": { + "bundleId": 2965, + "bundleSize": 1, + "recordId": 0, + "serialNumber": 2965, + "streamId": "78804150-9fa0-4f73-b490-54c507ebc52b" + } + }, + "payload": { + "data": { + "msgCnt": 2, + "packetID": "257559968DC2308890", + "timeStamp": 502536, + "urlB": "null", + "dataFrames": [ + { + "content": { + "advisory": [ + { + "item": {"itis": 4871} + } + ] + }, + "durationTime": 32000, + "frameType": "advisory", + "msgId": { + "roadSignID": { + "mutcdCode": "warning", + "position": { + "lat": 412696444, + "long": -1054796709 + }, + "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 + } + } + }, + "priority": 5, + "regions": [ + { + "anchor": { + "lat": 412696444, + "long": -1054796709 + }, + "closedPath": "false", + "description": { + "path": { + "offset": { + "ll": { + "nodes": [ + { + "delta": { + "node-LL3": { + "lat": -10830, + "lon": 12710 + } + } + }, + { + "delta": { + "node-LL3": { + "lat": -20785, + "lon": 26578 + } + } + }, + { + "delta": { + "node-LL3": { + "lat": -6698, + "lon": 16897 + } + } + }, + { + "delta": { + "node-LL4": { + "lat": -5448, + "lon": 56865 + } + } + }, + { + "delta": { + "node-LL3": { + "lat": -14806, + "lon": 32584 + } + } + }, + { + "delta": { + "node-LL3": { + "lat": -15537, + "lon": 32086 + } + } + }, + { + "delta": { + "node-LL4": { + "lat": -18878, + "lon": 51470 + } + } + }, + { + "delta": { + "node-LL4": { + "lat": -55342, + "lon": 88538 + } + } + }, + { + "delta": { + "node-LL3": { + "lat": -23750, + "lon": 21609 + } + } + }, + { + "delta": { + "node-LL4": { + "lat": -117938, + "lon": 73050 } + } }, - "msgCnt": 2, - "packetID": "257559968DC2308890", - "timeStamp": 502536, - "urlB": null + { + "delta": { + "node-LL4": { + "lat": -56861, + "lon": 14308 + } + } + }, + { + "delta": { + "node-LL3": { + "lat": -28664, + "lon": -2927 + } + } + }, + { + "delta": { + "node-LL4": { + "lat": -41129, + "lon": -17876 + } + } + }, + { + "delta": { + "node-LL3": { + "lat": -14462, + "lon": 667 + } + } + } + ] } + }, + "scale": 0 } + }, + "direction": { + "from000-0to022-5degrees": false, + "from022-5to045-0degrees": false, + "from045-0to067-5degrees": false, + "from067-5to090-0degrees": false, + "from090-0to112-5degrees": true, + "from112-5to135-0degrees": true, + "from135-0to157-5degrees": true, + "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 + }, + "directionality": "both", + "id": { + "id": 0, + "region": 0 + }, + "laneWidth": 5000, + "name": "I_I 80_RSU-10.145.12.27_RC_test-t-12" } - }, - "dataType": "TravelerInformation" + ], + "doNotUse2": 0, + "doNotUse3": 0, + "doNotUse4": 0, + "doNotUse1": 0, + "startTime": 502536, + "startYear": 2020, + "url": "null" + } + ] } -} \ No newline at end of file + }, + "dataType": "us.dot.its.jpo.ode.plugin.j2735.travelerinformation.TravelerInformation" +} From 2db3924505af6269348e2ad01b46398529dc67f7 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 13 Mar 2025 08:09:39 -0600 Subject: [PATCH 074/168] Remove unnecessary test from TimDataConverterTest --- .../dataConverters/TimDataConverterTest.java | 13 -- .../src/test/resources/TIM_unsigned.json | 213 ------------------ 2 files changed, 226 deletions(-) delete mode 100644 logger-kafka-consumer/src/test/resources/TIM_unsigned.json diff --git a/logger-kafka-consumer/src/test/java/com/trihydro/loggerkafkaconsumer/app/dataConverters/TimDataConverterTest.java b/logger-kafka-consumer/src/test/java/com/trihydro/loggerkafkaconsumer/app/dataConverters/TimDataConverterTest.java index 2600838b3..79405f92f 100644 --- a/logger-kafka-consumer/src/test/java/com/trihydro/loggerkafkaconsumer/app/dataConverters/TimDataConverterTest.java +++ b/logger-kafka-consumer/src/test/java/com/trihydro/loggerkafkaconsumer/app/dataConverters/TimDataConverterTest.java @@ -208,19 +208,6 @@ public void processTimJson_odeTimWithRsus() throws IOException { } - @Test - public void processTimJson_unsigned() throws IOException { - // Arrange - String value = new String(Files.readAllBytes(Paths.get("src/test/resources/TIM_unsigned.json"))); - - // Act - var data = uut.processTimJson(value); - - // Assert - Assertions.assertNotNull(data); - Assertions.assertNotNull(data.getMetadata()); - } - /** * Helper method to get an OdeTravelerInformationMessage object given an OdeTimPayload. */ diff --git a/logger-kafka-consumer/src/test/resources/TIM_unsigned.json b/logger-kafka-consumer/src/test/resources/TIM_unsigned.json deleted file mode 100644 index 2a74209cc..000000000 --- a/logger-kafka-consumer/src/test/resources/TIM_unsigned.json +++ /dev/null @@ -1,213 +0,0 @@ -{ - "metadata": { - "request": { - "ode": { - "verb": "POST", - "version": "3" - }, - "sdw": { - "recordId": "60F53BDF", - "serviceRegion": { - "nwCorner": { - "latitude": "44.09328877", - "longitude": "-107.96034055" - }, - "seCorner": { - "latitude": "44.07225981", - "longitude": "-107.95401624" - } - }, - "ttl": "oneyear" - } - }, - "recordGeneratedBy": "TMC", - "schemaVersion": "6", - "payloadType": "us.dot.its.jpo.ode.model.OdeTimPayload", - "odePacketID": "20F6CCABC034423CB3", - "serialId": { - "recordId": "0", - "serialNumber": "76194", - "streamId": "662dd7d9-72d8-4b8a-a25a-4efa45b48936", - "bundleSize": "1", - "bundleId": "76194" - }, - "sanitized": "false", - "recordGeneratedAt": "2022-11-18T17:12:40.652239Z", - "maxDurationTime": "32000", - "odeTimStartDateTime": "2022-09-12T00:00:00.000Z", - "odeReceivedAt": "2022-11-18T17:12:40.682413Z" - }, - "payload": { - "data": { - "AdvisorySituationData": { - "recordID": "60F53BDF", - "timeToLive": "5", - "serviceRegion": { - "nwCorner": { - "lat": "440932888", - "long": "-1079603406" - }, - "seCorner": { - "lat": "440722598", - "long": "-1079540162" - } - }, - "asdmDetails": { - "advisoryMessage": { - "Ieee1609Dot2Data": { - "protocolVersion": "3", - "content": { - "unsecuredData": { - "MessageFrame": { - "messageId": "31", - "value": { - "TravelerInformation": { - "timeStamp": "463272", - "packetID": "20F6CCABC034423CB3", - "urlB": "null", - "dataFrames": { - "TravelerDataFrame": { - "regions": { - "GeographicalPath": { - "closedPath": { - "false": "" - }, - "anchor": { - "lat": "440947086", - "long": "-1079550305" - }, - "name": "D_WY 433_SAT-60F53BDF_RW_39683-0", - "laneWidth": "5000", - "directionality": { - "both": "" - }, - "description": { - "path": { - "offset": { - "ll": { - "nodes": { - "NodeLL": [ - { - "delta": { - "node-LL3": { - "lon": "3768", - "lat": "-14198" - } - } - }, - { - "delta": { - "node-LL3": { - "lon": "6374", - "lat": "-28466" - } - } - }, - { - "delta": { - "node-LL3": { - "lon": "-5520", - "lat": "-28521" - } - } - }, - { - "delta": { - "node-LL4": { - "lon": "-52848", - "lat": "-124572" - } - } - }, - { - "delta": { - "node-LL3": { - "lon": "-4875", - "lat": "-28730" - } - } - } - ] - } - } - }, - "scale": "0" - } - }, - "id": { - "id": "0", - "region": "0" - }, - "direction": "0000000110000000" - } - }, - "durationTime": "32000", - "doNotUse3": "1", - "doNotUse4": "1", - "startYear": "2022", - "msgId": { - "roadSignID": { - "viewAngle": "1111111111111111", - "mutcdCode": { - "warning": "" - }, - "position": { - "lat": "440947086", - "long": "-1079550305" - } - } - }, - "priority": "5", - "content": { - "workZone": { - "SEQUENCE": { - "item": { - "itis": "1025" - } - } - } - }, - "url": "null", - "doNotUse1": "1", - "doNotUse2": "1", - "frameType": { - "advisory": "" - }, - "startTime": "365760" - } - }, - "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": "427DA360" - }, - "requestID": "427DA360", - "groupID": "00000000", - "dialogID": "156", - "seqID": "5" - } - }, - "dataType": "TravelerInformation" - } -} \ No newline at end of file From 12cec95a810a42cc5e93beb71c63c7416d91b9a3 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 27 Mar 2025 09:53:24 -0600 Subject: [PATCH 075/168] Add additional ODE env vars to local-deployment docker-compose.yml --- local-deployment/docker-compose.yml | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/local-deployment/docker-compose.yml b/local-deployment/docker-compose.yml index 37ad144e7..4322f04c2 100644 --- a/local-deployment/docker-compose.yml +++ b/local-deployment/docker-compose.yml @@ -52,13 +52,28 @@ services: - "6666:6666/udp" environment: DOCKER_HOST_IP: ${DOCKER_HOST_IP} - ZK: ${DOCKER_HOST_IP}:2181 + ODE_KAFKA_BROKERS: ${DOCKER_HOST_IP}:9092 ODE_SECURITY_SVCS_SIGNATURE_URI: http://notused ODE_RSU_USERNAME: testusername ODE_RSU_PASSWORD: testpassword DATA_SIGNING_ENABLED_RSU: false DATA_SIGNING_ENABLED_SDW: false DEFAULT_SNMP_PROTOCOL: NTCIP1218 + KAFKA_TYPE: local + CONFLUENT_KEY: notused + CONFLUENT_SECRET: notused + KAFKA_LINGER_MS: 1 + KAFKA_ACKS: all + KAFKA_RETRIES: 0 + KAFKA_BATCH_SIZE: 16384 + KAFKA_BUFFER_MEMORY=: 33554432 + KAFKA_COMPRESSION_TYPE: zstd + KAFKA_KEY_SERIALIZER: org.apache.kafka.common.serialization.StringSerializer + KAFKA_VALUE_SERIALIZER: org.apache.kafka.common.serialization.StringSerializer + KAFKA_PARTITIONER_CLASS: org.apache.kafka.clients.producer.internals.DefaultPartitioner + ODE_TIM_INGEST_MONITORING_ENABLED: false + ODE_TIM_INGEST_MONITORING_INTERVAL: 10000 + depends_on: - kafka volumes: From db068a6e1f1674af466b18aeeffd6a17bbfc6660 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 27 Mar 2025 10:19:28 -0600 Subject: [PATCH 076/168] Remove equals sign from ode env var --- local-deployment/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/local-deployment/docker-compose.yml b/local-deployment/docker-compose.yml index 4322f04c2..65a767c8e 100644 --- a/local-deployment/docker-compose.yml +++ b/local-deployment/docker-compose.yml @@ -66,7 +66,7 @@ services: KAFKA_ACKS: all KAFKA_RETRIES: 0 KAFKA_BATCH_SIZE: 16384 - KAFKA_BUFFER_MEMORY=: 33554432 + KAFKA_BUFFER_MEMORY: 33554432 KAFKA_COMPRESSION_TYPE: zstd KAFKA_KEY_SERIALIZER: org.apache.kafka.common.serialization.StringSerializer KAFKA_VALUE_SERIALIZER: org.apache.kafka.common.serialization.StringSerializer From d22ef56097262b8e48937ec46911c9593f4e9d4c Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Wed, 2 Apr 2025 08:09:49 -0600 Subject: [PATCH 077/168] Update getRegion to use StringBuilder, parseBoolean --- .../trihydro/library/helpers/JsonToJavaConverter.java | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/JsonToJavaConverter.java b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/JsonToJavaConverter.java index 124dc1c9e..0779c9016 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/JsonToJavaConverter.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/JsonToJavaConverter.java @@ -242,17 +242,14 @@ else if (reverse != null) } if (regionDirectionNode != null) { - var direction = ""; + StringBuilder directionBuilder = new StringBuilder(); Iterator> fields = regionDirectionNode.fields(); while (fields.hasNext()) { Map.Entry field = fields.next(); - var directionBool = field.getValue().toString(); - if ("true".equals(directionBool)) - direction += "1"; - else - direction += "0"; + boolean directionBool= Boolean.parseBoolean(field.getValue().toString()); + directionBuilder.append(directionBool ? "1" : "0"); } - region.setDirection(direction); + region.setDirection(directionBuilder.toString()); } JsonNode descriptionNode = regionNode.get("description"); From dbf1b95801df494fd7dc7e463e9c017b4c1263c0 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Thu, 3 Apr 2025 16:39:46 -0600 Subject: [PATCH 078/168] Improved frame type value resolution in `ActiveTimController` to default to "advisory" when the original value is unusable --- .../controller/ActiveTimController.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java index 1afe4c81a..c7fa27404 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java @@ -172,6 +172,12 @@ public ResponseEntity> GetExpiringActiveTims() { if (!rs.wasNull() && frameTypeValue >= 0 && frameTypeValue < TravelerInfoType.values().length) { activeTim.setFrameType(TravelerInfoType.values()[frameTypeValue]); } + else { + utility.logWithDate("Could not set frame type from value " + frameTypeValue + + " for active tim id " + activeTim.getActiveTimId() + ". Assuming Advisory."); + // assume advisory + activeTim.setFrameType(TravelerInfoType.advisory); + } // set dataFrame content. it's required for the ODE, so if we didn't record it, // assume Advisory @@ -303,6 +309,12 @@ public ResponseEntity GetUpdateModelFromActiveTimId(@PathVariabl if (!rs.wasNull() && frameTypeValue >= 0 && frameTypeValue < TravelerInfoType.values().length) { activeTim.setFrameType(TravelerInfoType.values()[frameTypeValue]); } + else { + utility.logWithDate("Could not set frame type from value " + frameTypeValue + + " for active tim id " + activeTimId + ". Assuming Advisory."); + // assume advisory + activeTim.setFrameType(TravelerInfoType.advisory); + } // set dataFrame content. it's required for the ODE, so if we didn't record it, // assume Advisory From 10df33c6dc501b29f43ebfa3879186430cbddaed Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Tue, 8 Apr 2025 07:36:03 -0600 Subject: [PATCH 079/168] Remove outdated comment --- .../com/trihydro/cvdatacontroller/controller/RsuController.java | 1 - 1 file changed, 1 deletion(-) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/RsuController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/RsuController.java index e273adf92..f34f09c87 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/RsuController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/RsuController.java @@ -84,7 +84,6 @@ public ResponseEntity> GetFullRsusTimIsOn(@PathVariable Long t connection = dbInteractions.getConnectionPool(); statement = connection.createStatement(); - // select all RSUs that are labeled as 'Existing' in the WYDOT view rs = statement.executeQuery( "select rsus.rsu_id, rsu_credentials.username as update_username, " + "rsu_credentials.password as update_password, ST_X(ST_AsText(rsus.geography)) " + From a035d8e54b0b2bf90c559a00b92de1e5a28ba323 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Tue, 8 Apr 2025 07:41:25 -0600 Subject: [PATCH 080/168] Update CDOT compose file to include confluent values --- docker-compose-cdot-deployment.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docker-compose-cdot-deployment.yml b/docker-compose-cdot-deployment.yml index d3f291fdc..b42f296bc 100644 --- a/docker-compose-cdot-deployment.yml +++ b/docker-compose-cdot-deployment.yml @@ -149,6 +149,9 @@ services: restart: always environment: KAFKA_HOST_SERVER: ${LOGGER_KAFKA_HOST_SERVER} + KAFKA_TYPE: ${KAFKA_TYPE} + CONFLUENT_KEY: ${CONFLUENT_KEY} + CONFLUENT_SECRET: ${CONFLUENT_SECRET} DATA_SERVICE_LIBRARY_KAFKA_KAFKA_TYPE: ${KAFKA_TYPE} DATA_SERVICE_LIBRARY_KAFKA_CONFLUENT_KEY: ${CONFLUENT_KEY} DATA_SERVICE_LIBRARY_KAFKA_CONFLUENT_SECRET: ${CONFLUENT_SECRET} @@ -173,6 +176,9 @@ services: DEPOSIT_GROUP: ${DBCONSUMER_DEPOSIT_GROUP} DEPOSIT_TOPIC: ${DBCONSUMER_DEPOSIT_TOPIC} KAFKA_HOST_SERVER: ${DBCONSUMER_KAFKA_HOST_SERVER} + KAFKA_TYPE: ${KAFKA_TYPE} + CONFLUENT_KEY: ${CONFLUENT_KEY} + CONFLUENT_SECRET: ${CONFLUENT_SECRET} DATA_SERVICE_LIBRARY_KAFKA_KAFKA_TYPE: ${KAFKA_TYPE} DATA_SERVICE_LIBRARY_KAFKA_CONFLUENT_KEY: ${CONFLUENT_KEY} DATA_SERVICE_LIBRARY_KAFKA_CONFLUENT_SECRET: ${CONFLUENT_SECRET} @@ -198,6 +204,9 @@ services: restart: always environment: KAFKA_HOST_SERVER: ${LOGGER_KAFKA_HOST_SERVER} + KAFKA_TYPE: ${KAFKA_TYPE} + CONFLUENT_KEY: ${CONFLUENT_KEY} + CONFLUENT_SECRET: ${CONFLUENT_SECRET} ALERT_ADDRESSES: ${LOGGER_ALERT_ADDRESSES} FROM_EMAIL: ${LOGGER_FROM_EMAIL} ENVIRONMENT_NAME: ${ENVIRONMENT_NAME} From de32dc617e6970779ecabc4b4785aa8a68707b64 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Tue, 8 Apr 2025 07:48:30 -0600 Subject: [PATCH 081/168] Update MilepostController to use try-with-resources --- .../controller/MilepostController.java | 37 +++++++------------ 1 file changed, 13 insertions(+), 24 deletions(-) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/MilepostController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/MilepostController.java index 9292b9e95..c0800c28f 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/MilepostController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/MilepostController.java @@ -350,18 +350,14 @@ public ResponseEntity deleteMilepostCache(@PathVariable String timID) { return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Milepost cache not found for timID: " + timID); } - @RequestMapping(method = RequestMethod.GET, value="/clear-milepost-cache") + @RequestMapping(method = RequestMethod.GET, value = "/clear-milepost-cache") public ResponseEntity clearMilepostCache() { utility.logWithDate("Clearing milepost cache"); List timIDs = new ArrayList<>(milepostCache.keySet()); - Connection connection = null; - Statement statement = null; - ResultSet rs = null; - try { - connection = dbInteractions.getConnectionPool(); - statement = connection.createStatement(); - rs = statement.executeQuery("SELECT client_id FROM active_tim WHERE marked_for_deletion = False"); + try (Connection connection = dbInteractions.getConnectionPool(); + Statement statement = connection.createStatement(); + ResultSet rs = statement.executeQuery("SELECT client_id FROM active_tim WHERE marked_for_deletion = False");) { List activeTimIds = new ArrayList<>(); while (rs.next()) { @@ -374,25 +370,18 @@ public ResponseEntity clearMilepostCache() { milepostCache.remove(timID); } + if (statement != null) + statement.close(); + // return connection back to pool + if (connection != null) + connection.close(); + // close result set + } catch (SQLException e) { e.printStackTrace(); - } finally { - try { - // close prepared statement - if (statement != null) - statement.close(); - // return connection back to pool - if (connection != null) - connection.close(); - // close result set - if (rs != null) - rs.close(); - } catch (SQLException e) { - e.printStackTrace(); - } } - return ResponseEntity.ok("Milepost cache cleared successfully"); - } + return ResponseEntity.ok("Milepost cache cleared successfully"); + } /** * Rewrite of getMilepostsByStartEndPoint used in testing to cut time on geojson From ce34c55bf7f7e07c816580c10a83ae82f11fda2f Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Tue, 8 Apr 2025 08:08:50 -0600 Subject: [PATCH 082/168] Rename MilepostCacheBody to SetMilepostCacheRequest to clarify class intent --- .../cvdatacontroller/controller/MilepostController.java | 4 ++-- ...ilepostCacheBody.java => SetMilepostCacheRequest.java} | 8 ++++---- .../com/trihydro/library/service/MilepostService.java | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) rename cv-data-service-library/src/main/java/com/trihydro/library/model/{MilepostCacheBody.java => SetMilepostCacheRequest.java} (58%) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/MilepostController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/MilepostController.java index c0800c28f..7257e0193 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/MilepostController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/MilepostController.java @@ -19,7 +19,7 @@ import com.trihydro.library.model.Milepost; import com.trihydro.library.model.MilepostBuffer; import com.trihydro.library.model.WydotTim; -import com.trihydro.library.model.MilepostCacheBody; +import com.trihydro.library.model.SetMilepostCacheRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; @@ -312,7 +312,7 @@ public ResponseEntity> } @RequestMapping(method = RequestMethod.POST, value="/set-milepost-cache") - public ResponseEntity setMilepostCache(@RequestBody MilepostCacheBody milepostCacheBody) { + public ResponseEntity setMilepostCache(@RequestBody SetMilepostCacheRequest milepostCacheBody) { utility.logWithDate("Setting milepost cache for timID: " + milepostCacheBody.getTimID()); diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/model/MilepostCacheBody.java b/cv-data-service-library/src/main/java/com/trihydro/library/model/SetMilepostCacheRequest.java similarity index 58% rename from cv-data-service-library/src/main/java/com/trihydro/library/model/MilepostCacheBody.java rename to cv-data-service-library/src/main/java/com/trihydro/library/model/SetMilepostCacheRequest.java index eabc3e1e0..bda604c15 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/model/MilepostCacheBody.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/model/SetMilepostCacheRequest.java @@ -2,11 +2,11 @@ import java.util.List; -public class MilepostCacheBody { - private List mileposts; - private String timID; +public class SetMilepostCacheRequest { + private final List mileposts; + private final String timID; - public MilepostCacheBody(List mileposts, String timID) { + public SetMilepostCacheRequest(List mileposts, String timID) { this.mileposts = mileposts; this.timID = timID; } diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/service/MilepostService.java b/cv-data-service-library/src/main/java/com/trihydro/library/service/MilepostService.java index 1a16394c8..2867998b7 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/service/MilepostService.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/service/MilepostService.java @@ -5,7 +5,7 @@ import com.trihydro.library.model.Milepost; import com.trihydro.library.model.MilepostBuffer; import com.trihydro.library.model.WydotTim; -import com.trihydro.library.model.MilepostCacheBody; +import com.trihydro.library.model.SetMilepostCacheRequest; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpEntity; @@ -46,8 +46,8 @@ public String setMilepostCache(List mileposts, String timID) { String url = String.format("%s/set-milepost-cache", config.getCvRestService()); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); - MilepostCacheBody body = new MilepostCacheBody(mileposts, timID); - HttpEntity entity = new HttpEntity(body, headers); + SetMilepostCacheRequest body = new SetMilepostCacheRequest(mileposts, timID); + HttpEntity entity = new HttpEntity(body, headers); ResponseEntity response = restTemplateProvider.GetRestTemplate().exchange(url, HttpMethod.POST, entity, String.class); return response.getBody(); From f6d13ff79ed918640e45fd801e9259a892d073ba Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Tue, 8 Apr 2025 08:22:00 -0600 Subject: [PATCH 083/168] Update GetRSU method to use parameterized queries and try-with-resources --- .../rsudatacontroller/service/RsuService.java | 67 +++++-------------- 1 file changed, 18 insertions(+), 49 deletions(-) diff --git a/rsu-data-controller/src/main/java/com/trihydro/rsudatacontroller/service/RsuService.java b/rsu-data-controller/src/main/java/com/trihydro/rsudatacontroller/service/RsuService.java index 0a035af89..f59a2f15b 100644 --- a/rsu-data-controller/src/main/java/com/trihydro/rsudatacontroller/service/RsuService.java +++ b/rsu-data-controller/src/main/java/com/trihydro/rsudatacontroller/service/RsuService.java @@ -4,6 +4,7 @@ import java.io.IOException; import java.io.InputStreamReader; import java.sql.Connection; +import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; @@ -129,58 +130,26 @@ private String hexStringToDateTime(String hexString) { return date.format(rsuDateTimeFormatter); } - RSU getRSU(String rsuIpv4Address) throws Exception { - Connection connection = null; - Statement statement = null; - ResultSet rs = null; - RSU rsu = null; - - - try { - connection = dbInteractions.getConnectionPool(); - - statement = connection.createStatement(); - - // select RSU username, password, and firmware type - String selectStatement = "select rc.username, rc.password, sp.nickname FROM rsus " + - "JOIN rsu_credentials AS rc " + // - "ON rsus.snmp_credential_id = rc.credential_id " + // - "JOIN snmp_protocols AS sp " + // - "ON rsus.snmp_protocol_id = sp.snmp_protocol_id " + // - "WHERE rsus.ipv4_address = '" + rsuIpv4Address + "'"; - - rs = statement.executeQuery(selectStatement); - - // parse resultSet - while (rs.next()) { + protected RSU getRSU(String rsuIpv4Address) throws Exception { + // select RSU username, password, and firmware type + String SELECT_RSU_CREDENTIALS = "SELECT rc.username, rc.password, sp.nickname " + + "FROM rsus " + + "JOIN rsu_credentials AS rc ON rsus.snmp_credential_id = rc.credential_id " + + "JOIN snmp_protocols AS sp ON rsus.snmp_protocol_id = sp.snmp_protocol_id " + + "WHERE rsus.ipv4_address = ?"; + try (Connection connection = dbInteractions.getConnectionPool(); + PreparedStatement statement = connection.prepareStatement(SELECT_RSU_CREDENTIALS)) { + statement.setString(1, rsuIpv4Address); // Setting parameter to prevent injection. + try (ResultSet rs = statement.executeQuery()) { + if (!rs.next()) { + utility.logWithDate("Unable to find RSU in database (RSU: " + rsuIpv4Address + ")"); + return null; + } String rsuUsername = rs.getString("username"); String rsuPassword = rs.getString("password"); SnmpProtocol snmpProtocol = rs.getString("nickname").equals("NTCIP 1218") ? SnmpProtocol.NTCIP1218 : SnmpProtocol.FOURDOT1; - - rsu = new RSU(rsuIpv4Address, rsuUsername, rsuPassword, config.getSnmpRetries(), config.getSnmpTimeoutSeconds(), snmpProtocol); + return new RSU(rsuIpv4Address, rsuUsername, rsuPassword, config.getSnmpRetries(), config.getSnmpTimeoutSeconds(), snmpProtocol); } - - - - } catch (SQLException e) { - e.printStackTrace(); - return null; - } finally { - try { - // close prepared statement - if (statement != null) - statement.close(); - // return connection back to pool - if (connection != null) - connection.close(); - // close result set - if (rs != null) - rs.close(); - } catch (SQLException e) { - e.printStackTrace(); - } - } - - return rsu; + } } } \ No newline at end of file From 6b28b1fc2290d0755a90c3ba22809b8cedb5b58a Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Tue, 8 Apr 2025 08:23:29 -0600 Subject: [PATCH 084/168] Update getRSU tests to reflect parameterized query updates --- .../rsudatacontroller/service/RsuServiceTest.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/rsu-data-controller/src/test/java/com/trihydro/rsudatacontroller/service/RsuServiceTest.java b/rsu-data-controller/src/test/java/com/trihydro/rsudatacontroller/service/RsuServiceTest.java index 59315f567..f1932c4b9 100644 --- a/rsu-data-controller/src/test/java/com/trihydro/rsudatacontroller/service/RsuServiceTest.java +++ b/rsu-data-controller/src/test/java/com/trihydro/rsudatacontroller/service/RsuServiceTest.java @@ -14,8 +14,8 @@ import java.io.IOException; import java.io.InputStream; import java.sql.Connection; +import java.sql.PreparedStatement; import java.sql.ResultSet; -import java.sql.Statement; import java.util.List; import com.trihydro.library.helpers.DbInteractions; @@ -193,14 +193,14 @@ public void getRSU_Success() throws Exception { SnmpProtocol snmpProtocol = SnmpProtocol.NTCIP1218; Connection mockConnection = mock(Connection.class); - Statement mockStatement = mock(Statement.class); + PreparedStatement mockStatement = mock(PreparedStatement.class); ResultSet mockResultSet = mock(ResultSet.class); RsuService spyUut = spy(uut); DbInteractions mockDbInteractions = mock(DbInteractions.class); when(mockDbInteractions.getConnectionPool()).thenReturn(mockConnection); - when(mockConnection.createStatement()).thenReturn(mockStatement); - when(mockStatement.executeQuery(anyString())).thenReturn(mockResultSet); + when(mockConnection.prepareStatement(any())).thenReturn(mockStatement); + when(mockStatement.executeQuery()).thenReturn(mockResultSet); when(mockResultSet.next()).thenReturn(true).thenReturn(false); when(mockResultSet.getString("username")).thenReturn(username); when(mockResultSet.getString("password")).thenReturn(password); @@ -229,15 +229,15 @@ public void getRSU_NoResult() throws Exception { String rsuIpv4Address = "192.168.1.1"; Connection mockConnection = mock(Connection.class); - Statement mockStatement = mock(Statement.class); + PreparedStatement mockStatement = mock(PreparedStatement.class); ResultSet mockResultSet = mock(ResultSet.class); DbInteractions mockDbInteractions = mock(DbInteractions.class); RsuService spyUut = spy(uut); when(mockDbInteractions.getConnectionPool()).thenReturn(mockConnection); - when(mockConnection.createStatement()).thenReturn(mockStatement); - when(mockStatement.executeQuery(anyString())).thenReturn(mockResultSet); + when(mockConnection.prepareStatement(any())).thenReturn(mockStatement); + when(mockStatement.executeQuery()).thenReturn(mockResultSet); when(mockResultSet.next()).thenReturn(false); spyUut.dbInteractions = mockDbInteractions; From 5435fc8e6b093550b44c541cf11da563b4f4db22 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Tue, 8 Apr 2025 08:30:10 -0600 Subject: [PATCH 085/168] Move ToMileposts logic to WydotTim class --- .../library/helpers/TimGenerationHelper.java | 10 +--------- .../java/com/trihydro/library/model/WydotTim.java | 14 ++++++++++++++ .../trihydro/library/service/WydotTimService.java | 13 ++++--------- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/TimGenerationHelper.java b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/TimGenerationHelper.java index ff0489b29..761f4d551 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/TimGenerationHelper.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/TimGenerationHelper.java @@ -315,15 +315,7 @@ private List getAllMps(WydotTim wydotTim) { utility.logWithDate("Fetching mileposts for regular TIM with client id: " + wydotTim.getClientId()); if (wydotTim.getEndPoint() != null) { if (wydotTim.getGeometry() != null && wydotTim.getGeometry().size() > 1) { - for (Coordinate coordinate : wydotTim.getGeometry()) { - Milepost milepost = new Milepost(); - milepost.setLatitude(coordinate.getLatitude()); - milepost.setLongitude(coordinate.getLongitude()); - milepost.setDirection(wydotTim.getDirection()); - milepost.setCommonName(wydotTim.getRoute()); - milepost.setMilepost(0.0); - allMps.add(milepost); - } + allMps.addAll(wydotTim.toMileposts()); milepostService.setMilepostCache(allMps, wydotTim.getClientId()); } else { // Check to see if milepost array exists in cache diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/model/WydotTim.java b/cv-data-service-library/src/main/java/com/trihydro/library/model/WydotTim.java index 47a3ac896..b09de0424 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/model/WydotTim.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/model/WydotTim.java @@ -130,4 +130,18 @@ public boolean isGeometryValid() { return false; } } + + public List toMileposts() { + var mileposts = new ArrayList(); + for (Coordinate coordinate : this.getGeometry()) { + Milepost milepost = new Milepost(); + milepost.setLatitude(coordinate.getLatitude()); + milepost.setLongitude(coordinate.getLongitude()); + milepost.setDirection(this.getDirection()); + milepost.setCommonName(this.getRoute()); + milepost.setMilepost(0.0); + mileposts.add(milepost); + } + return mileposts; + } } \ No newline at end of file diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java b/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java index e9a21874b..69f01861b 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java @@ -163,20 +163,15 @@ public List getAllMilepostsForTim(WydotTim wydotTim) { // get mileposts from cache if they exist milepostsAll = milepostService.getMilepostCache(wydotTim.getClientId()); - if (milepostsAll != null && milepostsAll.size() > 0) { + if (milepostsAll != null && !milepostsAll.isEmpty()) { return milepostsAll; } if (wydotTim.getGeometry() != null && wydotTim.getGeometry().size() > 1) { - for (Coordinate coordinate : wydotTim.getGeometry()) { - Milepost milepost = new Milepost(); - milepost.setLatitude(coordinate.getLatitude()); - milepost.setLongitude(coordinate.getLongitude()); - milepost.setDirection(wydotTim.getDirection()); - milepost.setCommonName(wydotTim.getRoute()); - milepost.setMilepost(0.0); - milepostsAll.add(milepost); + if (milepostsAll == null) { + milepostsAll = new ArrayList<>(); } + milepostsAll.addAll(wydotTim.toMileposts()); } else if (wydotTim.getEndPoint() != null && wydotTim.getEndPoint().getLatitude() != null && wydotTim.getEndPoint().getLongitude() != null) { milepostsAll = milepostService.getMilepostsByStartEndPointDirection(wydotTim); From 5404aff86804403b9667a4e383793ba7009bd530 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Tue, 8 Apr 2025 08:39:41 -0600 Subject: [PATCH 086/168] Update getRsusByGeometry to use StringBuilder --- .../java/com/trihydro/library/service/RsuService.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/service/RsuService.java b/cv-data-service-library/src/main/java/com/trihydro/library/service/RsuService.java index a4bb929b3..590518595 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/service/RsuService.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/service/RsuService.java @@ -210,12 +210,15 @@ public List getRsusByLatLong(String direction, Coordinate startPoint, } public List getRsusByGeometry(List geometry) { - String coordinates = "LINESTRING("; + var coordinateBuilder = new StringBuilder("LINESTRING("); + for (Coordinate coordinate : geometry) { - coordinates += coordinate.getLongitude() + " " + coordinate.getLatitude() + ","; + coordinateBuilder.append(coordinate.getLongitude()).append(" ").append(coordinate.getLatitude()).append(","); } - coordinates = coordinates.substring(0, coordinates.length() - 1) + ")"; - List rsus = selectRsusByGeometry(coordinates); + coordinateBuilder.deleteCharAt(coordinateBuilder.length() - 1); + coordinateBuilder.append(")"); + + List rsus = selectRsusByGeometry(coordinateBuilder.toString()); for (WydotRsu rsu : rsus) { rsu.setRsuRetries(3); rsu.setRsuTimeout(5000); From cf74b0514fb1c8f7126cb692da10b3056676bc4d Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Tue, 8 Apr 2025 08:56:24 -0600 Subject: [PATCH 087/168] Extract getActiveTimIds to a separate method for better readability when clearing milepost cache --- .../controller/MilepostController.java | 40 +++++++++---------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/MilepostController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/MilepostController.java index 7257e0193..be644f9d5 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/MilepostController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/MilepostController.java @@ -350,37 +350,33 @@ public ResponseEntity deleteMilepostCache(@PathVariable String timID) { return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Milepost cache not found for timID: " + timID); } - @RequestMapping(method = RequestMethod.GET, value = "/clear-milepost-cache") + @RequestMapping(method = RequestMethod.GET, value="/clear-milepost-cache") public ResponseEntity clearMilepostCache() { utility.logWithDate("Clearing milepost cache"); List timIDs = new ArrayList<>(milepostCache.keySet()); + List activeTimIds = getActiveTimIds(); + // remove all active TIM IDs from the list of milepost cache TIM IDs + timIDs.removeAll(activeTimIds); + for (String timID : timIDs) { + milepostCache.remove(timID); + } + return ResponseEntity.ok("Milepost cache cleared successfully"); + } + private List getActiveTimIds() { + List activeTimIds = new ArrayList<>(); + String sql = "SELECT client_id FROM active_tim WHERE marked_for_deletion = False"; try (Connection connection = dbInteractions.getConnectionPool(); - Statement statement = connection.createStatement(); - ResultSet rs = statement.executeQuery("SELECT client_id FROM active_tim WHERE marked_for_deletion = False");) { - - List activeTimIds = new ArrayList<>(); + Statement statement = connection.createStatement(); + ResultSet rs = statement.executeQuery(sql)) { while (rs.next()) { - String tim_id = rs.getString("CLIENT_ID"); - activeTimIds.add(tim_id); + String timId = rs.getString("CLIENT_ID"); + activeTimIds.add(timId); } - // remove all active TIM IDs from the list of milepost cache TIM IDs - timIDs.removeAll(activeTimIds); - for (String timID : timIDs) { - milepostCache.remove(timID); - } - - if (statement != null) - statement.close(); - // return connection back to pool - if (connection != null) - connection.close(); - // close result set - } catch (SQLException e) { - e.printStackTrace(); + utility.logWithDate("Error retrieving active TIM IDs " + e.toString()); // Improved logging } - return ResponseEntity.ok("Milepost cache cleared successfully"); + return activeTimIds; } /** From 9dc747399698fd175e287410b6ca2c8d5507399e Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Tue, 8 Apr 2025 09:13:14 -0600 Subject: [PATCH 088/168] Add RSU-Specific tables to create_all_tables.sql --- .../pgsql/setup/sql/1-create_all_tables.sql | 192 +++++++++++++++++- 1 file changed, 191 insertions(+), 1 deletion(-) diff --git a/db-scripts/pgsql/setup/sql/1-create_all_tables.sql b/db-scripts/pgsql/setup/sql/1-create_all_tables.sql index af409be51..335534a79 100644 --- a/db-scripts/pgsql/setup/sql/1-create_all_tables.sql +++ b/db-scripts/pgsql/setup/sql/1-create_all_tables.sql @@ -1,5 +1,6 @@ SET client_encoding TO 'UTF8'; - +CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; +CREATE EXTENSION IF NOT EXISTS postgis; -- not part of a dependency relationship -- @@ -513,3 +514,192 @@ ALTER TABLE region_list ALTER COLUMN X_OFFSET SET NOT NULL; ALTER TABLE region_list ALTER COLUMN Y_OFFSET SET NOT NULL; ALTER TABLE region_list ALTER COLUMN Z_OFFSET SET NOT NULL; ALTER TABLE region_list ADD CONSTRAINT fk_old_region_region_list FOREIGN KEY (old_region_id) REFERENCES old_region(old_region_id) ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE; + +-- RSU-Specific Tables + +CREATE SEQUENCE rsu_organization_rsu_organization_id_seq + INCREMENT 1 + START 1 + MINVALUE 1 + MAXVALUE 2147483647 + CACHE 1; + +CREATE TABLE IF NOT EXISTS rsu_organization +( + rsu_organization_id integer NOT NULL DEFAULT nextval('rsu_organization_rsu_organization_id_seq'::regclass), + rsu_id integer NOT NULL, + organization_id integer NOT NULL, + CONSTRAINT rsu_organization_pkey PRIMARY KEY (rsu_organization_id), + CONSTRAINT fk_rsu_id FOREIGN KEY (rsu_id) + REFERENCES rsus (rsu_id) MATCH SIMPLE + ON UPDATE NO ACTION + ON DELETE NO ACTION, + CONSTRAINT fk_organization_id FOREIGN KEY (organization_id) + REFERENCES organizations (organization_id) MATCH SIMPLE + ON UPDATE NO ACTION + ON DELETE NO ACTION +); + +CREATE SEQUENCE manufacturers_manufacturer_id_seq + INCREMENT 1 + START 1 + MINVALUE 1 + MAXVALUE 2147483647 + CACHE 1; + +CREATE TABLE IF NOT EXISTS manufacturers +( + manufacturer_id integer NOT NULL DEFAULT nextval('manufacturers_manufacturer_id_seq'::regclass), + name character varying(128) COLLATE pg_catalog.default NOT NULL, + CONSTRAINT manufacturers_pkey PRIMARY KEY (manufacturer_id), + CONSTRAINT manufacturers_name UNIQUE (name) +); + +CREATE SEQUENCE rsu_models_rsu_model_id_seq + INCREMENT 1 + START 1 + MINVALUE 1 + MAXVALUE 2147483647 + CACHE 1; + +CREATE TABLE IF NOT EXISTS rsu_models +( + rsu_model_id integer NOT NULL DEFAULT nextval('rsu_models_rsu_model_id_seq'::regclass), + name character varying(128) COLLATE pg_catalog.default NOT NULL, + supported_radio character varying(128) COLLATE pg_catalog.default NOT NULL, + manufacturer integer NOT NULL, + CONSTRAINT rsu_models_pkey PRIMARY KEY (rsu_model_id), + CONSTRAINT rsu_models_name UNIQUE (name), + CONSTRAINT fk_manufacturer FOREIGN KEY (manufacturer) + REFERENCES manufacturers (manufacturer_id) MATCH SIMPLE + ON UPDATE NO ACTION + ON DELETE NO ACTION +); + +CREATE SEQUENCE rsu_credentials_credential_id_seq + INCREMENT 1 + START 1 + MINVALUE 1 + MAXVALUE 2147483647 + CACHE 1; + +CREATE TABLE IF NOT EXISTS rsu_credentials +( + credential_id integer NOT NULL DEFAULT nextval('rsu_credentials_credential_id_seq'::regclass), + username character varying(128) COLLATE pg_catalog.default NOT NULL, + password character varying(128) COLLATE pg_catalog.default NOT NULL, + nickname character varying(128) COLLATE pg_catalog.default NOT NULL, + CONSTRAINT rsu_credentials_pkey PRIMARY KEY (credential_id), + CONSTRAINT rsu_credentials_nickname UNIQUE (nickname) +); + +CREATE SEQUENCE snmp_credentials_snmp_credential_id_seq + INCREMENT 1 + START 1 + MINVALUE 1 + MAXVALUE 2147483647 + CACHE 1; + +CREATE TABLE IF NOT EXISTS snmp_credentials +( + snmp_credential_id integer NOT NULL DEFAULT nextval('snmp_credentials_snmp_credential_id_seq'::regclass), + username character varying(128) COLLATE pg_catalog.default NOT NULL, + password character varying(128) COLLATE pg_catalog.default NOT NULL, + encrypt_password character varying(128) COLLATE pg_catalog.default, + nickname character varying(128) COLLATE pg_catalog.default NOT NULL, + CONSTRAINT snmp_credentials_pkey PRIMARY KEY (snmp_credential_id), + CONSTRAINT snmp_credentials_nickname UNIQUE (nickname) +); + +CREATE SEQUENCE snmp_protocols_snmp_protocol_id_seq + INCREMENT 1 + START 1 + MINVALUE 1 + MAXVALUE 2147483647 + CACHE 1; + +CREATE TABLE IF NOT EXISTS snmp_protocols +( + snmp_protocol_id integer NOT NULL DEFAULT nextval('snmp_protocols_snmp_protocol_id_seq'::regclass), + protocol_code character varying(128) COLLATE pg_catalog.default NOT NULL, + nickname character varying(128) COLLATE pg_catalog.default NOT NULL, + CONSTRAINT snmp_protocols_pkey PRIMARY KEY (snmp_protocol_id), + CONSTRAINT snmp_protocols_nickname UNIQUE (nickname) +); + +CREATE SEQUENCE firmware_images_firmware_id_seq + INCREMENT 1 + START 1 + MINVALUE 1 + MAXVALUE 2147483647 + CACHE 1; + +CREATE TABLE IF NOT EXISTS firmware_images +( + firmware_id integer NOT NULL DEFAULT nextval('firmware_images_firmware_id_seq'::regclass), + name character varying(128) COLLATE pg_catalog.default NOT NULL, + model integer NOT NULL, + install_package character varying(128) COLLATE pg_catalog.default NOT NULL, + version character varying(128) COLLATE pg_catalog.default NOT NULL, + CONSTRAINT firmware_images_pkey PRIMARY KEY (firmware_id), + CONSTRAINT firmware_images_name UNIQUE (name), + CONSTRAINT firmware_images_install_package UNIQUE (install_package), + CONSTRAINT firmware_images_version UNIQUE (version), + CONSTRAINT fk_model FOREIGN KEY (model) + REFERENCES rsu_models (rsu_model_id) MATCH SIMPLE + ON UPDATE NO ACTION + ON DELETE NO ACTION +); + +CREATE SEQUENCE rsus_rsu_id_seq + INCREMENT 1 + START 1 + MINVALUE 1 + MAXVALUE 2147483647 + CACHE 1; + +CREATE TABLE IF NOT EXISTS rsus +( + rsu_id integer NOT NULL DEFAULT nextval('rsus_rsu_id_seq'::regclass), + geography geography NOT NULL, + milepost double precision NOT NULL, + ipv4_address inet NOT NULL, + serial_number character varying(128) COLLATE pg_catalog.default NOT NULL, + iss_scms_id character varying(128) COLLATE pg_catalog.default NOT NULL, + primary_route character varying(128) COLLATE pg_catalog.default NOT NULL, + model integer NOT NULL, + credential_id integer NOT NULL, + snmp_credential_id integer NOT NULL, + snmp_protocol_id integer NOT NULL, + firmware_version integer, + target_firmware_version integer, + CONSTRAINT rsu_pkey PRIMARY KEY (rsu_id), + CONSTRAINT rsu_ipv4_address UNIQUE (ipv4_address), + CONSTRAINT rsu_milepost_primary_route UNIQUE (milepost, primary_route), + CONSTRAINT rsu_serial_number UNIQUE (serial_number), + CONSTRAINT rsu_iss_scms_id UNIQUE (iss_scms_id), + CONSTRAINT fk_model FOREIGN KEY (model) + REFERENCES rsu_models (rsu_model_id) MATCH SIMPLE + ON UPDATE NO ACTION + ON DELETE NO ACTION, + CONSTRAINT fk_credential_id FOREIGN KEY (credential_id) + REFERENCES rsu_credentials (credential_id) MATCH SIMPLE + ON UPDATE NO ACTION + ON DELETE NO ACTION, + CONSTRAINT fk_snmp_credential_id FOREIGN KEY (snmp_credential_id) + REFERENCES snmp_credentials (snmp_credential_id) MATCH SIMPLE + ON UPDATE NO ACTION + ON DELETE NO ACTION, + CONSTRAINT fk_snmp_protocol_id FOREIGN KEY (snmp_protocol_id) + REFERENCES snmp_protocols (snmp_protocol_id) MATCH SIMPLE + ON UPDATE NO ACTION + ON DELETE NO ACTION, + CONSTRAINT fk_firmware_version FOREIGN KEY (firmware_version) + REFERENCES firmware_images (firmware_id) MATCH SIMPLE + ON UPDATE NO ACTION + ON DELETE NO ACTION, + CONSTRAINT fk_target_firmware_version FOREIGN KEY (target_firmware_version) + REFERENCES firmware_images (firmware_id) MATCH SIMPLE + ON UPDATE NO ACTION + ON DELETE NO ACTION +); \ No newline at end of file From d124327c4b3bdc79acef31c6d6842f5b7cca4c17 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Tue, 8 Apr 2025 09:44:05 -0600 Subject: [PATCH 089/168] Add RSU-Specific tables from jpo-cvmanager --- .../pgsql/setup/sql/1-create_all_tables.sql | 93 +++++++++++-------- 1 file changed, 54 insertions(+), 39 deletions(-) diff --git a/db-scripts/pgsql/setup/sql/1-create_all_tables.sql b/db-scripts/pgsql/setup/sql/1-create_all_tables.sql index 335534a79..7e40bf548 100644 --- a/db-scripts/pgsql/setup/sql/1-create_all_tables.sql +++ b/db-scripts/pgsql/setup/sql/1-create_all_tables.sql @@ -430,22 +430,6 @@ ALTER TABLE old_region ALTER COLUMN CIRCLE_UNITS SET NOT NULL; ALTER TABLE old_region ADD CONSTRAINT fk_shape_point FOREIGN KEY (shape_point_id) REFERENCES shape_point(shape_point_id) ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE; -CREATE TABLE IF NOT EXISTS tim_rsu ( - tim_rsu_id bigint NOT NULL, - rsu_id bigint NOT NULL, - tim_id bigint NOT NULL, - rsu_index bigint -) ; -ALTER TABLE tim_rsu ADD UNIQUE (rsu_id,tim_id,rsu_index); -ALTER TABLE tim_rsu ADD PRIMARY KEY (tim_rsu_id); -ALTER TABLE tim_rsu ALTER COLUMN TIM_RSU_ID SET NOT NULL; -ALTER TABLE tim_rsu ALTER COLUMN RSU_ID SET NOT NULL; -ALTER TABLE tim_rsu ALTER COLUMN TIM_ID SET NOT NULL; -ALTER TABLE tim_rsu ADD CONSTRAINT sys_c0021538 FOREIGN KEY (rsu_id) REFERENCES rsus(rsu_id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE; - -ALTER TABLE tim_rsu ADD CONSTRAINT sys_c0021539 FOREIGN KEY (tim_id) REFERENCES tim(tim_id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE; - - -- dependent level 3 (dependent on level 2 tables and possibly level 1/level 0 tables) -- CREATE TABLE IF NOT EXISTS data_frame_itis_code ( data_frame_itis_code_id bigint NOT NULL, @@ -517,29 +501,6 @@ ALTER TABLE region_list ADD CONSTRAINT fk_old_region_region_list FOREIGN KEY (ol -- RSU-Specific Tables -CREATE SEQUENCE rsu_organization_rsu_organization_id_seq - INCREMENT 1 - START 1 - MINVALUE 1 - MAXVALUE 2147483647 - CACHE 1; - -CREATE TABLE IF NOT EXISTS rsu_organization -( - rsu_organization_id integer NOT NULL DEFAULT nextval('rsu_organization_rsu_organization_id_seq'::regclass), - rsu_id integer NOT NULL, - organization_id integer NOT NULL, - CONSTRAINT rsu_organization_pkey PRIMARY KEY (rsu_organization_id), - CONSTRAINT fk_rsu_id FOREIGN KEY (rsu_id) - REFERENCES rsus (rsu_id) MATCH SIMPLE - ON UPDATE NO ACTION - ON DELETE NO ACTION, - CONSTRAINT fk_organization_id FOREIGN KEY (organization_id) - REFERENCES organizations (organization_id) MATCH SIMPLE - ON UPDATE NO ACTION - ON DELETE NO ACTION -); - CREATE SEQUENCE manufacturers_manufacturer_id_seq INCREMENT 1 START 1 @@ -702,4 +663,58 @@ CREATE TABLE IF NOT EXISTS rsus REFERENCES firmware_images (firmware_id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE NO ACTION +); + +CREATE TABLE IF NOT EXISTS tim_rsu ( + tim_rsu_id bigint NOT NULL, + rsu_id bigint NOT NULL, + tim_id bigint NOT NULL, + rsu_index bigint +) ; +ALTER TABLE tim_rsu ADD UNIQUE (rsu_id,tim_id,rsu_index); +ALTER TABLE tim_rsu ADD PRIMARY KEY (tim_rsu_id); +ALTER TABLE tim_rsu ALTER COLUMN TIM_RSU_ID SET NOT NULL; +ALTER TABLE tim_rsu ALTER COLUMN RSU_ID SET NOT NULL; +ALTER TABLE tim_rsu ALTER COLUMN TIM_ID SET NOT NULL; +ALTER TABLE tim_rsu ADD CONSTRAINT sys_c0021538 FOREIGN KEY (rsu_id) REFERENCES rsus(rsu_id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE; + +ALTER TABLE tim_rsu ADD CONSTRAINT sys_c0021539 FOREIGN KEY (tim_id) REFERENCES tim(tim_id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE; + +CREATE SEQUENCE public.organizations_organization_id_seq + INCREMENT 1 + START 1 + MINVALUE 1 + MAXVALUE 2147483647 + CACHE 1; + +CREATE TABLE IF NOT EXISTS public.organizations +( + organization_id integer NOT NULL DEFAULT nextval('organizations_organization_id_seq'::regclass), + name character varying(128) COLLATE pg_catalog.default NOT NULL, + email character varying(128) COLLATE pg_catalog.default, + CONSTRAINT organizations_pkey PRIMARY KEY (organization_id), + CONSTRAINT organizations_name UNIQUE (name) +); + +CREATE SEQUENCE rsu_organization_rsu_organization_id_seq + INCREMENT 1 + START 1 + MINVALUE 1 + MAXVALUE 2147483647 + CACHE 1; + +CREATE TABLE IF NOT EXISTS rsu_organization +( + rsu_organization_id integer NOT NULL DEFAULT nextval('rsu_organization_rsu_organization_id_seq'::regclass), + rsu_id integer NOT NULL, + organization_id integer NOT NULL, + CONSTRAINT rsu_organization_pkey PRIMARY KEY (rsu_organization_id), + CONSTRAINT fk_rsu_id FOREIGN KEY (rsu_id) + REFERENCES rsus (rsu_id) MATCH SIMPLE + ON UPDATE NO ACTION + ON DELETE NO ACTION, + CONSTRAINT fk_organization_id FOREIGN KEY (organization_id) + REFERENCES organizations (organization_id) MATCH SIMPLE + ON UPDATE NO ACTION + ON DELETE NO ACTION ); \ No newline at end of file From 767ec6ee7484c91532ab2ef161a76df41f08bb6a Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Tue, 8 Apr 2025 11:38:06 -0600 Subject: [PATCH 090/168] Update WydotTim geometry property access modifier --- .../src/main/java/com/trihydro/library/model/WydotTim.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/model/WydotTim.java b/cv-data-service-library/src/main/java/com/trihydro/library/model/WydotTim.java index b09de0424..917a0f707 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/model/WydotTim.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/model/WydotTim.java @@ -20,7 +20,7 @@ public class WydotTim { @ApiModelProperty(required = true) private String clientId; @ApiModelProperty(required = false) - protected List geometry; + private List geometry; @ApiModelProperty(required = false) private Integer bearing; From fd7535f7d329c35df44e64e3a48bcf039944ec05 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Wed, 9 Apr 2025 07:29:07 -0600 Subject: [PATCH 091/168] Add db env vars to rsu-data-controller, remove duplicate kafka/confluent values --- docker-compose-cdot-deployment.yml | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/docker-compose-cdot-deployment.yml b/docker-compose-cdot-deployment.yml index b42f296bc..614fbe1a2 100644 --- a/docker-compose-cdot-deployment.yml +++ b/docker-compose-cdot-deployment.yml @@ -139,6 +139,9 @@ services: CONFIG_SNMP_AUTH_PASSPHRASE: ${RSUCONTROLLER_CONFIG_SNMP_AUTH_PASSPHRASE} CONFIG_SNMP_AUTH_PROTOCOL: ${RSUCONTROLLER_CONFIG_SNMP_AUTH_PROTOCOL} CONFIG_SNMP_SECURITY_LEVEL: ${RSUCONTROLLER_CONFIG_SNMP_SECURITY_LEVEL} + DB_URL: ${RSUCONTROLLER_DB_URL} + DB_USERNAME: ${RSUCONTROLLER_DB_USERNAME} + DB_PASSWORD: ${RSUCONTROLLER_DB_PASSWORD} logging: options: max-size: "20m" @@ -149,9 +152,6 @@ services: restart: always environment: KAFKA_HOST_SERVER: ${LOGGER_KAFKA_HOST_SERVER} - KAFKA_TYPE: ${KAFKA_TYPE} - CONFLUENT_KEY: ${CONFLUENT_KEY} - CONFLUENT_SECRET: ${CONFLUENT_SECRET} DATA_SERVICE_LIBRARY_KAFKA_KAFKA_TYPE: ${KAFKA_TYPE} DATA_SERVICE_LIBRARY_KAFKA_CONFLUENT_KEY: ${CONFLUENT_KEY} DATA_SERVICE_LIBRARY_KAFKA_CONFLUENT_SECRET: ${CONFLUENT_SECRET} @@ -176,9 +176,6 @@ services: DEPOSIT_GROUP: ${DBCONSUMER_DEPOSIT_GROUP} DEPOSIT_TOPIC: ${DBCONSUMER_DEPOSIT_TOPIC} KAFKA_HOST_SERVER: ${DBCONSUMER_KAFKA_HOST_SERVER} - KAFKA_TYPE: ${KAFKA_TYPE} - CONFLUENT_KEY: ${CONFLUENT_KEY} - CONFLUENT_SECRET: ${CONFLUENT_SECRET} DATA_SERVICE_LIBRARY_KAFKA_KAFKA_TYPE: ${KAFKA_TYPE} DATA_SERVICE_LIBRARY_KAFKA_CONFLUENT_KEY: ${CONFLUENT_KEY} DATA_SERVICE_LIBRARY_KAFKA_CONFLUENT_SECRET: ${CONFLUENT_SECRET} @@ -204,9 +201,9 @@ services: restart: always environment: KAFKA_HOST_SERVER: ${LOGGER_KAFKA_HOST_SERVER} - KAFKA_TYPE: ${KAFKA_TYPE} - CONFLUENT_KEY: ${CONFLUENT_KEY} - CONFLUENT_SECRET: ${CONFLUENT_SECRET} + DATA_SERVICE_LIBRARY_KAFKA_KAFKA_TYPE: ${KAFKA_TYPE} + DATA_SERVICE_LIBRARY_KAFKA_CONFLUENT_KEY: ${CONFLUENT_KEY} + DATA_SERVICE_LIBRARY_KAFKA_CONFLUENT_SECRET: ${CONFLUENT_SECRET} ALERT_ADDRESSES: ${LOGGER_ALERT_ADDRESSES} FROM_EMAIL: ${LOGGER_FROM_EMAIL} ENVIRONMENT_NAME: ${ENVIRONMENT_NAME} From e058545f9c5ed3d7efa33ecc3b506847b3233949 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Wed, 9 Apr 2025 07:50:58 -0600 Subject: [PATCH 092/168] Add kafka vars, rsu controller db vars --- sample.env | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sample.env b/sample.env index 94ba6d673..ca71b5e78 100644 --- a/sample.env +++ b/sample.env @@ -17,6 +17,13 @@ ENVIRONMENT_NAME=DEV SDW_REST_URL= SDW_API_KEY= ######################### +# Kafka Properties +KAFKA_TYPE=local +# These values are only required if KAFKA_TYPE is set to 'confluent' +# More information on setting up Confluent Cloud can be found here: https://www.confluent.io/confluent-cloud/ +CONFLUENT_KEY= +CONFLUENT_SECRET= +######################### # Logger Properties BSM_TOPIC=topic.OdeBsmJson BSM_GROUP_MONGO=group_bsm_mongo_logger @@ -130,6 +137,11 @@ RSUCONTROLLER_CONFIG_SNMP_USER_NAME=username RSUCONTROLLER_CONFIG_SNMP_AUTH_PASSPHRASE= RSUCONTROLLER_CONFIG_SNMP_AUTH_PROTOCOL=SHA RSUCONTROLLER_CONFIG_SNMP_SECURITY_LEVEL=authNoPriv +RSUCONTROLLER_DB_URL=jdbc:postgresql://localhost:5432/dbname?user=username +RSUCONTROLLER_DB_USERNAME=username +RSUCONTROLLER_DB_PASSWORD= +RSUCONTROLLER_MAXIMUM_POOL_SIZE=13 +RSUCONTROLLER_CONNECTION_TIMEOUT=300000 # Data Tasks TASKS_CONFIG_ODE_URL=http://ode-url:8080 From b6f0c8a5626c14dd67ed71bd045ca22f5f40d605 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Wed, 9 Apr 2025 07:51:18 -0600 Subject: [PATCH 093/168] Add additional rsu-data-controller db vars to docker compose files --- docker-compose-cdot-deployment.yml | 2 ++ docker-compose.yml | 5 +++++ local-deployment/docker-compose.yml | 5 +++++ 3 files changed, 12 insertions(+) diff --git a/docker-compose-cdot-deployment.yml b/docker-compose-cdot-deployment.yml index 614fbe1a2..733de75ce 100644 --- a/docker-compose-cdot-deployment.yml +++ b/docker-compose-cdot-deployment.yml @@ -142,6 +142,8 @@ services: DB_URL: ${RSUCONTROLLER_DB_URL} DB_USERNAME: ${RSUCONTROLLER_DB_USERNAME} DB_PASSWORD: ${RSUCONTROLLER_DB_PASSWORD} + MAXIMUM_POOL_SIZE: ${RSUCONTROLLER_MAXIMUM_POOL_SIZE} + CONNECTION_TIMEOUT: ${RSUCONTROLLER_CONNECTION_TIMEOUT} logging: options: max-size: "20m" diff --git a/docker-compose.yml b/docker-compose.yml index 85c111bc5..6359ca4c0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -157,6 +157,11 @@ services: CONFIG_SNMP_AUTH_PASSPHRASE: ${RSUCONTROLLER_CONFIG_SNMP_AUTH_PASSPHRASE} CONFIG_SNMP_AUTH_PROTOCOL: ${RSUCONTROLLER_CONFIG_SNMP_AUTH_PROTOCOL} CONFIG_SNMP_SECURITY_LEVEL: ${RSUCONTROLLER_CONFIG_SNMP_SECURITY_LEVEL} + DB_URL: ${RSUCONTROLLER_DB_URL} + DB_USERNAME: ${RSUCONTROLLER_DB_USERNAME} + DB_PASSWORD: ${RSUCONTROLLER_DB_PASSWORD} + MAXIMUM_POOL_SIZE: ${RSUCONTROLLER_MAXIMUM_POOL_SIZE} + CONNECTION_TIMEOUT: ${RSUCONTROLLER_CONNECTION_TIMEOUT} logging: options: max-size: "20m" diff --git a/local-deployment/docker-compose.yml b/local-deployment/docker-compose.yml index b68e7e498..66f039859 100644 --- a/local-deployment/docker-compose.yml +++ b/local-deployment/docker-compose.yml @@ -247,6 +247,11 @@ services: CONFIG_SNMP_AUTH_PASSPHRASE: testpassword CONFIG_SNMP_AUTH_PROTOCOL: SHA CONFIG_SNMP_SECURITY_LEVEL: authNoPriv + DB_URL: jdbc:postgresql://${POSTGRES_DB_HOSTNAME}:5432/${POSTGRES_DB_NAME}?user=${POSTGRES_USER} + DB_USERNAME: ${POSTGRES_USER} + DB_PASSWORD: ${POSTGRES_PASSWORD} + MAXIMUM_POOL_SIZE: 13 + CONNECTION_TIMEOUT: 300000 logging: options: max-size: "20m" From 35bbc03e0efb1f7b8e11bff4e480eccda7d0e635 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Wed, 16 Apr 2025 14:24:53 -0600 Subject: [PATCH 094/168] Update UpstreamPathController to find closest milepost with 1 mile starting buffer --- .../controller/CdotUpstreamPathController.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java index ffc600920..95fb09781 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/CdotUpstreamPathController.java @@ -176,16 +176,25 @@ private int getIndexOfMilepost(List mileposts, Milepost milepost) { } BigDecimal latitude = milepost.getLatitude().setScale(14, RoundingMode.HALF_UP); BigDecimal longitude = milepost.getLongitude().setScale(14, RoundingMode.HALF_UP); + // Roughly a 1-mile starting buffer + BigDecimal latDifference = new BigDecimal(0.015); + BigDecimal lonDifference = new BigDecimal(0.015); + int closestIndex = -1; for (int i = 0; i < mileposts.size(); i++) { Milepost currentMilepost = mileposts.get(i); BigDecimal currentLatitude = currentMilepost.getLatitude().setScale(14, RoundingMode.HALF_UP); BigDecimal currentLongitude = currentMilepost.getLongitude().setScale(14, RoundingMode.HALF_UP); - if (latitude.equals(currentLatitude) && longitude.equals(currentLongitude)) { - return i; + + // If the current milepost is closer, update the closest index + if (latDifference.compareTo(latitude.subtract(currentLatitude).abs()) > 0 + && lonDifference.compareTo(longitude.subtract(currentLongitude).abs()) > 0) { + latDifference = latitude.subtract(currentLatitude).abs(); + lonDifference = longitude.subtract(currentLongitude).abs(); + closestIndex = i; } } - return -1; + return closestIndex; } private String convertMilepostsToGeojsonString(List mileposts) { From fd20d4d0ba1de1164d3f2bdf9a38a075398e0700 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Wed, 16 Apr 2025 14:25:15 -0600 Subject: [PATCH 095/168] Add Connecting the West ITIS codes to 03-itis_code.sql --- .../pgsql/static-data/sql/03-itis_code.sql | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/db-scripts/pgsql/static-data/sql/03-itis_code.sql b/db-scripts/pgsql/static-data/sql/03-itis_code.sql index 3b238de62..5d95c1eae 100644 --- a/db-scripts/pgsql/static-data/sql/03-itis_code.sql +++ b/db-scripts/pgsql/static-data/sql/03-itis_code.sql @@ -50,6 +50,7 @@ INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (3 INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (4,E'Hazardous material spill',2,550); INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (5,E'Closed',2,770); INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (6,E'Closed for the season',2,774); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (7,E'Closed to traffic',2,769); INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (8,E'Avalanche control activities',2,1042); INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (10,E'Herd of animals on roadway',2,1292); INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (11,E'Landslide',2,1310); @@ -96,6 +97,7 @@ INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (4 -- BOWR ITIS CODES (5127, 2563, 2569, 7682, 2577, 8739 and 11589-11607) INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (26,E'Strong winds',2,5127); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (27,E'Gusty winds',2, 5131); INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (428,E'Truck restriction',2,2563); INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (429,E'No high profile vehicles',2,2569); INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (430,E'Below',2,7682); @@ -121,5 +123,53 @@ INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (4 INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (450,E'65000',1,11606); INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (451,E'70000',1,11607); +-- Connecting the West ITIS Codes +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (500,E'May Exceed',2,7759); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (501,E'Dense Fog',2,5377); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (502,E'Slippery',2,5897); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (503,E'Ahead',2,13569); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (504,E'Right Lane',3,8196); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (505,E'Left Lane',3,8195); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (506,E'Center Lane',3,8197); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (507,E'Blocked Ahead',3,776); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (508,E'Closed Ahead',3,771); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (509,E'Right',3,13579); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (510,E'Left',3,13580); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (511,E'Lane',3,13588); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (512,E'Right Shoulder',3,8208); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (513,E'Left Shoulder',3,8209); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (514,E'Both Directions of Travel',3,13593); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (515,E'End',3,13583); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (516,E'Reduced',1,12302); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (517,E'Advice',2,7712); + +-- Small Number Values +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (530,E'0',1,12542); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (531,E'1',1,12543); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (532,E'2',1,12544); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (533,E'3',1,12545); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (534,E'4',1,12546); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (535,E'5',1,12547); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (536,E'6',1,12548); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (537,E'7',1,12549); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (538,E'8',1,12550); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (539,E'9',1,12551); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (540,E'10',1,12552); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (541,E'15',1,12557); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (542,E'20',1,12562); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (543,E'25',1,12567); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (544,E'30',1,12572); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (545,E'35',1,12577); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (546,E'40',1,12582); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (547,E'45',1,12587); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (548,E'50',1,12592); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (549,E'55',1,12597); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (550,E'60',1,12602); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (551,E'65',1,12607); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (552,E'70',1,12612); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (553,E'75',1,12617); +INSERT INTO itis_code (itis_code_id,description,category_id,itis_code) VALUES (554,E'80',1,12622); + + COMMIT; From e4962fbb6dda958fbb142d626f066c398f78d24c Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Wed, 16 Apr 2025 14:27:17 -0600 Subject: [PATCH 096/168] Add milepost service, bufferTIMItisCodes list, milepostToGeometry method for calculating buffer TIM --- .../controller/WydotTimBaseController.java | 39 ++++++++++++------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java index c645fcc93..488af9efb 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java @@ -11,7 +11,6 @@ import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; import java.util.ArrayList; -import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.TimeZone; @@ -30,6 +29,7 @@ import com.trihydro.library.model.WydotTimRw; import com.trihydro.library.model.WydotTravelerInputData; import com.trihydro.library.service.ActiveTimService; +import com.trihydro.library.service.MilepostService; import com.trihydro.library.service.RestTemplateProvider; import com.trihydro.library.service.TimTypeService; import com.trihydro.library.service.WydotTimService; @@ -55,20 +55,22 @@ public abstract class WydotTimBaseController { protected WydotTimService wydotTimService; protected TimTypeService timTypeService; private TimType timType = null; - private SetItisCodes setItisCodes; + private final SetItisCodes setItisCodes; protected ActiveTimService activeTimService; protected RestTemplateProvider restTemplateProvider; MilepostReduction milepostReduction; protected Utility utility; protected TimGenerationHelper timGenerationHelper; + protected MilepostService milepostService; protected static Gson gson = new Gson(); private List timTypes; + protected final List bufferTimITISCodes; public WydotTimBaseController(BasicConfiguration _basicConfiguration, WydotTimService _wydotTimService, TimTypeService _timTypeService, SetItisCodes _setItisCodes, ActiveTimService _activeTimService, RestTemplateProvider _restTemplateProvider, MilepostReduction _milepostReduction, Utility _utility, - TimGenerationHelper _timGenerationHelper) { + TimGenerationHelper _timGenerationHelper, MilepostService _milepostService) { configuration = _basicConfiguration; wydotTimService = _wydotTimService; timTypeService = _timTypeService; @@ -78,6 +80,9 @@ public WydotTimBaseController(BasicConfiguration _basicConfiguration, WydotTimSe milepostReduction = _milepostReduction; utility = _utility; timGenerationHelper = _timGenerationHelper; + milepostService = _milepostService; + // closed-ahead, blocked-ahead, and ahead ITIS codes + bufferTimITISCodes = List.of(771, 776, 13569); } protected String getStartTime() { @@ -104,7 +109,7 @@ protected String getIsoDateTimeString(ZonedDateTime date) { protected ControllerResult validateInputParking(WydotTimParking tim) { ControllerResult result = new ControllerResult(); - List resultMessages = new ArrayList(); + List resultMessages = new ArrayList<>(); // get route number if (tim.getDirection() != null) @@ -134,7 +139,7 @@ protected ControllerResult validateInputParking(WydotTimParking tim) { // set itis codes List itisCodes = setItisCodes.setItisCodesParking(tim); - if (itisCodes.size() == 0) + if (itisCodes.isEmpty()) resultMessages.add("No ITIS codes found"); result.setItisCodes(itisCodes); tim.setItisCodes(itisCodes); @@ -146,7 +151,7 @@ protected ControllerResult validateInputParking(WydotTimParking tim) { public ControllerResult validateInputIncident(WydotTimIncident tim) { ControllerResult result = new ControllerResult(); - List resultMessages = new ArrayList(); + List resultMessages = new ArrayList<>(); // get route number if (tim.getDirection() != null) @@ -180,8 +185,8 @@ public ControllerResult validateInputIncident(WydotTimIncident tim) { } // set itis codes - List itisCodes = setItisCodes.setItisCodesIncident(tim); - if (itisCodes.size() == 0) + List itisCodes = setItisCodes.setItisCodes(tim); + if (itisCodes.isEmpty()) resultMessages.add("No ITIS codes found"); result.setItisCodes(itisCodes); tim.setItisCodes(itisCodes); @@ -281,8 +286,8 @@ protected ControllerResult validateInputRw(WydotTimRw tim) { } // set itis codes - List itisCodes = setItisCodes.setItisCodesRw(tim); - if (itisCodes.size() == 0) + List itisCodes = setItisCodes.setItisCodes(tim); + if (itisCodes.isEmpty()) resultMessages.add("No ITIS codes found"); result.setItisCodes(itisCodes); tim.setItisCodes(itisCodes); @@ -386,7 +391,7 @@ protected ControllerResult validateRcAc(WydotTimRc allClear) { protected ControllerResult validateInputVsl(WydotTimVsl tim) { ControllerResult result = new ControllerResult(); - List resultMessages = new ArrayList(); + List resultMessages = new ArrayList<>(); // get route number if (tim.getDirection() != null) @@ -423,7 +428,7 @@ protected ControllerResult validateInputVsl(WydotTimVsl tim) { // set itis codes List itisCodes = setItisCodes.setItisCodesVsl(tim); - if (itisCodes.size() == 0) + if (itisCodes.isEmpty()) resultMessages.add("No ITIS codes found"); result.setItisCodes(itisCodes); tim.setItisCodes(itisCodes); @@ -655,7 +660,7 @@ protected void expireReduceCreateSendTims(WydotTim wydotTim, TimType timType, St List milepostsAll = wydotTimService.getAllMilepostsForTim(wydotTim); // Expire existing tims - List existingTimIds = new ArrayList(); + List existingTimIds = new ArrayList<>(); for (ActiveTim existingTim : existingTims) { existingTimIds.add(existingTim.getActiveTimId()); } @@ -727,4 +732,12 @@ private Milepost getAnchorPoint(Milepost firstPoint, Milepost secondPoint) { anchor.setDirection(firstPoint.getDirection()); return anchor; } + + public List milepostToGeometry(List mileposts) { + var timGeometry = new ArrayList(); + for (Milepost milepost : mileposts) { + timGeometry.add(new Coordinate(milepost.getLatitude(), milepost.getLongitude())); + } + return timGeometry; + } } \ No newline at end of file From 30c99551cbfbea35b1ace3a67ccccc97041ecbc3 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Wed, 16 Apr 2025 14:27:57 -0600 Subject: [PATCH 097/168] Add milepostService to WydotTim controllers --- .../controller/UtilityController.java | 5 +++-- .../controller/WydotTimBowrController.java | 5 +++-- .../controller/WydotTimCcController.java | 5 +++-- .../controller/WydotTimParkingController.java | 5 +++-- .../controller/WydotTimRcController.java | 18 +++++++++--------- 5 files changed, 21 insertions(+), 17 deletions(-) diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/UtilityController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/UtilityController.java index 40e4a1653..0ce1fca0a 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/UtilityController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/UtilityController.java @@ -14,6 +14,7 @@ import com.trihydro.library.model.TimQuery; import com.trihydro.library.model.WydotRsu; import com.trihydro.library.service.ActiveTimService; +import com.trihydro.library.service.MilepostService; import com.trihydro.library.service.OdeService; import com.trihydro.library.service.RestTemplateProvider; import com.trihydro.library.service.TimTypeService; @@ -57,9 +58,9 @@ class RsuClearSuccess { public UtilityController(BasicConfiguration _basicConfiguration, WydotTimService _wydotTimService, TimTypeService _timTypeService, SetItisCodes _setItisCodes, ActiveTimService _activeTimService, OdeService _odeService, RestTemplateProvider _restTemplateProvider, MilepostReduction _milepostReduction, - Utility _utility, TimGenerationHelper _timGenerationHelper) { + Utility _utility, TimGenerationHelper _timGenerationHelper, MilepostService _milepostService) { super(_basicConfiguration, _wydotTimService, _timTypeService, _setItisCodes, _activeTimService, - _restTemplateProvider, _milepostReduction, _utility, _timGenerationHelper); + _restTemplateProvider, _milepostReduction, _utility, _timGenerationHelper, _milepostService); this.odeService = _odeService; } diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBowrController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBowrController.java index fc392c927..752026737 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBowrController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBowrController.java @@ -10,6 +10,7 @@ import com.trihydro.library.model.ContentEnum; import com.trihydro.library.model.WydotTim; import com.trihydro.library.service.ActiveTimService; +import com.trihydro.library.service.MilepostService; import com.trihydro.library.service.RestTemplateProvider; import com.trihydro.library.service.TimTypeService; import com.trihydro.library.service.WydotTimService; @@ -43,9 +44,9 @@ public class WydotTimBowrController extends WydotTimBaseController { public WydotTimBowrController(BasicConfiguration _basicConfiguration, WydotTimService _wydotTimService, TimTypeService _timTypeService, SetItisCodes _setItisCodes, ActiveTimService _activeTimService, RestTemplateProvider _restTemplateProvider, MilepostReduction _milepostReduction, Utility _utility, - TimGenerationHelper _timGenerationHelper) { + TimGenerationHelper _timGenerationHelper, MilepostService _milepostService) { super(_basicConfiguration, _wydotTimService, _timTypeService, _setItisCodes, _activeTimService, - _restTemplateProvider, _milepostReduction, _utility, _timGenerationHelper); + _restTemplateProvider, _milepostReduction, _utility, _timGenerationHelper, _milepostService); } @RequestMapping(value = "/create-or-update-bowr-tim", method = RequestMethod.POST, headers = "Accept=application/json") diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimCcController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimCcController.java index aa9d91f41..7321e9f4e 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimCcController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimCcController.java @@ -12,6 +12,7 @@ import com.trihydro.library.model.ContentEnum; import com.trihydro.library.model.WydotTim; import com.trihydro.library.service.ActiveTimService; +import com.trihydro.library.service.MilepostService; import com.trihydro.library.service.RestTemplateProvider; import com.trihydro.library.service.TimTypeService; import com.trihydro.library.service.WydotTimService; @@ -44,9 +45,9 @@ public class WydotTimCcController extends WydotTimBaseController { public WydotTimCcController(BasicConfiguration _basicConfiguration, WydotTimService _wydotTimService, TimTypeService _timTypeService, SetItisCodes _setItisCodes, ActiveTimService _activeTimService, RestTemplateProvider _restTemplateProvider, MilepostReduction _milepostReduction, Utility _utility, - TimGenerationHelper _timGenerationHelper) { + TimGenerationHelper _timGenerationHelper, MilepostService _milepostService) { super(_basicConfiguration, _wydotTimService, _timTypeService, _setItisCodes, _activeTimService, - _restTemplateProvider, _milepostReduction, _utility, _timGenerationHelper); + _restTemplateProvider, _milepostReduction, _utility, _timGenerationHelper, _milepostService); } @RequestMapping(value = "/cc-tim", method = RequestMethod.POST, headers = "Accept=application/json") diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimParkingController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimParkingController.java index e2a46b08d..041a49a60 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimParkingController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimParkingController.java @@ -13,6 +13,7 @@ import com.trihydro.library.model.ActiveTim; import com.trihydro.library.model.ContentEnum; import com.trihydro.library.service.ActiveTimService; +import com.trihydro.library.service.MilepostService; import com.trihydro.library.service.RestTemplateProvider; import com.trihydro.library.service.TimTypeService; import com.trihydro.library.service.WydotTimService; @@ -46,9 +47,9 @@ public class WydotTimParkingController extends WydotTimBaseController { public WydotTimParkingController(BasicConfiguration _basicConfiguration, WydotTimService _wydotTimService, TimTypeService _timTypeService, SetItisCodes _setItisCodes, ActiveTimService _activeTimService, RestTemplateProvider _restTemplateProvider, MilepostReduction _milepostReduction, Utility _utility, - TimGenerationHelper _timGenerationHelper) { + TimGenerationHelper _timGenerationHelper, MilepostService _milepostService) { super(_basicConfiguration, _wydotTimService, _timTypeService, _setItisCodes, _activeTimService, - _restTemplateProvider, _milepostReduction, _utility, _timGenerationHelper); + _restTemplateProvider, _milepostReduction, _utility, _timGenerationHelper, _milepostService); } @RequestMapping(value = "/parking-tim", method = RequestMethod.POST, headers = "Accept=application/json") diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRcController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRcController.java index a73d87f2c..deac6a1dc 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRcController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRcController.java @@ -31,6 +31,8 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; +import com.trihydro.library.service.MilepostService; + import io.swagger.annotations.Api; import us.dot.its.jpo.ode.plugin.j2735.timstorage.FrameType.TravelerInfoType; @@ -46,9 +48,9 @@ public class WydotTimRcController extends WydotTimBaseController { public WydotTimRcController(BasicConfiguration _basicConfiguration, WydotTimService _wydotTimService, TimTypeService _timTypeService, SetItisCodes _setItisCodes, ActiveTimService _activeTimService, RestTemplateProvider _restTemplateProvider, MilepostReduction _milepostReduction, Utility _utility, - TimGenerationHelper _timGenerationHelper) { + TimGenerationHelper _timGenerationHelper, MilepostService _milepostService) { super(_basicConfiguration, _wydotTimService, _timTypeService, _setItisCodes, _activeTimService, - _restTemplateProvider, _milepostReduction, _utility, _timGenerationHelper); + _restTemplateProvider, _milepostReduction, _utility, _timGenerationHelper, _milepostService); configuration = _basicConfiguration; } @@ -159,13 +161,11 @@ public ResponseEntity submitAllClearRoadConditionsTim(@RequestBody TimRc public void processRequestAsync(List wydotTims) { // An Async task always executes in new thread - new Thread(new Runnable() { - public void run() { - var startTime = getStartTime(); - for (WydotTim tim : wydotTims) { - processRequest(tim, getTimType(type), startTime, null, null, ContentEnum.advisory, - TravelerInfoType.advisory); - } + new Thread(() -> { + var startTime = getStartTime(); + for (WydotTim tim : wydotTims) { + processRequest(tim, getTimType(type), startTime, null, null, ContentEnum.advisory, + TravelerInfoType.advisory); } }).start(); } From e857ee6b1c6b08b51da79acc6785fceff1ac8aca Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Wed, 16 Apr 2025 14:32:58 -0600 Subject: [PATCH 098/168] Add milepostService to VSL controller --- .../odewrapper/controller/WydotTimVslController.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimVslController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimVslController.java index 2a0854462..5b4414247 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimVslController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimVslController.java @@ -14,6 +14,7 @@ import com.trihydro.library.model.ContentEnum; import com.trihydro.library.model.WydotTim; import com.trihydro.library.service.ActiveTimService; +import com.trihydro.library.service.MilepostService; import com.trihydro.library.service.RestTemplateProvider; import com.trihydro.library.service.TimTypeService; import com.trihydro.library.service.WydotTimService; @@ -46,9 +47,9 @@ public class WydotTimVslController extends WydotTimBaseController { public WydotTimVslController(BasicConfiguration _basicConfiguration, WydotTimService _wydotTimService, TimTypeService _timTypeService, SetItisCodes _setItisCodes, ActiveTimService _activeTimService, RestTemplateProvider _restTemplateProvider, MilepostReduction _milepostReduction, Utility _utility, - TimGenerationHelper _timGenerationHelper) { + TimGenerationHelper _timGenerationHelper, MilepostService _milepostService) { super(_basicConfiguration, _wydotTimService, _timTypeService, _setItisCodes, _activeTimService, - _restTemplateProvider, _milepostReduction, _utility, _timGenerationHelper); + _restTemplateProvider, _milepostReduction, _utility, _timGenerationHelper, _milepostService); } @RequestMapping(value = "/vsl-tim", method = RequestMethod.POST, headers = "Accept=application/json") From 5c5470fcd1c3b6b1b3c1315219e85984835cd405 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Wed, 16 Apr 2025 14:37:34 -0600 Subject: [PATCH 099/168] Add milepost service to Incident Controller --- .../WydotTimIncidentController.java | 45 ++++++++++--------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java index ad72b610a..1347c8fbc 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java @@ -6,6 +6,7 @@ import java.util.Collection; import java.util.Date; import java.util.List; + import com.trihydro.library.helpers.MilepostReduction; import com.trihydro.library.helpers.TimGenerationHelper; import com.trihydro.library.helpers.Utility; @@ -31,6 +32,8 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; +import com.trihydro.library.service.MilepostService; + import io.swagger.annotations.Api; import us.dot.its.jpo.ode.plugin.j2735.timstorage.FrameType.TravelerInfoType; @@ -45,9 +48,9 @@ public class WydotTimIncidentController extends WydotTimBaseController { public WydotTimIncidentController(BasicConfiguration _basicConfiguration, WydotTimService _wydotTimService, TimTypeService _timTypeService, SetItisCodes _setItisCodes, ActiveTimService _activeTimService, RestTemplateProvider _restTemplateProvider, MilepostReduction _milepostReduction, Utility _utility, - TimGenerationHelper _timGenerationHelper) { + TimGenerationHelper _timGenerationHelper, MilepostService _milepostService) { super(_basicConfiguration, _wydotTimService, _timTypeService, _setItisCodes, _activeTimService, - _restTemplateProvider, _milepostReduction, _utility, _timGenerationHelper); + _restTemplateProvider, _milepostReduction, _utility, _timGenerationHelper, _milepostService); } @RequestMapping(value = "/incident-tim", method = RequestMethod.POST, headers = "Accept=application/json") @@ -58,19 +61,19 @@ public ResponseEntity createIncidentTim(@RequestBody TimIncidentList tim utility.logWithDate(dateFormat.format(date) + " - Create Incident TIM", this.getClass()); String post = gson.toJson(timIncidentList); - utility.logWithDate(post.toString(), this.getClass()); + utility.logWithDate(post, this.getClass()); - List timsToSend = new ArrayList(); + List timsToSend = new ArrayList<>(); - List resultList = new ArrayList(); - ControllerResult resultTim = null; + List resultList = new ArrayList<>(); + ControllerResult resultTim; // build TIM for (WydotTimIncident wydotTim : timIncidentList.getTimIncidentList()) { resultTim = validateInputIncident(wydotTim); - if (resultTim.getResultMessages().size() > 0) { + if (!resultTim.getResultMessages().isEmpty()) { resultList.add(resultTim); continue; } @@ -96,18 +99,18 @@ public ResponseEntity updateIncidentTim(@RequestBody TimIncidentList tim utility.logWithDate(dateFormat.format(date) + " - Update Incident TIM", this.getClass()); String post = gson.toJson(timIncidentList); - utility.logWithDate(post.toString(), this.getClass()); + utility.logWithDate(post, this.getClass()); - List resultList = new ArrayList(); - ControllerResult resultTim = null; - List timsToSend = new ArrayList(); + List resultList = new ArrayList<>(); + ControllerResult resultTim; + List timsToSend = new ArrayList<>(); // delete TIMs for (WydotTimIncident wydotTim : timIncidentList.getTimIncidentList()) { resultTim = validateInputIncident(wydotTim); - if (resultTim.getResultMessages().size() > 0) { + if (!resultTim.getResultMessages().isEmpty()) { resultList.add(resultTim); continue; } @@ -118,7 +121,7 @@ public ResponseEntity updateIncidentTim(@RequestBody TimIncidentList tim resultTim.getResultMessages().add("success"); resultList.add(resultTim); } - if (timsToSend.size() > 0) { + if (!timsToSend.isEmpty()) { // make tims, expire existing ones, and send them makeTimsAsync(timsToSend); } @@ -129,15 +132,13 @@ public ResponseEntity updateIncidentTim(@RequestBody TimIncidentList tim public void makeTimsAsync(List wydotTims) { - new Thread(new Runnable() { - public void run() { - var startTime = getStartTime(); - for (WydotTimIncident wydotTim : wydotTims) { - // set route - wydotTim.setRoute(wydotTim.getHighway()); - processRequest(wydotTim, getTimType(type), startTime, null, wydotTim.getPk(), ContentEnum.advisory, - TravelerInfoType.advisory); - } + new Thread(() -> { + var startTime = getStartTime(); + for (WydotTimIncident wydotTim : wydotTims) { + // set route + wydotTim.setRoute(wydotTim.getRoute()); + processRequest(wydotTim, getTimType(type), startTime, null, wydotTim.getPk(), ContentEnum.advisory, + TravelerInfoType.advisory); } }).start(); } From a77517795b93dbbd1159e845b873fc66d2cddf1d Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Wed, 16 Apr 2025 15:17:41 -0600 Subject: [PATCH 100/168] Remove duplicate code from TIM generation logic, add buffer generation --- .../controller/WydotTimRwController.java | 224 +++++------------- 1 file changed, 61 insertions(+), 163 deletions(-) diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java index 91e6b111e..92dd5e91c 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java @@ -1,7 +1,7 @@ package com.trihydro.odewrapper.controller; -import java.math.BigDecimal; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Comparator; import java.util.List; @@ -12,7 +12,7 @@ import com.trihydro.library.model.ActiveTim; import com.trihydro.library.model.Buffer; import com.trihydro.library.model.ContentEnum; -import com.trihydro.library.model.Coordinate; +import com.trihydro.library.model.Milepost; import com.trihydro.library.model.TimRwList; import com.trihydro.library.model.WydotTimRw; import com.trihydro.library.service.ActiveTimService; @@ -24,9 +24,6 @@ import com.trihydro.odewrapper.model.ControllerResult; import org.apache.commons.lang3.StringUtils; -import org.gavaghan.geodesy.Ellipsoid; -import org.gavaghan.geodesy.GeodeticCalculator; -import org.gavaghan.geodesy.GlobalCoordinates; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -37,6 +34,8 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; +import com.trihydro.library.service.MilepostService; + import io.swagger.annotations.Api; import us.dot.its.jpo.ode.plugin.j2735.timstorage.FrameType.TravelerInfoType; @@ -52,20 +51,20 @@ public class WydotTimRwController extends WydotTimBaseController { public WydotTimRwController(BasicConfiguration _basicConfiguration, WydotTimService _wydotTimService, TimTypeService _timTypeService, SetItisCodes _setItisCodes, ActiveTimService _activeTimService, RestTemplateProvider _restTemplateProvider, MilepostReduction _milepostReduction, Utility _utility, - TimGenerationHelper _timGenerationHelper) { + TimGenerationHelper _timGenerationHelper, MilepostService _milepostService) { super(_basicConfiguration, _wydotTimService, _timTypeService, _setItisCodes, _activeTimService, - _restTemplateProvider, _milepostReduction, _utility, _timGenerationHelper); + _restTemplateProvider, _milepostReduction, _utility, _timGenerationHelper, _milepostService); } @RequestMapping(value = "/rw-tim", method = RequestMethod.POST, headers = "Accept=application/json") public ResponseEntity createRoadContructionTim(@RequestBody TimRwList timRwList) { utility.logWithDate("Create/Update RW TIM", this.getClass()); String post = gson.toJson(timRwList); - utility.logWithDate(post.toString(), this.getClass()); + utility.logWithDate(post, this.getClass()); - List resultList = new ArrayList(); - ControllerResult resultTim = null; - timsToSend = new ArrayList(); + List resultList = new ArrayList<>(); + ControllerResult resultTim; + timsToSend = new ArrayList<>(); // build TIM for (WydotTimRw wydotTim : timRwList.getTimRwList()) { @@ -74,7 +73,7 @@ public ResponseEntity createRoadContructionTim(@RequestBody TimRwList ti resultTim = validateInputRw(wydotTim); // if there are invalidation messages skip to next TIM - if (resultTim.getResultMessages().size() > 0) { + if (!resultTim.getResultMessages().isEmpty()) { resultList.add(resultTim); continue; } @@ -112,183 +111,82 @@ else if (wydotTim.getDirection().equalsIgnoreCase("i")) { } public void makeIncreasingTims(WydotTimRw wydotTim) { - // i - add buffer for point TIMs - WydotTimRw timOneWay = wydotTim.copy(); - if (StringUtils.isBlank(timOneWay.getSchedStart())) { - String startTime = getStartTime(); - timOneWay.setSchedStart(startTime); - } - + WydotTimRw timOneWay = copyTimWithStartDate(wydotTim); timOneWay.setDirection("I"); - timsToSend.add(timOneWay); - if (timOneWay.getBuffers() != null) - makeIncreasingBufferTim(timOneWay); + addTimsToSend(timOneWay, false); + + makeBufferTims(timOneWay); } public void makeDecreasingTims(WydotTimRw wydotTim) { - // d - add buffer for point TIMs + WydotTimRw timOneWay = copyTimWithStartDate(wydotTim); + timOneWay.setDirection("D"); + + addTimsToSend(timOneWay, false); + makeBufferTims(timOneWay); + } + + private WydotTimRw copyTimWithStartDate(WydotTimRw wydotTim) { WydotTimRw timOneWay = wydotTim.copy(); if (StringUtils.isBlank(timOneWay.getSchedStart())) { String startTime = getStartTime(); timOneWay.setSchedStart(startTime); } - - timOneWay.setDirection("D"); - timsToSend.add(timOneWay); - if (timOneWay.getBuffers() != null) - makeDecreasingBufferTim(timOneWay); - } - - private double getIBearingForRoute(String route) { - // TODO: this needs to call out to the DIRECTION_EXCEPTION view and compare - // mileage to determine direction - Integer numericRoute = Integer.parseInt(route.replaceAll("\\D+", "")); - if (numericRoute % 2 == 0) { - return 270; - } - return 180; + return timOneWay; } - private double getDBearingForRoute(String route) { - // TODO: this needs to call out to the DIRECTION_EXCEPTION view and compare - // mileage to determine direction - Integer numericRoute = Integer.parseInt(route.replaceAll("\\D+", "")); - if (numericRoute % 2 == 0) { - return 90; - } - return 0; - } + private void addTimsToSend(WydotTimRw tim, boolean isBuffer) { + for (String itisCodeEntry : tim.getItisCodes()) { + // CTW Update requires that individual TIMs are created for each ITIS ordering + List itisCodes = Arrays.asList(itisCodeEntry.split(" ")); - private double getTimBearing(WydotTimRw wydotTim) { - if (wydotTim.getBearing() != null) { - switch (wydotTim.getBearing()) { - case 0: - return 180; - case 90: - return 270; - case 180: - return 0; - case 270: - return 90; - default: - return 0; - } - } else if (wydotTim.getDirection().equalsIgnoreCase("i")) { - return getIBearingForRoute(wydotTim.getRoute()); - } else { - return getDBearingForRoute(wydotTim.getRoute()); - } - } - - public void makeIncreasingBufferTim(WydotTimRw wydotTim) { - - double bufferBefore = 0.000; - - Ellipsoid reference = Ellipsoid.WGS84; - GlobalCoordinates startCoordinates = new GlobalCoordinates(wydotTim.getStartPoint().getLatitude().doubleValue(), - wydotTim.getStartPoint().getLongitude().doubleValue()); - GlobalCoordinates nextCoordinates = null; - double bearing = getTimBearing(wydotTim); - GeodeticCalculator calculator = new GeodeticCalculator(); - - for (int i = 0; i < wydotTim.getBuffers().size(); i++) { - // i - // starts at lower milepost minus the buffer distance - nextCoordinates = calculator.calculateEndingGlobalCoordinates(reference, startCoordinates, bearing, - wydotTim.getBuffers().get(i).getDistanceMeters()); - - // update start and stopping points - WydotTimRw wydotTimBuffer = wydotTim.copy(); - - wydotTimBuffer.setStartPoint(new Coordinate(BigDecimal.valueOf(nextCoordinates.getLatitude()), - BigDecimal.valueOf(nextCoordinates.getLongitude()))); - wydotTimBuffer.setEndPoint(new Coordinate(BigDecimal.valueOf(startCoordinates.getLatitude()), - BigDecimal.valueOf(startCoordinates.getLongitude()))); - wydotTimBuffer.setAction(wydotTim.getBuffers().get(i).getAction()); - wydotTimBuffer.setClientId(wydotTim.getClientId() + "%BUFF" + Integer.toString((int) bufferBefore)); - - // send buffer tim - wydotTimBuffer.setAdvisory(wydotTimService.setBufferItisCodes(wydotTimBuffer.getAction())); - if (wydotTimBuffer.getAdvisory() != null) { - List tempList = new ArrayList(wydotTimBuffer.getAdvisory().length); - for (Integer code : wydotTimBuffer.getAdvisory()) { - tempList.add(code.toString()); - } - wydotTimBuffer.setItisCodes(tempList); + // only generate appropriate TIMs for geometry list (buffer, workZone) + String lastItisCode = itisCodes.get(itisCodes.size() - 1); + boolean isBufferTim = bufferTimITISCodes.contains(Integer.valueOf(lastItisCode)); + if (isBuffer && !isBufferTim) { + continue; + } else if (!isBuffer && isBufferTim) { + continue; } - timsToSend.add(wydotTimBuffer); - // update running buffer distance - bufferBefore = wydotTim.getBuffers().get(i).getDistance(); - startCoordinates = nextCoordinates; + WydotTimRw timToSend = tim.copy(); + timToSend.setItisCodes(itisCodes); + String clientIdWithItis = tim.getClientId() + '-' + itisCodeEntry.replace(' ', '-'); + timToSend.setClientId(clientIdWithItis); + timsToSend.add(timToSend); } } - public void makeDecreasingBufferTim(WydotTimRw wydotTim) { - - double bufferBefore = 0; - - Ellipsoid reference = Ellipsoid.WGS84; - GlobalCoordinates startCoordinates = new GlobalCoordinates(wydotTim.getEndPoint().getLatitude().doubleValue(), - wydotTim.getEndPoint().getLongitude().doubleValue()); - GlobalCoordinates nextCoordinates = null; - double bearing = getTimBearing(wydotTim); - GeodeticCalculator calculator = new GeodeticCalculator(); - - for (int i = 0; i < wydotTim.getBuffers().size(); i++) { - // d - // starts at higher milepost plus buffer distance - nextCoordinates = calculator.calculateEndingGlobalCoordinates(reference, startCoordinates, bearing, - wydotTim.getBuffers().get(i).getDistanceMeters()); - - // update start and stopping mileposts - WydotTimRw wydotTimBuffer = wydotTim.copy(); - - wydotTimBuffer.setStartPoint(new Coordinate(BigDecimal.valueOf(startCoordinates.getLatitude()), - BigDecimal.valueOf(startCoordinates.getLongitude()))); - wydotTimBuffer.setEndPoint(new Coordinate(BigDecimal.valueOf(nextCoordinates.getLatitude()), - BigDecimal.valueOf(nextCoordinates.getLongitude()))); - wydotTimBuffer.setAction(wydotTim.getBuffers().get(i).getAction()); - wydotTimBuffer.setClientId(wydotTim.getClientId() + "%BUFF" + Integer.toString((int) bufferBefore)); - - // send buffer tim - wydotTimBuffer.setAdvisory(wydotTimService.setBufferItisCodes(wydotTimBuffer.getAction())); - List tempList = new ArrayList(wydotTimBuffer.getAdvisory().length); - for (Integer code : wydotTimBuffer.getAdvisory()) { - tempList.add(code.toString()); - } - wydotTimBuffer.setItisCodes(tempList); - timsToSend.add(wydotTimBuffer); + public void makeBufferTims(WydotTimRw wydotTim) { + // get mileposts for buffer + List bufferMps = milepostService.getBufferForPath(wydotTim.getRoute().replace('-', '_'), 1.0, wydotTim.toMileposts()); + wydotTim.setGeometry(milepostToGeometry(bufferMps)); + wydotTim.setClientId(wydotTim.getClientId() + "%BUFF"); - // update running buffer distance - bufferBefore = wydotTim.getBuffers().get(i).getDistance(); - startCoordinates = nextCoordinates; - } + addTimsToSend(wydotTim, true); } public void processRequestAsync() { // An Async task always executes in new thread - new Thread(new Runnable() { - public void run() { - for (WydotTimRw tim : timsToSend) { - // check for reduce speed, itis code 7443 - if (tim.getItisCodes() != null && tim.getItisCodes().size() == 3 - && tim.getItisCodes().get(0).equals("7443")) { - processRequest(tim, getTimType(type), tim.getSchedStart(), tim.getSchedEnd(), null, - ContentEnum.speedLimit, TravelerInfoType.advisory); - } else if (tim.getItisCodes() != null && tim.getItisCodes().get(0).equals("7186")) { - // prepare to stop - processRequest(tim, getTimType(type), tim.getSchedStart(), tim.getSchedEnd(), null, - ContentEnum.advisory, TravelerInfoType.advisory); - } else { - // the rest are content=workZone - processRequest(tim, getTimType(type), tim.getSchedStart(), tim.getSchedEnd(), null, - ContentEnum.workZone, TravelerInfoType.advisory); - } + new Thread(() -> { + for (WydotTimRw tim : timsToSend) { + // check for reduce speed, itis code 7443 + if (tim.getItisCodes() != null && tim.getItisCodes().size() == 3 + && tim.getItisCodes().get(0).equals("7443")) { + processRequest(tim, getTimType(type), tim.getSchedStart(), tim.getSchedEnd(), null, + ContentEnum.speedLimit, TravelerInfoType.advisory); + } else if (tim.getItisCodes() != null && tim.getItisCodes().get(0).equals("7186")) { + // prepare to stop + processRequest(tim, getTimType(type), tim.getSchedStart(), tim.getSchedEnd(), null, + ContentEnum.advisory, TravelerInfoType.advisory); + } else { + // the rest are content=workZone + processRequest(tim, getTimType(type), tim.getSchedStart(), tim.getSchedEnd(), null, + ContentEnum.workZone, TravelerInfoType.advisory); } } }).start(); From 3fabb8032520fbc92293db29b4f43ded41a5467b Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Wed, 16 Apr 2025 15:18:13 -0600 Subject: [PATCH 101/168] Remove unnecessary validation from ValidateInputIncident --- .../odewrapper/controller/WydotTimBaseController.java | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java index 488af9efb..39c0c0beb 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java @@ -164,8 +164,8 @@ public ControllerResult validateInputIncident(WydotTimIncident tim) { if (tim.getHighway() == null || !routeSupported(tim.getHighway())) { resultMessages.add("route not supported"); } else { - tim.setRoute(tim.getHighway()); - result.setRoute(tim.getHighway()); + tim.setRoute(tim.getRoute()); + result.setRoute(tim.getRoute()); } // if direction is not i/d/b fail @@ -176,13 +176,6 @@ public ControllerResult validateInputIncident(WydotTimIncident tim) { if (tim.getIncidentId() == null) { resultMessages.add("Null value for incidentId"); } - if (tim.getStartPoint() == null || !tim.getStartPoint().isValid()) { - resultMessages.add("Invalid startPoint"); - } - // endPoint may be null here, so check if not null that it is valid - if (tim.getEndPoint() != null && !tim.getEndPoint().isValid()) { - resultMessages.add("Invalid endPoint"); - } // set itis codes List itisCodes = setItisCodes.setItisCodes(tim); From 1c8fb60dcdaf82382d586ea292a15824b35cfc6b Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Wed, 16 Apr 2025 15:18:38 -0600 Subject: [PATCH 102/168] Update ITIS code set logic to account for multiple ITIS codes --- .../odewrapper/helpers/SetItisCodes.java | 59 +++---------------- 1 file changed, 7 insertions(+), 52 deletions(-) diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java index dacb12724..047d604ac 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java @@ -107,7 +107,7 @@ public String getCustomAlphabetic(Integer itisCode) { public List setItisCodesVsl(WydotTimVsl wydotTim) { - List items = new ArrayList(); + List items = new ArrayList<>(); // speed limit itis code ItisCode speedLimit = getItisCodes().stream().filter(x -> x.getDescription().equals("speed limit")).findFirst() @@ -209,54 +209,6 @@ public List setItisCodesFromAvailability(WydotTimParking wydotTim) { return items; } - public List setItisCodesIncident(WydotTimIncident wydotTim) { - List items = new ArrayList(); - - // action - IncidentChoice incidentAction = getIncidentActions().stream() - .filter(x -> x.getCode().equals(wydotTim.getAction())).findFirst().orElse(null); - - // if action is not null and action itis code exists - if (incidentAction != null && incidentAction.getItisCodeId() != null) { - ItisCode actionItisCode = getItisCodes().stream() - .filter(x -> x.getItisCodeId().equals(incidentAction.getItisCodeId())).findFirst().orElse(null); - if (actionItisCode != null) { - items.add(actionItisCode.getItisCode().toString()); - } - } - - // effect - IncidentChoice incidentEffect = getIncidentEffects().stream() - .filter(x -> x.getCode().equals(wydotTim.getEffect())).findFirst().orElse(null); - - // if effect is not null and effect itis code exists - if (incidentEffect != null && incidentEffect.getItisCodeId() != null) { - ItisCode effectItisCode = getItisCodes().stream() - .filter(x -> x.getItisCodeId().equals(incidentEffect.getItisCodeId())).findFirst().orElse(null); - if (effectItisCode != null) { - items.add(effectItisCode.getItisCode().toString()); - } - } - - // problem - IncidentChoice incidentProblem = getIncidentProblems().stream() - .filter(x -> x.getCode().equals(wydotTim.getProblem())).findFirst().orElse(null); - - // if problem is not null and problem itis code exists - if (incidentProblem != null && incidentProblem.getItisCodeId() != null) { - ItisCode problemItisCode = getItisCodes().stream() - .filter(x -> x.getItisCodeId().equals(incidentProblem.getItisCodeId())).findFirst().orElse(null); - if (problemItisCode != null) { - items.add(problemItisCode.getItisCode().toString()); - } - } - - if (items.size() == 0) - items.add("531");// 531 is "Incident" - - return items; - } - public List getIncidentProblems() { if (incidentProblems != null) return incidentProblems; @@ -284,7 +236,7 @@ public List getIncidentActions() { } } - public List setItisCodesRw(WydotTim wydotTim) { + public List setItisCodes(WydotTim wydotTim) { List items = new ArrayList<>(); @@ -296,6 +248,11 @@ public List setItisCodesRw(WydotTim wydotTim) { for (String item : wydotTim.getItisCodes()) { + if (item.contains(" ")) { + // if the item contains a space it is a sequence of ITIS codes + items.add(item); + continue; + } Integer itisCode = Integer.valueOf(item); var alphaItis = getCustomAlphabetic(itisCode); @@ -310,8 +267,6 @@ public List setItisCodesRw(WydotTim wydotTim) { items.add(code.getItisCode().toString()); } - items.add("1025"); - return items; } From 4af9158b616cd385a60d02d3dcb20feefc93ec43 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Wed, 16 Apr 2025 15:39:14 -0600 Subject: [PATCH 103/168] Update buffer query to account for new buffer ID --- .../cvdatacontroller/controller/ActiveTimController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java index 205e332a9..3451f4187 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java @@ -621,7 +621,7 @@ public ResponseEntity> GetBufferTimsByClientId(@PathVariable Str connection = dbInteractions.getConnectionPool(); statement = connection.createStatement(); String query = "select * from active_tim where CLIENT_ID like '" + clientId - + "\\%BUFF_-%' ESCAPE '\\'"; + + "\\%BUFF-%' ESCAPE '\\'"; rs = statement.executeQuery(query); activeTims = getActiveTimFromRS(rs, false); From 32a53b1b23705f45bbadd71450dc1b10d7977fde Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Wed, 16 Apr 2025 15:39:38 -0600 Subject: [PATCH 104/168] Add increasing/decreasing and buffer TIM generation logic to incident controller --- .../WydotTimIncidentController.java | 70 ++++++++++++++++--- 1 file changed, 60 insertions(+), 10 deletions(-) diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java index 1347c8fbc..a072e3079 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java @@ -3,6 +3,7 @@ import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Date; import java.util.List; @@ -12,6 +13,7 @@ import com.trihydro.library.helpers.Utility; import com.trihydro.library.model.ActiveTim; import com.trihydro.library.model.ContentEnum; +import com.trihydro.library.model.Milepost; import com.trihydro.library.service.ActiveTimService; import com.trihydro.library.service.RestTemplateProvider; import com.trihydro.library.service.TimTypeService; @@ -43,6 +45,7 @@ public class WydotTimIncidentController extends WydotTimBaseController { private final String type = "I"; + List timsToSend = new ArrayList<>(); @Autowired public WydotTimIncidentController(BasicConfiguration _basicConfiguration, WydotTimService _wydotTimService, @@ -63,8 +66,6 @@ public ResponseEntity createIncidentTim(@RequestBody TimIncidentList tim String post = gson.toJson(timIncidentList); utility.logWithDate(post, this.getClass()); - List timsToSend = new ArrayList<>(); - List resultList = new ArrayList<>(); ControllerResult resultTim; @@ -73,13 +74,12 @@ public ResponseEntity createIncidentTim(@RequestBody TimIncidentList tim resultTim = validateInputIncident(wydotTim); - if (!resultTim.getResultMessages().isEmpty()) { - resultList.add(resultTim); - continue; + if (wydotTim.getDirection().equalsIgnoreCase("i")) { + makeIncreasingTims(wydotTim); + } + else { + makeDecreasingTims(wydotTim); } - - // make tims - timsToSend.add(wydotTim); resultTim.getResultMessages().add("success"); resultList.add(resultTim); @@ -91,6 +91,57 @@ public ResponseEntity createIncidentTim(@RequestBody TimIncidentList tim return ResponseEntity.status(HttpStatus.OK).body(responseMessage); } + public void makeIncreasingTims(WydotTimIncident wydotTim) { + // i - add buffer for point TIMs + WydotTimIncident timOneWay = wydotTim.copy(); + timOneWay.setDirection("I"); + + addTimsToSend(timOneWay, false); + + makeBufferTims(timOneWay); + } + + public void makeDecreasingTims(WydotTimIncident wydotTim) { + // d - add buffer for point TIMs + WydotTimIncident timOneWay = wydotTim.copy(); + timOneWay.setDirection("D"); + + addTimsToSend(timOneWay, false); + + makeBufferTims(timOneWay); + } + + private void addTimsToSend(WydotTimIncident tim, boolean isBuffer) { + for (String itisCodeEntry : tim.getItisCodes()) { + // CTW Update requires that individual TIMs are created for each ITIS ordering + List itisCodes = Arrays.asList(itisCodeEntry.split(" ")); + + // only generate appropriate TIMs for geometry list (buffer, workZone) + String lastItisCode = itisCodes.get(itisCodes.size() - 1); + boolean isBufferTim = bufferTimITISCodes.contains(Integer.valueOf(lastItisCode)); + if (isBuffer && !isBufferTim) { + continue; + } else if (!isBuffer && isBufferTim) { + continue; + } + + WydotTimIncident timToSend = tim.copy(); + timToSend.setItisCodes(itisCodes); + String clientIdWithItis = tim.getClientId() + '-' + itisCodeEntry.replace(' ', '-'); + timToSend.setClientId(clientIdWithItis); + timsToSend.add(timToSend); + } + } + + public void makeBufferTims(WydotTimIncident wydotTim) { + // get mileposts for buffer + List bufferMps = milepostService.getBufferForPath(wydotTim.getRoute().replace('-', '_'), 1.0, wydotTim.toMileposts()); + wydotTim.setGeometry(milepostToGeometry(bufferMps)); + wydotTim.setClientId(wydotTim.getClientId() + "%BUFF"); + + addTimsToSend(wydotTim, true); + } + @RequestMapping(value = "/incident-tim", method = RequestMethod.PUT, headers = "Accept=application/json") public ResponseEntity updateIncidentTim(@RequestBody TimIncidentList timIncidentList) { @@ -103,7 +154,6 @@ public ResponseEntity updateIncidentTim(@RequestBody TimIncidentList tim List resultList = new ArrayList<>(); ControllerResult resultTim; - List timsToSend = new ArrayList<>(); // delete TIMs for (WydotTimIncident wydotTim : timIncidentList.getTimIncidentList()) { @@ -152,7 +202,7 @@ public ResponseEntity deleteIncidentTim(@PathVariable String incidentId) utility.logWithDate(dateFormat.format(date) + " - Delete Incident TIM", this.getClass()); // expire and clear TIM - wydotTimService.clearTimsById("I", incidentId, null); + wydotTimService.clearTimsById("I", incidentId, null, true); String responseMessage = "success"; return ResponseEntity.status(HttpStatus.OK).body(responseMessage); From 2f9fad39d95f5268b570d155f6fb66fbc22888aa Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 17 Apr 2025 06:26:23 -0600 Subject: [PATCH 105/168] Remove setItisCodesVsl --- .../odewrapper/helpers/SetItisCodes.java | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java index 047d604ac..3dddeca4a 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java @@ -105,30 +105,6 @@ public String getCustomAlphabetic(Integer itisCode) { return text; } - public List setItisCodesVsl(WydotTimVsl wydotTim) { - - List items = new ArrayList<>(); - - // speed limit itis code - ItisCode speedLimit = getItisCodes().stream().filter(x -> x.getDescription().equals("speed limit")).findFirst() - .orElse(null); - if (speedLimit != null) { - items.add(speedLimit.getItisCode().toString()); - } - - // number e.g 50, convert to ITIS code - Integer speed = wydotTim.getSpeed() + 12544; - items.add(speed.toString()); - - // mph itis code - ItisCode mph = getItisCodes().stream().filter(x -> x.getDescription().equals("mph")).findFirst().orElse(null); - if (mph != null) { - items.add(mph.getItisCode().toString()); - } - - return items; - } - public List setItisCodesParking(WydotTimParking wydotTim) { // check to see if code exists From 4153a0bc3b251dc7626b4a944a6eff48f37c045c Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 17 Apr 2025 06:33:27 -0600 Subject: [PATCH 106/168] Update clientID to include direction --- .../odewrapper/controller/WydotTimIncidentController.java | 2 +- .../trihydro/odewrapper/controller/WydotTimRwController.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java index a072e3079..831188f92 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java @@ -127,7 +127,7 @@ private void addTimsToSend(WydotTimIncident tim, boolean isBuffer) { WydotTimIncident timToSend = tim.copy(); timToSend.setItisCodes(itisCodes); - String clientIdWithItis = tim.getClientId() + '-' + itisCodeEntry.replace(' ', '-'); + String clientIdWithItis = tim.getClientId() + '-' + tim.getDirection() + '-' + itisCodeEntry.replace(' ', '-'); timToSend.setClientId(clientIdWithItis); timsToSend.add(timToSend); } diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java index 92dd5e91c..14d8fadc0 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java @@ -155,7 +155,7 @@ private void addTimsToSend(WydotTimRw tim, boolean isBuffer) { WydotTimRw timToSend = tim.copy(); timToSend.setItisCodes(itisCodes); - String clientIdWithItis = tim.getClientId() + '-' + itisCodeEntry.replace(' ', '-'); + String clientIdWithItis = tim.getClientId() + '-' + tim.getDirection() + '-' + itisCodeEntry.replace(' ', '-'); timToSend.setClientId(clientIdWithItis); timsToSend.add(timToSend); } From 9dbc0fdfcc22308ea5576baca8fe4456ce8cfcbe Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 17 Apr 2025 07:29:29 -0600 Subject: [PATCH 107/168] Add ITIS code abbreviation method to SetItisCodes --- .../com/trihydro/odewrapper/helpers/SetItisCodes.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java index 3dddeca4a..8c3381735 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java @@ -1,6 +1,7 @@ package com.trihydro.odewrapper.helpers; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import com.trihydro.library.helpers.Utility; @@ -262,6 +263,15 @@ public List setItisCodesBowr(WydotTimBowr tim) throws WeightNotSupported return itisCodes; } + public static String getItisCodeAbbreviation(String itisCodes) { + List words = Arrays.asList(itisCodes.split(" ")); + if (words.size() < 3) { + return itisCodes.replace(" ", "-"); + } + + return words.stream().map(word -> word.substring(0, 1)).reduce("", String::concat); + } + /** * This method translates the weight in pounds to its corresponding ITIS code. * These are large number ITIS codes and do not abide by the standard translations used for other numbers such as mph. From 3e2b65d0c2d777df75ac140bdce731e4ca85d285 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 17 Apr 2025 07:55:49 -0600 Subject: [PATCH 108/168] Update VSL validation to remove unnecessary logic --- .../odewrapper/controller/WydotTimBaseController.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java index 39c0c0beb..64cbcb672 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java @@ -401,12 +401,6 @@ protected ControllerResult validateInputVsl(WydotTimVsl tim) { && !tim.getDirection().equalsIgnoreCase("b")) { resultMessages.add("direction not supported"); } - if (tim.getStartPoint() == null || !tim.getStartPoint().isValid()) { - resultMessages.add("Invalid startPoint"); - } - if (tim.getEndPoint() == null || !tim.getEndPoint().isValid()) { - resultMessages.add("Invalid endPoint"); - } if (tim.getRoute() == null) { resultMessages.add("Null value for route"); } @@ -416,11 +410,11 @@ protected ControllerResult validateInputVsl(WydotTimVsl tim) { if (tim.getDeviceId() == null) { resultMessages.add("Null value for deviceId"); } else { - tim.setClientId(tim.getDeviceId()); + tim.setClientId(tim.getClientId()); } // set itis codes - List itisCodes = setItisCodes.setItisCodesVsl(tim); + List itisCodes = setItisCodes.setItisCodes(tim); if (itisCodes.isEmpty()) resultMessages.add("No ITIS codes found"); result.setItisCodes(itisCodes); From 8816ce8fc81553613f284c695e613b2939f0d777 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 17 Apr 2025 07:56:09 -0600 Subject: [PATCH 109/168] Add delete method to VSL controller, add increasing/decreasing/buffer TIM generation logic --- .../controller/WydotTimVslController.java | 100 +++++++++++++++--- 1 file changed, 86 insertions(+), 14 deletions(-) diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimVslController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimVslController.java index 5b4414247..0a864a9cd 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimVslController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimVslController.java @@ -3,6 +3,7 @@ import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Date; import java.util.List; @@ -12,6 +13,7 @@ import com.trihydro.library.helpers.Utility; import com.trihydro.library.model.ActiveTim; import com.trihydro.library.model.ContentEnum; +import com.trihydro.library.model.Milepost; import com.trihydro.library.model.WydotTim; import com.trihydro.library.service.ActiveTimService; import com.trihydro.library.service.MilepostService; @@ -28,6 +30,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @@ -42,6 +45,7 @@ public class WydotTimVslController extends WydotTimBaseController { private final String type = "VSL"; + List timsToSend = new ArrayList<>(); @Autowired public WydotTimVslController(BasicConfiguration _basicConfiguration, WydotTimService _wydotTimService, @@ -60,23 +64,26 @@ public ResponseEntity createUpdateVslTim(@RequestBody TimVslList timVslL utility.logWithDate(dateFormat.format(date) + " - Create/Update VSL TIM", this.getClass()); String post = gson.toJson(timVslList); - utility.logWithDate(post.toString(), this.getClass()); + utility.logWithDate(post, this.getClass()); - List resultList = new ArrayList(); - ControllerResult resultTim = null; - List timsToSend = new ArrayList(); + List resultList = new ArrayList<>(); + ControllerResult resultTim; // build TIM for (WydotTimVsl wydotTim : timVslList.getTimVslList()) { resultTim = validateInputVsl(wydotTim); - if (resultTim.getResultMessages().size() > 0) { + if (!resultTim.getResultMessages().isEmpty()) { resultList.add(resultTim); continue; } - // add TIM to list for processing later - timsToSend.add(wydotTim); + if (wydotTim.getDirection().equalsIgnoreCase("i")) { + makeIncreasingTims(wydotTim); + } + else { + makeDecreasingTims(wydotTim); + } resultTim.getResultMessages().add("success"); resultList.add(resultTim); @@ -87,19 +94,84 @@ public ResponseEntity createUpdateVslTim(@RequestBody TimVslList timVslL return ResponseEntity.status(HttpStatus.OK).body(responseMessage); } + public void makeIncreasingTims(WydotTimVsl wydotTim) { + // i - add buffer for point TIMs + WydotTimVsl timOneWay = wydotTim.copy(); + timOneWay.setDirection("I"); + + addTimsToSend(timOneWay, false); + + makeBufferTims(timOneWay); + } + + public void makeDecreasingTims(WydotTimVsl wydotTim) { + // d - add buffer for point TIMs + WydotTimVsl timOneWay = wydotTim.copy(); + timOneWay.setDirection("D"); + + addTimsToSend(timOneWay, false); + + makeBufferTims(timOneWay); + } + + private void addTimsToSend(WydotTimVsl tim, boolean isBuffer) { + for (String itisCodeEntry : tim.getItisCodes()) { + // CTW Update requires that individual TIMs are created for each ITIS ordering + List itisCodes = Arrays.asList(itisCodeEntry.split(" ")); + + // only generate appropriate TIMs for geometry list (buffer, workZone) + String lastItisCode = itisCodes.get(itisCodes.size() - 1); + boolean isBufferTim = bufferTimITISCodes.contains(Integer.valueOf(lastItisCode)); + if (isBuffer && !isBufferTim) { + continue; + } else if (!isBuffer && isBufferTim) { + continue; + } + + WydotTimVsl timToSend = tim.copy(); + timToSend.setItisCodes(itisCodes); + var itisCodeAbb = SetItisCodes.getItisCodeAbbreviation(itisCodeEntry); + String clientIdWithItis = tim.getClientId() + '-' + tim.getDirection() + '-' + itisCodeAbb; + timToSend.setClientId(clientIdWithItis); + timsToSend.add(timToSend); + } + } + + public void makeBufferTims(WydotTimVsl wydotTim) { + // get mileposts for buffer + List bufferMps = milepostService.getBufferForPath(wydotTim.getRoute().replace('-', '_'), 1.0, wydotTim.toMileposts()); + wydotTim.setGeometry(milepostToGeometry(bufferMps)); + wydotTim.setClientId(wydotTim.getClientId() + "%BUFF"); + + addTimsToSend(wydotTim, true); + } + public void processRequestAsync(List wydotTims) { // An Async task always executes in new thread - new Thread(new Runnable() { - public void run() { - var startTime = getStartTime(); - for (WydotTim tim : wydotTims) { - processRequest(tim, getTimType(type), startTime, null, null, ContentEnum.speedLimit, - TravelerInfoType.roadSignage); - } + new Thread(() -> { + var startTime = getStartTime(); + for (WydotTim tim : wydotTims) { + processRequest(tim, getTimType(type), startTime, null, null, ContentEnum.speedLimit, + TravelerInfoType.roadSignage); } }).start(); } + @RequestMapping(value = "/vsl-tim/{vslTimId}", method = RequestMethod.DELETE, headers = "Accept=application/json") + public ResponseEntity deleteVslTim(@PathVariable String vslTimId) { + + DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); + Date date = new Date(); + + utility.logWithDate(dateFormat.format(date) + " - Delete VSL TIM", this.getClass()); + + // expire and clear TIM + wydotTimService.clearTimsById("VSL", vslTimId, null, true); + + String responseMessage = "success"; + return ResponseEntity.status(HttpStatus.OK).body(responseMessage); + } + @RequestMapping(value = "/vsl-tim", method = RequestMethod.GET, headers = "Accept=application/json") public Collection getVslTims() { From 6eb981dd4a8c8e59bf2709c80c09a412564f1abb Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 17 Apr 2025 07:58:22 -0600 Subject: [PATCH 110/168] Update clientID generation to use getItisCodeAbbreviation method --- .../odewrapper/controller/WydotTimIncidentController.java | 3 ++- .../trihydro/odewrapper/controller/WydotTimRwController.java | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java index 831188f92..ca0351999 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java @@ -127,7 +127,8 @@ private void addTimsToSend(WydotTimIncident tim, boolean isBuffer) { WydotTimIncident timToSend = tim.copy(); timToSend.setItisCodes(itisCodes); - String clientIdWithItis = tim.getClientId() + '-' + tim.getDirection() + '-' + itisCodeEntry.replace(' ', '-'); + var itisCodeAbb = SetItisCodes.getItisCodeAbbreviation(itisCodeEntry); + String clientIdWithItis = tim.getClientId() + '-' + tim.getDirection() + '-' + itisCodeAbb; timToSend.setClientId(clientIdWithItis); timsToSend.add(timToSend); } diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java index 14d8fadc0..0bc027ad4 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java @@ -155,7 +155,8 @@ private void addTimsToSend(WydotTimRw tim, boolean isBuffer) { WydotTimRw timToSend = tim.copy(); timToSend.setItisCodes(itisCodes); - String clientIdWithItis = tim.getClientId() + '-' + tim.getDirection() + '-' + itisCodeEntry.replace(' ', '-'); + var itisCodeAbb = SetItisCodes.getItisCodeAbbreviation(itisCodeEntry); + String clientIdWithItis = tim.getClientId() + '-' + tim.getDirection() + '-' + itisCodeAbb; timToSend.setClientId(clientIdWithItis); timsToSend.add(timToSend); } From 796d74e49e7ac054a122541040efc412508f6207 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 1 May 2025 07:07:52 -0600 Subject: [PATCH 111/168] Remove unnecessary autowired annotation --- .../main/java/com/trihydro/library/factory/KafkaFactory.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/factory/KafkaFactory.java b/cv-data-service-library/src/main/java/com/trihydro/library/factory/KafkaFactory.java index e0ddca64d..b7d19ebb7 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/factory/KafkaFactory.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/factory/KafkaFactory.java @@ -9,7 +9,6 @@ import org.apache.kafka.clients.consumer.KafkaConsumer; import org.apache.kafka.clients.producer.KafkaProducer; import org.apache.kafka.clients.producer.Producer; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @@ -25,7 +24,6 @@ public class KafkaFactory { private String confluentSecret; private final Properties kafkaProperties; - @Autowired public KafkaFactory(Utility _utility) throws IllegalArgumentException { utility = _utility; kafkaType = getKafkaType(); From 143e70f739ee831e039b1b48562d713559277367 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 1 May 2025 07:10:35 -0600 Subject: [PATCH 112/168] Update clearMilepostCache variable naming for clarity --- .../controller/MilepostController.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/MilepostController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/MilepostController.java index be644f9d5..8534f553e 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/MilepostController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/MilepostController.java @@ -353,12 +353,12 @@ public ResponseEntity deleteMilepostCache(@PathVariable String timID) { @RequestMapping(method = RequestMethod.GET, value="/clear-milepost-cache") public ResponseEntity clearMilepostCache() { utility.logWithDate("Clearing milepost cache"); - List timIDs = new ArrayList<>(milepostCache.keySet()); - List activeTimIds = getActiveTimIds(); + List clientIDs = new ArrayList<>(milepostCache.keySet()); + List activeTimClientIds = getActiveTimIds(); // remove all active TIM IDs from the list of milepost cache TIM IDs - timIDs.removeAll(activeTimIds); - for (String timID : timIDs) { - milepostCache.remove(timID); + clientIDs.removeAll(activeTimClientIds); + for (String clientID : clientIDs) { + milepostCache.remove(clientID); } return ResponseEntity.ok("Milepost cache cleared successfully"); } From 6b227f32f3d07e6c51e9719435b8bc03697697b3 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 1 May 2025 07:10:47 -0600 Subject: [PATCH 113/168] Add if not exists to table creation --- db-scripts/pgsql/setup/sql/1-create_all_tables.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/db-scripts/pgsql/setup/sql/1-create_all_tables.sql b/db-scripts/pgsql/setup/sql/1-create_all_tables.sql index 7e40bf548..bd0b10b65 100644 --- a/db-scripts/pgsql/setup/sql/1-create_all_tables.sql +++ b/db-scripts/pgsql/setup/sql/1-create_all_tables.sql @@ -164,7 +164,7 @@ ALTER TABLE computed_lane ALTER COLUMN OFFSET_SMALL_Y SET NOT NULL; ALTER TABLE computed_lane ALTER COLUMN OFFSET_LARGE_Y SET NOT NULL; -CREATE TABLE status_log ( +CREATE TABLE IF NOT EXISTS status_log ( log_id bigint NOT NULL, status_time timestamp NOT NULL, entity_id integer NOT NULL, @@ -279,7 +279,7 @@ ALTER TABLE data_list ALTER COLUMN LANE_ANGLE SET NOT NULL; ALTER TABLE data_list ADD CONSTRAINT fk_node_xy_data_list FOREIGN KEY (node_xy_id) REFERENCES node_xy(node_xy_id) ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE; -CREATE TABLE incident_action_lut ( +CREATE TABLE IF NOT EXISTS incident_action_lut ( description varchar(60), code varchar(10), itis_code_id bigint, From 4ae10bfa73aad9e2425ea0e1ea7e1763260d8fcc Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 1 May 2025 07:12:03 -0600 Subject: [PATCH 114/168] Update dbInteractions variable name in RsuService constructor --- .../com/trihydro/rsudatacontroller/service/RsuService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rsu-data-controller/src/main/java/com/trihydro/rsudatacontroller/service/RsuService.java b/rsu-data-controller/src/main/java/com/trihydro/rsudatacontroller/service/RsuService.java index f59a2f15b..92e9edf4f 100644 --- a/rsu-data-controller/src/main/java/com/trihydro/rsudatacontroller/service/RsuService.java +++ b/rsu-data-controller/src/main/java/com/trihydro/rsudatacontroller/service/RsuService.java @@ -39,11 +39,11 @@ public class RsuService { protected DbInteractions dbInteractions; @Autowired - public void InjectDependencies(ProcessFactory processFactory, BasicConfiguration config, DbInteractions _dbInteractions, Utility utility) { + public void InjectDependencies(ProcessFactory processFactory, BasicConfiguration config, DbInteractions dbInteractions, Utility utility) { this.processFactory = processFactory; this.config = config; this.utility = utility; - this.dbInteractions = _dbInteractions; + this.dbInteractions = dbInteractions; } /** From cf6707de1f9df35774339803531b82839a546671 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 8 May 2025 07:51:13 -0600 Subject: [PATCH 115/168] Remove unused imports --- .../java/com/trihydro/rsudatacontroller/service/RsuService.java | 2 -- .../com/trihydro/rsudatacontroller/service/RsuServiceTest.java | 1 - 2 files changed, 3 deletions(-) diff --git a/rsu-data-controller/src/main/java/com/trihydro/rsudatacontroller/service/RsuService.java b/rsu-data-controller/src/main/java/com/trihydro/rsudatacontroller/service/RsuService.java index 92e9edf4f..ddcc9d1f0 100644 --- a/rsu-data-controller/src/main/java/com/trihydro/rsudatacontroller/service/RsuService.java +++ b/rsu-data-controller/src/main/java/com/trihydro/rsudatacontroller/service/RsuService.java @@ -6,8 +6,6 @@ import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; diff --git a/rsu-data-controller/src/test/java/com/trihydro/rsudatacontroller/service/RsuServiceTest.java b/rsu-data-controller/src/test/java/com/trihydro/rsudatacontroller/service/RsuServiceTest.java index f1932c4b9..bd3428f93 100644 --- a/rsu-data-controller/src/test/java/com/trihydro/rsudatacontroller/service/RsuServiceTest.java +++ b/rsu-data-controller/src/test/java/com/trihydro/rsudatacontroller/service/RsuServiceTest.java @@ -2,7 +2,6 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; From 36c75ce7018960598c34bda3b57ec18fcf4887c2 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 8 May 2025 07:55:32 -0600 Subject: [PATCH 116/168] Update setMilepostCache to update existing values, rename getActiveTimIds method for clarity --- .../controller/MilepostController.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/MilepostController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/MilepostController.java index 8534f553e..3644a2f55 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/MilepostController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/MilepostController.java @@ -314,13 +314,13 @@ public ResponseEntity> @RequestMapping(method = RequestMethod.POST, value="/set-milepost-cache") public ResponseEntity setMilepostCache(@RequestBody SetMilepostCacheRequest milepostCacheBody) { - utility.logWithDate("Setting milepost cache for timID: " + milepostCacheBody.getTimID()); - - if (milepostCacheBody.getMileposts().size() == 0 || milepostCacheBody.getTimID() == null) { + if (milepostCacheBody.getMileposts().isEmpty() || milepostCacheBody.getTimID() == null) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Invalid Request: please provide a valid milepost list and timID"); } if (milepostCache.containsKey(milepostCacheBody.getTimID())) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Milepost cache already exists for timID: " + milepostCacheBody.getTimID()); + utility.logWithDate("Updating milepost cache for timID: " + milepostCacheBody.getTimID()); + } else { + utility.logWithDate("Setting milepost cache for timID: " + milepostCacheBody.getTimID()); } milepostCache.put(milepostCacheBody.getTimID(), milepostCacheBody.getMileposts()); return ResponseEntity.ok("Milepost cache set successfully for timID: " + milepostCacheBody.getTimID()); @@ -354,7 +354,7 @@ public ResponseEntity deleteMilepostCache(@PathVariable String timID) { public ResponseEntity clearMilepostCache() { utility.logWithDate("Clearing milepost cache"); List clientIDs = new ArrayList<>(milepostCache.keySet()); - List activeTimClientIds = getActiveTimIds(); + List activeTimClientIds = getActiveTimClientIds(); // remove all active TIM IDs from the list of milepost cache TIM IDs clientIDs.removeAll(activeTimClientIds); for (String clientID : clientIDs) { @@ -363,7 +363,7 @@ public ResponseEntity clearMilepostCache() { return ResponseEntity.ok("Milepost cache cleared successfully"); } - private List getActiveTimIds() { + private List getActiveTimClientIds() { List activeTimIds = new ArrayList<>(); String sql = "SELECT client_id FROM active_tim WHERE marked_for_deletion = False"; try (Connection connection = dbInteractions.getConnectionPool(); From dfc9cc2f1f70a4df682571c5b32ae0e220d52da5 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Thu, 8 May 2025 08:41:00 -0600 Subject: [PATCH 117/168] update getTimBearing method name for clarity --- .../odewrapper/controller/WydotTimRwController.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java index 91e6b111e..03c60ce85 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java @@ -163,7 +163,7 @@ private double getDBearingForRoute(String route) { return 0; } - private double getTimBearing(WydotTimRw wydotTim) { + private double getTimUpstreamBearing(WydotTimRw wydotTim) { if (wydotTim.getBearing() != null) { switch (wydotTim.getBearing()) { case 0: @@ -192,7 +192,7 @@ public void makeIncreasingBufferTim(WydotTimRw wydotTim) { GlobalCoordinates startCoordinates = new GlobalCoordinates(wydotTim.getStartPoint().getLatitude().doubleValue(), wydotTim.getStartPoint().getLongitude().doubleValue()); GlobalCoordinates nextCoordinates = null; - double bearing = getTimBearing(wydotTim); + double bearing = getTimUpstreamBearing(wydotTim); GeodeticCalculator calculator = new GeodeticCalculator(); for (int i = 0; i < wydotTim.getBuffers().size(); i++) { @@ -236,7 +236,7 @@ public void makeDecreasingBufferTim(WydotTimRw wydotTim) { GlobalCoordinates startCoordinates = new GlobalCoordinates(wydotTim.getEndPoint().getLatitude().doubleValue(), wydotTim.getEndPoint().getLongitude().doubleValue()); GlobalCoordinates nextCoordinates = null; - double bearing = getTimBearing(wydotTim); + double bearing = getTimUpstreamBearing(wydotTim); GeodeticCalculator calculator = new GeodeticCalculator(); for (int i = 0; i < wydotTim.getBuffers().size(); i++) { From 6ae06220ffcd0e581d126daa9dbf8ddbe067f121 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Tue, 24 Jun 2025 16:14:03 -0600 Subject: [PATCH 118/168] Add reverted changes to JsonToJavaConverter class --- .../library/helpers/JsonToJavaConverter.java | 211 +++++++++--------- 1 file changed, 107 insertions(+), 104 deletions(-) diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/JsonToJavaConverter.java b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/JsonToJavaConverter.java index f251459c0..0779c9016 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/JsonToJavaConverter.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/JsonToJavaConverter.java @@ -1,14 +1,17 @@ package com.trihydro.library.helpers; -import static java.time.temporal.TemporalAdjusters.firstDayOfYear; - import java.io.IOException; import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; +import static java.time.temporal.TemporalAdjusters.firstDayOfYear; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; +import java.util.Map; + +import org.springframework.stereotype.Component; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationFeature; @@ -17,8 +20,6 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import com.trihydro.library.model.ContentEnum; -import org.springframework.stereotype.Component; - import us.dot.its.jpo.ode.model.OdeLogMetadata; import us.dot.its.jpo.ode.model.OdeMsgMetadata.GeneratedBy; import us.dot.its.jpo.ode.model.OdeRequestMsgMetadata; @@ -30,7 +31,6 @@ import us.dot.its.jpo.ode.plugin.SnmpProtocol; import us.dot.its.jpo.ode.plugin.j2735.J2735SpecialVehicleExtensions; import us.dot.its.jpo.ode.plugin.j2735.J2735SupplementalVehicleExtensions; -import us.dot.its.jpo.ode.plugin.j2735.J2735VehicleSafetyExtensions; 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.OdeTravelerInformationMessage.DataFrame.Region; @@ -242,7 +242,14 @@ else if (reverse != null) } if (regionDirectionNode != null) { - region.setDirection(mapper.treeToValue(regionDirectionNode, String.class)); + StringBuilder directionBuilder = new StringBuilder(); + Iterator> fields = regionDirectionNode.fields(); + while (fields.hasNext()) { + Map.Entry field = fields.next(); + boolean directionBool= Boolean.parseBoolean(field.getValue().toString()); + directionBuilder.append(directionBool ? "1" : "0"); + } + region.setDirection(directionBuilder.toString()); } JsonNode descriptionNode = regionNode.get("description"); @@ -266,7 +273,7 @@ public OdeTimPayload convertTimPayloadJsonToJava(String value) { try { OdeTravelerInformationMessage.DataFrame[] dataFrames = new OdeTravelerInformationMessage.DataFrame[1]; OdeTravelerInformationMessage.DataFrame dataFrame = new OdeTravelerInformationMessage.DataFrame(); - List regions = new ArrayList(); + List regions = new ArrayList<>(); // JsonNode payloadNode = JsonUtils.getJsonNode(value, "payload"); JsonNode timNode = JsonUtils.getJsonNode(value, "payload").get("data").get("MessageFrame").get("value") @@ -390,10 +397,10 @@ public OdeTravelerInformationMessage.DataFrame.Region.Path GetPathData(JsonNode if (nodesNode == null) return null; - JsonNode nodeXYArrNode = isXy ? nodesNode.get("NodeXY") : nodesNode.get("NodeLL"); + JsonNode nodeXYArrNode = isXy ? nodesNode.get("NodeXY") : nodesNode; OdeTravelerInformationMessage.DataFrame.Region.Path path = new OdeTravelerInformationMessage.DataFrame.Region.Path(); - List nodeXYs = new ArrayList(); - OdeTravelerInformationMessage.NodeXY nodeXY = new OdeTravelerInformationMessage.NodeXY(); + List nodeXYs = new ArrayList<>(); + OdeTravelerInformationMessage.NodeXY nodeXY; if (nodeXYArrNode.isArray()) { for (final JsonNode objNode : nodeXYArrNode) { @@ -470,123 +477,119 @@ public OdeTimPayload convertTmcTimTopicJsonToJava(String value) { OdeTimPayload odeTimPayload = null; try { - OdeTravelerInformationMessage.DataFrame[] dataFrames = new OdeTravelerInformationMessage.DataFrame[1]; + List dataFrames = new ArrayList<>(); OdeTravelerInformationMessage.DataFrame dataFrame = new OdeTravelerInformationMessage.DataFrame(); - List regions = new ArrayList(); - - // JsonNode timNode = JsonUtils.getJsonNode(value, - // "payload").get("data").get("MessageFrame").get("value") - // .get("TravelerInformation"); - JsonNode timNode = JsonUtils.getJsonNode(value, "payload").findValue("TravelerInformation"); - JsonNode travelerDataFrame = timNode.findValue("TravelerDataFrame"); - - JsonNode sequenceArrNode = null; - JsonNode contentNode = travelerDataFrame.get("content"); - if (contentNode.has(ContentEnum.advisory.getStringValue())) { - sequenceArrNode = contentNode.get(ContentEnum.advisory.getStringValue()).get("SEQUENCE"); - dataFrame.setContent(ContentEnum.advisory.getStringValue()); - } else if (contentNode.has(ContentEnum.speedLimit.getStringValue())) { - sequenceArrNode = contentNode.get(ContentEnum.speedLimit.getStringValue()).get("SEQUENCE"); - dataFrame.setContent(ContentEnum.speedLimit.getStringValue()); - } else if (contentNode.has(ContentEnum.exitService.getStringValue())) { - sequenceArrNode = contentNode.get(ContentEnum.exitService.getStringValue()).get("SEQUENCE"); - dataFrame.setContent(ContentEnum.exitService.getStringValue()); - } else if (contentNode.has(ContentEnum.genericSign.getStringValue())) { - sequenceArrNode = contentNode.get(ContentEnum.genericSign.getStringValue()).get("SEQUENCE"); - dataFrame.setContent(ContentEnum.genericSign.getStringValue()); - } else if (contentNode.has(ContentEnum.workZone.getStringValue())) { - sequenceArrNode = contentNode.get(ContentEnum.workZone.getStringValue()).get("SEQUENCE"); - dataFrame.setContent(ContentEnum.workZone.getStringValue()); - } - - List itemsList = new ArrayList(); - String item = null; - if (sequenceArrNode != null && sequenceArrNode.isArray()) { - for (final JsonNode objNode : sequenceArrNode) { - if (objNode.get("item").get("itis") != null) - item = mapper.treeToValue(objNode.get("item").get("itis"), String.class); - else if (objNode.get("item").get("text") != null) - item = mapper.treeToValue(objNode.get("item").get("text"), String.class); + List regions = new ArrayList<>(); - itemsList.add(item); - } - } - - // ADD NON ARRAY ELEMENT - if (sequenceArrNode != null && !sequenceArrNode.isArray()) { - if (sequenceArrNode.get("item").get("itis") != null) - item = mapper.treeToValue(sequenceArrNode.get("item").get("itis"), String.class); - else if (sequenceArrNode.get("item").get("text") != null) - item = mapper.treeToValue(sequenceArrNode.get("item").get("text"), String.class); - - itemsList.add(item); - } - - // TravelerInfoType.valueOf(); - JsonNode frameTypeNode = travelerDataFrame.get("frameType"); - if (frameTypeNode != null) { - if (frameTypeNode.fieldNames().hasNext()) { - TravelerInfoType frameType = TravelerInfoType.valueOf(frameTypeNode.fieldNames().next()); - if (frameType != null) { - dataFrame.setFrameType(frameType); - } - } + OdeTravelerInformationMessage tim = new OdeTravelerInformationMessage(); + JsonNode timNode = JsonUtils.getJsonNode(value, "payload").findValue("data"); + tim.setMsgCnt(timNode.get("msgCnt").asInt()); + JsonNode packetIDNode = timNode.get("packetID"); + if (packetIDNode != null) { + tim.setPacketID(packetIDNode.asText()); } - JsonNode startTimeNode = travelerDataFrame.get("startTime"); - JsonNode durationNode = travelerDataFrame.get("durationTime"); - JsonNode priorityNode = travelerDataFrame.get("priority"); - LocalDate now = LocalDate.now(); LocalDate firstDay = now.with(firstDayOfYear()); - OdeTravelerInformationMessage tim = new OdeTravelerInformationMessage(); - JsonNode timeStampNode = timNode.get("timeStamp"); if (timeStampNode != null) { LocalDateTime timeStampDate = firstDay.atStartOfDay().plus(timeStampNode.asInt(), ChronoUnit.MINUTES); tim.setTimeStamp(timeStampDate.toString() + "Z"); } - LocalDateTime startDate = firstDay.atStartOfDay().plus(startTimeNode.asInt(), ChronoUnit.MINUTES); + JsonNode travelerDataFrameArray = timNode.findValue("dataFrames"); + for (final JsonNode travelerDataFrame : travelerDataFrameArray) { + JsonNode sequenceArrNode = null; + JsonNode contentNode = travelerDataFrame.get("content"); + if (contentNode.has(ContentEnum.advisory.getStringValue())) { + sequenceArrNode = contentNode.get("advisory"); + dataFrame.setContent(ContentEnum.advisory.getStringValue()); + } else if (contentNode.has(ContentEnum.speedLimit.getStringValue())) { + sequenceArrNode = contentNode.get("speedLimit"); + dataFrame.setContent(ContentEnum.speedLimit.getStringValue()); + } else if (contentNode.has(ContentEnum.exitService.getStringValue())) { + sequenceArrNode = contentNode.get("exitService"); + dataFrame.setContent(ContentEnum.exitService.getStringValue()); + } else if (contentNode.has(ContentEnum.genericSign.getStringValue())) { + sequenceArrNode = contentNode.get("genericSign"); + dataFrame.setContent(ContentEnum.genericSign.getStringValue()); + } else if (contentNode.has(ContentEnum.workZone.getStringValue())) { + sequenceArrNode = contentNode.get("workZone"); + dataFrame.setContent(ContentEnum.workZone.getStringValue()); + } - dataFrame.setStartDateTime(startDate.toString() + "Z"); - dataFrame.setDurationTime(durationNode.asInt()); - dataFrame.setPriority(priorityNode.asInt()); + List itemsList = new ArrayList<>(); + String item = null; + if (sequenceArrNode != null && sequenceArrNode.isArray()) { + for (final JsonNode objNode : sequenceArrNode) { + if (objNode.get("item").get("itis") != null) + item = mapper.treeToValue(objNode.get("item").get("itis"), String.class); + else if (objNode.get("item").get("text") != null) + item = mapper.treeToValue(objNode.get("item").get("text"), String.class); + if (!itemsList.contains(item)) + itemsList.add(item); + } + } - tim.setMsgCnt(timNode.get("msgCnt").asInt()); + // ADD NON ARRAY ELEMENT + if (sequenceArrNode != null && !sequenceArrNode.isArray()) { + if (sequenceArrNode.get("item").get("itis") != null) + item = mapper.treeToValue(sequenceArrNode.get("item").get("itis"), String.class); + else if (sequenceArrNode.get("item").get("text") != null) + item = mapper.treeToValue(sequenceArrNode.get("item").get("text"), String.class); - JsonNode packetIDNode = timNode.get("packetID"); - if (packetIDNode != null) { - tim.setPacketID(packetIDNode.asText()); - } + itemsList.add(item); + } - String[] items = new String[itemsList.size()]; - items = itemsList.toArray(items); + // TravelerInfoType.valueOf(); + JsonNode frameTypeNode = travelerDataFrame.get("frameType"); + if (frameTypeNode != null) { + if (frameTypeNode.fieldNames().hasNext()) { + TravelerInfoType frameType = TravelerInfoType.valueOf(frameTypeNode.fieldNames().next()); + if (frameType != null) { + dataFrame.setFrameType(frameType); + } + } + } - JsonNode geographicalPathNode = travelerDataFrame.findValue("GeographicalPath"); + JsonNode startTimeNode = travelerDataFrame.get("startTime"); + JsonNode durationNode = travelerDataFrame.get("durationTime"); + JsonNode priorityNode = travelerDataFrame.get("priority"); - // geographicalPathNode may be an object or an array; if it is an object, treat - // it as a region - if (geographicalPathNode.isObject()) { - // single region - JsonNode regionNode = geographicalPathNode; - Region region = getRegion(regionNode); - regions.add(region); - } else if (geographicalPathNode.isArray()) { - // multiple regions - for (final JsonNode regionNode : geographicalPathNode) { + LocalDateTime startDate = firstDay.atStartOfDay().plus(startTimeNode.asInt(), ChronoUnit.MINUTES); + + dataFrame.setStartDateTime(startDate.toString() + "Z"); + dataFrame.setDurationTime(durationNode.asInt()); + dataFrame.setPriority(priorityNode.asInt()); + + String[] items = new String[itemsList.size()]; + items = itemsList.toArray(items); + + JsonNode geographicalPathNode = travelerDataFrame.findValue("regions"); + + // geographicalPathNode may be an object or an array; if it is an object, treat + // it as a region + if (geographicalPathNode.isObject()) { + // single region + JsonNode regionNode = geographicalPathNode; Region region = getRegion(regionNode); regions.add(region); + } else if (geographicalPathNode.isArray()) { + // multiple regions + for (final JsonNode regionNode : geographicalPathNode) { + Region region = getRegion(regionNode); + regions.add(region); + } + } else { + System.out.println("warning: geographicalPathNode is not an object or an array"); } - } else { - System.out.println("warning: geographicalPathNode is not an object or an array"); - } - dataFrame.setRegions(regions.toArray(new OdeTravelerInformationMessage.DataFrame.Region[regions.size()])); - dataFrame.setItems(items); - dataFrames[0] = dataFrame; - tim.setDataframes(dataFrames); + dataFrame.setRegions(regions.toArray(OdeTravelerInformationMessage.DataFrame.Region[]::new)); + dataFrame.setItems(items); + dataFrames.add(dataFrame); + } + tim.setDataframes(dataFrames.toArray(OdeTravelerInformationMessage.DataFrame[]::new)); odeTimPayload = new OdeTimPayload(); odeTimPayload.setData(tim); } catch (IOException e) { From 011a6b461ff96c91354ec32891cfe61307f42650 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Tue, 24 Jun 2025 16:19:20 -0600 Subject: [PATCH 119/168] Update WydotTimRcController to use setItisCodes --- .../controller/WydotTimBaseController.java | 4 +-- .../controller/WydotTimRcController.java | 30 ++++++++++------- .../odewrapper/helpers/SetItisCodes.java | 33 ------------------- 3 files changed, 20 insertions(+), 47 deletions(-) diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java index 64cbcb672..9dee9f10a 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java @@ -346,8 +346,8 @@ protected ControllerResult validateInputRc(WydotTimRc tim) { } // set itis codes - List itisCodes = setItisCodes.setItisCodesRc(tim); - if (itisCodes.size() == 0) + List itisCodes = setItisCodes.setItisCodes(tim); + if (itisCodes.isEmpty()) resultMessages.add("No ITIS codes found"); result.setItisCodes(itisCodes); tim.setItisCodes(itisCodes); diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRcController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRcController.java index deac6a1dc..e23b190e1 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRcController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRcController.java @@ -3,6 +3,7 @@ import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.Date; import java.util.List; @@ -62,29 +63,34 @@ public ResponseEntity createUpdateRoadConditionsTim(@RequestBody TimRcLi utility.logWithDate(dateFormat.format(date) + " - Create Update RC TIM", this.getClass()); String post = gson.toJson(timRcList); - utility.logWithDate(post.toString(), this.getClass()); + utility.logWithDate(post, this.getClass()); - List resultList = new ArrayList(); - List errList = new ArrayList(); - ControllerResult resultTim = null; - List timsToSend = new ArrayList(); + List resultList = new ArrayList<>(); + List errList = new ArrayList<>(); + ControllerResult resultTim; + List timsToSend = new ArrayList<>(); // build TIM for (WydotTimRc wydotTim : timRcList.getTimRcList()) { resultTim = validateInputRc(wydotTim); - // workaround for geometry start/end point population - WydotTimRc wydotTimRc = wydotTim.copy(); - - if (resultTim.getResultMessages().size() > 0) { + if (!resultTim.getResultMessages().isEmpty()) { resultList.add(resultTim); errList.add(resultTim); continue; } - // add TIM to list for processing later - timsToSend.add(wydotTimRc); + // Each ITIS string in the TIM corresponds to a single TIM to be sent to ODE + for (String itisCodeEntry : wydotTim.getItisCodes()) { + List itisCodes = Arrays.asList(itisCodeEntry.split(" ")); + WydotTimRc timToSend = wydotTim.copy(); + timToSend.setItisCodes(itisCodes); + var itisCodeAbb = SetItisCodes.getItisCodeAbbreviation(itisCodeEntry); + String clientIdWithItis = wydotTim.getClientId() + '-' + wydotTim.getDirection() + '-' + itisCodeAbb; + timToSend.setClientId(clientIdWithItis); + timsToSend.add(timToSend); + } resultTim.getResultMessages().add("success"); resultList.add(resultTim); @@ -93,7 +99,7 @@ public ResponseEntity createUpdateRoadConditionsTim(@RequestBody TimRcLi processRequestAsync(timsToSend); String responseMessage = gson.toJson(resultList); - if (errList.size() > 0) { + if (!errList.isEmpty()) { utility.logWithDate("Failed to send TIMs: " + gson.toJson(errList), this.getClass()); } return ResponseEntity.status(HttpStatus.OK).body(responseMessage); diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java index 8c3381735..9bea2df50 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java @@ -64,39 +64,6 @@ public List setItisCodesFromAdvisoryArray(WydotTimRc wydotTim) { return items; } - public List setItisCodesRc(WydotTimRc wydotTim) { - - List items = new ArrayList<>(); - - if (wydotTim.getItisCodes() == null) { - return items; - } - - ItisCode code; - - for (String item : wydotTim.getItisCodes()) { - - Integer itisCode = Integer.valueOf(item); - - var alphaItis = getCustomAlphabetic(itisCode); - if (alphaItis != null) { - items.add(alphaItis); - continue; - } - // map "closed" itis code - if (itisCode == 769) { - code = getItisCodes().stream().filter(x -> x.getItisCode().equals(770)).findFirst().orElse(null); - } else { - code = getItisCodes().stream().filter(x -> x.getItisCode().equals(itisCode)).findFirst().orElse(null); - } - - if (code != null) - items.add(code.getItisCode().toString()); - } - - return items; - } - public String getCustomAlphabetic(Integer itisCode) { String text = null; var en = CustomItisEnum.valueOf(itisCode); From 457416ffa3aa87145519a1d501ef8e752095feb8 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Tue, 24 Jun 2025 16:19:34 -0600 Subject: [PATCH 120/168] Testing updates --- .../controller/ActiveTimControllerTest.java | 4 ++-- .../odewrapper/WydotTimIncidentControllerTest.java | 2 +- .../com/trihydro/odewrapper/WydotTimRcControllerTest.java | 4 ++-- .../com/trihydro/odewrapper/WydotTimRwControllerTest.java | 2 +- .../trihydro/odewrapper/WydotTimVslControllerTest.java | 2 +- .../com/trihydro/odewrapper/helpers/SetItisCodesTest.java | 8 ++++---- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/ActiveTimControllerTest.java b/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/ActiveTimControllerTest.java index f4fc50888..ec15f8425 100644 --- a/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/ActiveTimControllerTest.java +++ b/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/ActiveTimControllerTest.java @@ -486,7 +486,7 @@ public void GetBufferTimsByClientId_SUCCESS() throws SQLException { // Arrange String clientId = "clientId"; String selectStatement = "select * from active_tim where CLIENT_ID like '" + clientId - + "\\%BUFF_-%' ESCAPE '\\'"; + + "\\%BUFF-%' ESCAPE '\\'"; // Act ResponseEntity> data = uut.GetBufferTimsByClientId(clientId); @@ -518,7 +518,7 @@ public void GetBufferTimsByClientId_FAIL() throws SQLException { // Arrange String clientId = "clientId"; String selectStatement = "select * from active_tim where CLIENT_ID like '" + clientId - + "\\%BUFF_-%' ESCAPE '\\'"; + + "\\%BUFF-%' ESCAPE '\\'"; doThrow(new SQLException()).when(mockRs).getLong("ACTIVE_TIM_ID"); diff --git a/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimIncidentControllerTest.java b/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimIncidentControllerTest.java index 26c4d07eb..4b424c0f3 100644 --- a/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimIncidentControllerTest.java +++ b/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimIncidentControllerTest.java @@ -63,7 +63,7 @@ public void setup() throws Exception { itisCodes.add(ic); List itisCodesIncident = new ArrayList<>(); itisCodesIncident.add("531"); - lenient().doReturn(itisCodesIncident).when(setItisCodes).setItisCodesIncident(any()); + lenient().doReturn(itisCodesIncident).when(setItisCodes).setItisCodes(any()); lenient().doReturn(itisCodes).when(setItisCodes).getItisCodes(); lenient().doNothing().when(uut).makeTimsAsync(any()); diff --git a/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimRcControllerTest.java b/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimRcControllerTest.java index bd914b6e0..c9ceb3bbb 100644 --- a/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimRcControllerTest.java +++ b/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimRcControllerTest.java @@ -73,7 +73,7 @@ public void setup() throws Exception { itisCodes.add(ic); List itisCodesIncident = new ArrayList<>(); itisCodesIncident.add("531"); - lenient().doReturn(itisCodesIncident).when(setItisCodes).setItisCodesRc(any()); + lenient().doReturn(itisCodesIncident).when(setItisCodes).setItisCodes(any()); lenient().doReturn(itisCodes).when(setItisCodes).getItisCodes(); lenient().doReturn(true).when(uut).routeSupported(isA(String.class)); @@ -148,7 +148,7 @@ public void testCreateRcTim_bothDirections_NoItisCodes() throws Exception { // Arrange String rcJson = "{\"timRcList\": [{ \"route\": \"I80\", \"startPoint\": {\"latitude\": 41.161446, \"longitude\": -104.653162},\"endPoint\": {\"latitude\": 41.170465, \"longitude\": -104.085578},\"roadCode\": \"LARI80WQDHLD\", \"direction\":\"b\",\"advisory\": [11]} ]}"; TimRcList timRcList = gson.fromJson(rcJson, TimRcList.class); - lenient().doReturn(new ArrayList<>()).when(setItisCodes).setItisCodesRc(any()); + lenient().doReturn(new ArrayList<>()).when(setItisCodes).setItisCodes(any()); // Act ResponseEntity data = uut.createUpdateRoadConditionsTim(timRcList); diff --git a/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimRwControllerTest.java b/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimRwControllerTest.java index 7c933ca79..b632f272d 100644 --- a/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimRwControllerTest.java +++ b/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimRwControllerTest.java @@ -67,7 +67,7 @@ public void setup() throws Exception { itisCodes.add(ic); List itisCodesIncident = new ArrayList<>(); itisCodesIncident.add("531"); - lenient().doReturn(itisCodesIncident).when(setItisCodes).setItisCodesRw(any()); + lenient().doReturn(itisCodesIncident).when(setItisCodes).setItisCodes(any()); lenient().doReturn(itisCodes).when(setItisCodes).getItisCodes(); lenient().doReturn(true).when(uut).routeSupported(isA(String.class)); diff --git a/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimVslControllerTest.java b/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimVslControllerTest.java index 7f63d35f5..cb352011c 100644 --- a/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimVslControllerTest.java +++ b/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimVslControllerTest.java @@ -68,7 +68,7 @@ public void setup() throws Exception { itisCodes.add(ic); List itisCodesIncident = new ArrayList<>(); itisCodesIncident.add("531"); - lenient().doReturn(itisCodesIncident).when(mockSetItisCodes).setItisCodesVsl(any()); + lenient().doReturn(itisCodesIncident).when(mockSetItisCodes).setItisCodes(any()); lenient().doReturn(itisCodes).when(mockSetItisCodes).getItisCodes(); lenient().doNothing().when(uut).processRequestAsync(any()); diff --git a/ode-wrapper/src/test/java/com/trihydro/odewrapper/helpers/SetItisCodesTest.java b/ode-wrapper/src/test/java/com/trihydro/odewrapper/helpers/SetItisCodesTest.java index 2f9af1f7f..3704aa592 100644 --- a/ode-wrapper/src/test/java/com/trihydro/odewrapper/helpers/SetItisCodesTest.java +++ b/ode-wrapper/src/test/java/com/trihydro/odewrapper/helpers/SetItisCodesTest.java @@ -70,7 +70,7 @@ public void setItisCodesRc_numeric() { itisCodes.add("1309"); tim.setItisCodes(itisCodes); // Act - var result = uut.setItisCodesRc(tim); + var result = uut.setItisCodes(tim); // Assert Assertions.assertEquals(2, result.size()); @@ -86,7 +86,7 @@ public void setItisCodesRc_nonExistent() { itisCodes.add("13"); tim.setItisCodes(itisCodes); // Act - var result = uut.setItisCodesRc(tim); + var result = uut.setItisCodes(tim); // Assert Assertions.assertEquals(0, result.size()); @@ -102,7 +102,7 @@ public void setItisCodesRc_translated() { itisCodes.add("769"); tim.setItisCodes(itisCodes); // Act - var result = uut.setItisCodesRc(tim); + var result = uut.setItisCodes(tim); // Assert Assertions.assertEquals(2, result.size()); @@ -119,7 +119,7 @@ public void setItisCodesRc_alphabetic() { itisCodes.add(String.valueOf(CustomItisEnum.blowOver.getValue())); tim.setItisCodes(itisCodes); // Act - var result = uut.setItisCodesRc(tim); + var result = uut.setItisCodes(tim); // Assert Assertions.assertEquals(2, result.size()); From 900642a85e450cbcace7d9a26e6f5c2e0d013446 Mon Sep 17 00:00:00 2001 From: Marc Wodahl <56242265+mwodahl@users.noreply.github.com> Date: Tue, 24 Jun 2025 16:19:47 -0600 Subject: [PATCH 121/168] Add missing topic to kafka_init.sh --- local-deployment/kafka/kafka_init.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/local-deployment/kafka/kafka_init.sh b/local-deployment/kafka/kafka_init.sh index 9ed08f089..f9dbe553e 100644 --- a/local-deployment/kafka/kafka_init.sh +++ b/local-deployment/kafka/kafka_init.sh @@ -13,6 +13,7 @@ echo 'Creating kafka topics' /opt/bitnami/kafka/bin/kafka-topics.sh --create --if-not-exists --topic "topic.OdeBsmJson" --bootstrap-server kafka:9092 --replication-factor 1 --partitions 1 /opt/bitnami/kafka/bin/kafka-topics.sh --create --if-not-exists --topic "topic.FilteredOdeBsmJson" --bootstrap-server kafka:9092 --replication-factor 1 --partitions 1 /opt/bitnami/kafka/bin/kafka-topics.sh --create --if-not-exists --topic "topic.OdeTimJson" --bootstrap-server kafka:9092 --replication-factor 1 --partitions 1 +/opt/bitnami/kafka/bin/kafka-topics.sh --create --if-not-exists --topic "topic.OdeTimJsonTMCFiltered" --bootstrap-server kafka:9092 --replication-factor 1 --partitions 1 /opt/bitnami/kafka/bin/kafka-topics.sh --create --if-not-exists --topic "topic.OdeTimBroadcastJson" --bootstrap-server kafka:9092 --replication-factor 1 --partitions 1 /opt/bitnami/kafka/bin/kafka-topics.sh --create --if-not-exists --topic "topic.J2735TimBroadcastJson" --bootstrap-server kafka:9092 --replication-factor 1 --partitions 1 /opt/bitnami/kafka/bin/kafka-topics.sh --create --if-not-exists --topic "topic.OdeDriverAlertJson" --bootstrap-server kafka:9092 --replication-factor 1 --partitions 1 From f54d262683a1b3e52d3a35b4de479b90d86d2104 Mon Sep 17 00:00:00 2001 From: pmonington Date: Fri, 19 Sep 2025 13:56:52 -0600 Subject: [PATCH 122/168] chore: add GNIS ID configurable variable for packet id suffix for CTW compliance --- .../library/service/WydotTimService.java | 5 +++-- .../library/service/WydotTimServiceTest.java | 18 ++++++++++++------ docker-compose.yml | 1 + ode-wrapper/README.md | 1 + .../odewrapper/config/BasicConfiguration.java | 9 +++++++++ .../controller/WydotTimBaseController.java | 4 ++-- .../main/resources/application-dev.properties | 1 + sample.env | 1 + 8 files changed, 30 insertions(+), 10 deletions(-) diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java b/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java index f1ab3b7ca..2111c4d04 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java @@ -114,7 +114,7 @@ public void InjectDependencies(EmailProps _emailProps, OdeProps _odeProps, TimGe public WydotTravelerInputData createTim(WydotTim wydotTim, String timTypeStr, String startDateTime, String endDateTime, ContentEnum content, TravelerInfoType frameType, List allMileposts, - List reducedMileposts, Milepost anchor) { + List reducedMileposts, Milepost anchor, String dotGnisId) { // build base TIM WydotTravelerInputData timToSend = createBaseTimUtil.buildTim(wydotTim, genProps, content, frameType, @@ -147,9 +147,10 @@ public WydotTravelerInputData createTim(WydotTim wydotTim, String timTypeStr, St timToSend.getTim().getDataframes()[0].setDurationTime(120); } - // set PacketId to a random 18 character hex value + // Set PacketId as an 18-character hex string: DOT GNIS ID + random hex suffix Random rand = new Random(); StringBuffer sb = new StringBuffer(); + sb.append(dotGnisId); while (sb.length() < 18) { sb.append(Integer.toHexString(rand.nextInt())); } diff --git a/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java b/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java index 1c658cf52..7438e62ed 100644 --- a/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java +++ b/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java @@ -231,11 +231,12 @@ public void createTim_ReturnsNull_WhenBuildTimReturnsNull() { List allMileposts = new ArrayList<>(); List reducedMileposts = new ArrayList<>(); Milepost anchor = new Milepost(); + String dotGnisId = "1B2843"; when(mockCreateBaseTimUtil.buildTim(any(), any(), any(), any(), any(), any(), any())).thenReturn(null); // Act - WydotTravelerInputData result = uut.createTim(new WydotTim(), timTypeStr, startDateTime, endDateTime, content, frameType, allMileposts, reducedMileposts, anchor); + WydotTravelerInputData result = uut.createTim(new WydotTim(), timTypeStr, startDateTime, endDateTime, content, frameType, allMileposts, reducedMileposts, anchor, dotGnisId); // Assert assertNull(result); @@ -252,13 +253,14 @@ public void createTim_SetsStartDateTime_WhenProvided() { List allMileposts = new ArrayList<>(); List reducedMileposts = new ArrayList<>(); Milepost anchor = new Milepost(); + String dotGnisId = "1B2843"; WydotTravelerInputData timToSend = getMockWydotTravelerInputDataWithDataFrame(); when(mockCreateBaseTimUtil.buildTim(any(), any(), any(), any(), any(), any(), any())).thenReturn(timToSend); // Act - WydotTravelerInputData result = uut.createTim(new WydotTim(), timTypeStr, startDateTime, endDateTime, content, frameType, allMileposts, reducedMileposts, anchor); + WydotTravelerInputData result = uut.createTim(new WydotTim(), timTypeStr, startDateTime, endDateTime, content, frameType, allMileposts, reducedMileposts, anchor, dotGnisId); // Assert assertEquals(startDateTime, result.getTim().getDataframes()[0].getStartDateTime()); @@ -275,6 +277,7 @@ public void createTim_SetsDurationTime_WhenEndDateTimeProvided() { List allMileposts = new ArrayList<>(); List reducedMileposts = new ArrayList<>(); Milepost anchor = new Milepost(); + String dotGnisId = "1B2843"; WydotTravelerInputData timToSend = getMockWydotTravelerInputDataWithDataFrame(); @@ -282,7 +285,7 @@ public void createTim_SetsDurationTime_WhenEndDateTimeProvided() { when(mockUtility.getMinutesDurationBetweenTwoDates(anyString(), anyString())).thenReturn(60); // Act - WydotTravelerInputData result = uut.createTim(new WydotTim(), timTypeStr, startDateTime, endDateTime, content, frameType, allMileposts, reducedMileposts, anchor); + WydotTravelerInputData result = uut.createTim(new WydotTim(), timTypeStr, startDateTime, endDateTime, content, frameType, allMileposts, reducedMileposts, anchor, dotGnisId); // Assert assertEquals(60, result.getTim().getDataframes()[0].getDurationTime()); @@ -299,20 +302,21 @@ public void createTim_SetsDurationTimeTo120_ForParkingTim() { List allMileposts = new ArrayList<>(); List reducedMileposts = new ArrayList<>(); Milepost anchor = new Milepost(); + String dotGnisId = "1B2843"; WydotTravelerInputData timToSend = getMockWydotTravelerInputDataWithDataFrame(); when(mockCreateBaseTimUtil.buildTim(any(), any(), any(), any(), any(), any(), any())).thenReturn(timToSend); // Act - WydotTravelerInputData result = uut.createTim(new WydotTim(), timTypeStr, startDateTime, endDateTime, content, frameType, allMileposts, reducedMileposts, anchor); + WydotTravelerInputData result = uut.createTim(new WydotTim(), timTypeStr, startDateTime, endDateTime, content, frameType, allMileposts, reducedMileposts, anchor, dotGnisId); // Assert assertEquals(120, result.getTim().getDataframes()[0].getDurationTime()); } @Test - public void createTim_SetsRandomPacketId() { + public void createTim_SetsRandomPacketIdWithGnisIdPrefix() { // Arrange String timTypeStr = "A"; String startDateTime = "2023-01-01T00:00:00.000Z"; @@ -322,18 +326,20 @@ public void createTim_SetsRandomPacketId() { List allMileposts = new ArrayList<>(); List reducedMileposts = new ArrayList<>(); Milepost anchor = new Milepost(); + String dotGnisId = "1B2843"; WydotTravelerInputData timToSend = getMockWydotTravelerInputDataWithDataFrame(); when(mockCreateBaseTimUtil.buildTim(any(), any(), any(), any(), any(), any(), any())).thenReturn(timToSend); // Act - WydotTravelerInputData result = uut.createTim(new WydotTim(), timTypeStr, startDateTime, endDateTime, content, frameType, allMileposts, reducedMileposts, anchor); + WydotTravelerInputData result = uut.createTim(new WydotTim(), timTypeStr, startDateTime, endDateTime, content, frameType, allMileposts, reducedMileposts, anchor, dotGnisId); // Assert assertNotNull(result.getTim().getPacketID()); assertEquals(18, result.getTim().getPacketID().length()); assertTrue(result.getTim().getPacketID().matches("[0-9A-F]+")); + assertTrue(result.getTim().getPacketID().startsWith("1B2843")); } @Test diff --git a/docker-compose.yml b/docker-compose.yml index af0a6d10d..e6cb90a29 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -12,6 +12,7 @@ services: CONFIG_MAXIMUM_POOL_SIZE: ${WRAPPER_CONFIG_MAXIMUM_POOL_SIZE} CONFIG_CONNECTION_TIMEOUT: ${WRAPPER_CONFIG_CONNECTION_TIMEOUT} CONFIG_ENV: ${WRAPPER_CONFIG_ENV} + CONFIG_DB_DOT_GNIS_ID: ${WRAPPER_CONFIG_DOT_GNIS_ID} CONFIG_SDW_TTL: ${WRAPPER_CONFIG_SDW_TTL} CONFIG_SDW_REST_URL: ${SDW_REST_URL} CONFIG_SDW_API_KEY: ${SDW_API_KEY} diff --git a/ode-wrapper/README.md b/ode-wrapper/README.md index 91011f05d..9229e14ef 100644 --- a/ode-wrapper/README.md +++ b/ode-wrapper/README.md @@ -120,6 +120,7 @@ You may configure these values in `ode-wrapper/src/main/resources/application.pr | CONFIG_MAXIMUM_POOL_SIZE | WRAPPER_CONFIG_MAXIMUM_POOL_SIZE | config.maximumPoolSize | Number of threads in ThreadPool | 7 | | CONFIG_CONNECTION_TIMEOUT | WRAPPER_CONFIG_CONNECTION_TIMEOUT | config.connectionTimeout | Connection timeout in milliseconds | 10000 | | CONFIG_ENV | WRAPPER_CONFIG_ENV | config.env | Configuration environment | dev | +| CONFIG_DOT_GNIS_ID | WRAPPER_CONFIG_DOT_GNIS_ID | config.dotGnisId | GNIS ID of the DOT | 1B2843 | | CONFIG_SDW_TTL | WRAPPER_CONFIG_SDW_TTL | config.sdwTtl | SDW time to live default | oneday | | CONFIG_SDW_REST_URL | SDW_REST_URL | config.sdwRestUrl | REST endpoint for SDX | https://sdx-endpoint.com | | CONFIG_SDW_API_KEY | SDW_API_KEY | config.sdwApiKey | API Key for accessing SDX | asdf | diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/config/BasicConfiguration.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/config/BasicConfiguration.java index 4b9177252..6295f430b 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/config/BasicConfiguration.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/config/BasicConfiguration.java @@ -26,6 +26,7 @@ public class BasicConfiguration implements SdwProps, RsuDataServiceProps, TmddPr private String odeUrl; private String sdwRestUrl; private String sdwApiKey; + private String dotGnisId; private String mailHost; private int mailPort; private String[] alertAddresses; @@ -60,6 +61,14 @@ public void setPointIncidentBufferMiles(Double pointIncidentBufferMiles) { this.pointIncidentBufferMiles = pointIncidentBufferMiles; } + public String getDotGnisId() { + return dotGnisId; + } + + public void setDotGnisId(String dotGnisId) { + this.dotGnisId = dotGnisId; + } + public String getFromEmail() { return fromEmail; } diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java index 276123c33..4decb72f5 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java @@ -676,7 +676,7 @@ protected void createSendTims(WydotTim wydotTim, TimType timType, String startDa // create TIM WydotTravelerInputData timToSend = wydotTimService.createTim(wydotTim, timType.getType(), startDateTime, - endDateTime, content, frameType, allMileposts, reducedMileposts, anchor); + endDateTime, content, frameType, allMileposts, reducedMileposts, anchor, configuration.getDotGnisId()); if (timToSend == null) { return; @@ -704,7 +704,7 @@ protected void createSendTims(WydotTim wydotTim, TimType timType, String startDa /** * This method returns the anchor point for the given mileposts. - * + * * @param firstPoint The first milepost. * @param secondPoint The second milepost. * @return The anchor point as a Milepost. diff --git a/ode-wrapper/src/main/resources/application-dev.properties b/ode-wrapper/src/main/resources/application-dev.properties index efb8a6b36..80d4f6547 100644 --- a/ode-wrapper/src/main/resources/application-dev.properties +++ b/ode-wrapper/src/main/resources/application-dev.properties @@ -13,6 +13,7 @@ config.sdwApiKey= config.alertAddresses=user@example.com,user2@example.com config.fromEmail=support@example.com config.environmentName=DEV +config.dotGnisId=1B2843 config.mailHost=localhost config.mailPort=25 config.defaultLaneWidth=50 diff --git a/sample.env b/sample.env index 936596b87..437a594fc 100644 --- a/sample.env +++ b/sample.env @@ -81,6 +81,7 @@ WRAPPER_CONFIG_DB_PASSWORD= WRAPPER_CONFIG_MAXIMUM_POOL_SIZE=7 WRAPPER_CONFIG_CONNECTION_TIMEOUT=300000 WRAPPER_CONFIG_ENV=dev +WRAPPER_CONFIG_DOT_GNIS_ID= WRAPPER_CONFIG_SDW_TTL=oneday WRAPPER_CONFIG_ALERT_ADDRESSES=user@example.com,user2@example.com WRAPPER_CONFIG_FROM_EMAIL=support@example.com From 2bff6f515b4b82a37e7df4103e399ee402a5f323 Mon Sep 17 00:00:00 2001 From: pmonington Date: Fri, 19 Sep 2025 14:08:08 -0600 Subject: [PATCH 123/168] docs: add details for other dots for packetID variable to readme --- ode-wrapper/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ode-wrapper/README.md b/ode-wrapper/README.md index 9229e14ef..ff32a3774 100644 --- a/ode-wrapper/README.md +++ b/ode-wrapper/README.md @@ -120,7 +120,7 @@ You may configure these values in `ode-wrapper/src/main/resources/application.pr | CONFIG_MAXIMUM_POOL_SIZE | WRAPPER_CONFIG_MAXIMUM_POOL_SIZE | config.maximumPoolSize | Number of threads in ThreadPool | 7 | | CONFIG_CONNECTION_TIMEOUT | WRAPPER_CONFIG_CONNECTION_TIMEOUT | config.connectionTimeout | Connection timeout in milliseconds | 10000 | | CONFIG_ENV | WRAPPER_CONFIG_ENV | config.env | Configuration environment | dev | -| CONFIG_DOT_GNIS_ID | WRAPPER_CONFIG_DOT_GNIS_ID | config.dotGnisId | GNIS ID of the DOT | 1B2843 | +| CONFIG_DOT_GNIS_ID | WRAPPER_CONFIG_DOT_GNIS_ID | config.dotGnisId | GNIS ID of the DOT used for the packetID | CDOT: 1B2843, UDOT: 163775, WYDOT: 1B285F | | CONFIG_SDW_TTL | WRAPPER_CONFIG_SDW_TTL | config.sdwTtl | SDW time to live default | oneday | | CONFIG_SDW_REST_URL | SDW_REST_URL | config.sdwRestUrl | REST endpoint for SDX | https://sdx-endpoint.com | | CONFIG_SDW_API_KEY | SDW_API_KEY | config.sdwApiKey | API Key for accessing SDX | asdf | From f34fe0f171c7baf39c7182280195b2b4d1ecf5c9 Mon Sep 17 00:00:00 2001 From: pmonington Date: Mon, 22 Sep 2025 08:34:17 -0600 Subject: [PATCH 124/168] chore: change default to 000000 and add log for if the default was not changed in the configuration file --- .../library/service/WydotTimService.java | 3 ++ .../library/service/WydotTimServiceTest.java | 27 +++++++++++++++++ .../main/resources/application-dev.properties | 2 +- .../src/main/resources/application.properties | 30 +++++++++++++++++++ 4 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 ode-wrapper/src/main/resources/application.properties diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java b/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java index 2111c4d04..e2bfa035b 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java @@ -150,6 +150,9 @@ public WydotTravelerInputData createTim(WydotTim wydotTim, String timTypeStr, St // Set PacketId as an 18-character hex string: DOT GNIS ID + random hex suffix Random rand = new Random(); StringBuffer sb = new StringBuffer(); + if (dotGnisId.equals("000000")) { + utility.logWithDate("WARNING: DOT GNIS ID is set to default value of 000000. This is not a valid GNIS ID and should be changed in the configuration."); + } sb.append(dotGnisId); while (sb.length() < 18) { sb.append(Integer.toHexString(rand.nextInt())); diff --git a/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java b/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java index 7438e62ed..aa0c578b8 100644 --- a/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java +++ b/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java @@ -342,6 +342,33 @@ public void createTim_SetsRandomPacketIdWithGnisIdPrefix() { assertTrue(result.getTim().getPacketID().startsWith("1B2843")); } + @Test + public void createTim_SetsRandomPacketIdUnsetGNISId() { + // Arrange + String timTypeStr = "A"; + String startDateTime = "2023-01-01T00:00:00.000Z"; + String endDateTime = "2023-01-01T01:00:00.000Z"; + ContentEnum content = ContentEnum.workZone; + TravelerInfoType frameType = TravelerInfoType.advisory; + List allMileposts = new ArrayList<>(); + List reducedMileposts = new ArrayList<>(); + Milepost anchor = new Milepost(); + String dotGnisId = "000000"; + + WydotTravelerInputData timToSend = getMockWydotTravelerInputDataWithDataFrame(); + + when(mockCreateBaseTimUtil.buildTim(any(), any(), any(), any(), any(), any(), any())).thenReturn(timToSend); + + // Act + WydotTravelerInputData result = uut.createTim(new WydotTim(), timTypeStr, startDateTime, endDateTime, content, frameType, allMileposts, reducedMileposts, anchor, dotGnisId); + + // Assert + assertNotNull(result.getTim().getPacketID()); + assertEquals(18, result.getTim().getPacketID().length()); + assertTrue(result.getTim().getPacketID().matches("[0-9A-F]+")); + verify(mockUtility).logWithDate("WARNING: DOT GNIS ID is set to default value of 000000. This is not a valid GNIS ID and should be changed in the configuration."); + } + @Test public void getAllMilepostsForTim_EndPointNotNull() { // Arrange diff --git a/ode-wrapper/src/main/resources/application-dev.properties b/ode-wrapper/src/main/resources/application-dev.properties index 80d4f6547..228418409 100644 --- a/ode-wrapper/src/main/resources/application-dev.properties +++ b/ode-wrapper/src/main/resources/application-dev.properties @@ -13,7 +13,7 @@ config.sdwApiKey= config.alertAddresses=user@example.com,user2@example.com config.fromEmail=support@example.com config.environmentName=DEV -config.dotGnisId=1B2843 +config.dotGnisId=000000 config.mailHost=localhost config.mailPort=25 config.defaultLaneWidth=50 diff --git a/ode-wrapper/src/main/resources/application.properties b/ode-wrapper/src/main/resources/application.properties new file mode 100644 index 000000000..228418409 --- /dev/null +++ b/ode-wrapper/src/main/resources/application.properties @@ -0,0 +1,30 @@ +server.port=7777 + +config.odeUrl=https://localhost:8443 +config.dbUrl=jdbc:postgresql://localhost:5432/dbname +config.dbUsername=username +config.dbPassword=password +config.maximumPoolSize=7 +config.connectionTimeout=300000 +config.env=dev + +config.sdwRestUrl=https://sdx.trihydro.com/ +config.sdwApiKey= +config.alertAddresses=user@example.com,user2@example.com +config.fromEmail=support@example.com +config.environmentName=DEV +config.dotGnisId=000000 +config.mailHost=localhost +config.mailPort=25 +config.defaultLaneWidth=50 +config.cvRestService=http://localhost:8888 +config.httpLoggingMaxSize=2000 +# Note the rsuRoutes will need to reflect what's passed in, and what is in the rsu_view view +config.rsuRoutes=route1, route2 +config.pointIncidentBufferMiles=1 +config.sdwTtl=oneyear + +# server.ssl.key-store: classpath:keystore.jks +# server.ssl.key-store-password:password +# server.ssl.keyStoreType: JKS +# server.ssl.keyAlias: some-alias \ No newline at end of file From 825014550072554364fecf6cd805340d0aa93560 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Mon, 29 Sep 2025 15:34:13 -0600 Subject: [PATCH 125/168] git: resolve compilation errors --- .../com/trihydro/library/helpers/TimGenerationHelper.java | 2 +- .../trihydro/odewrapper/controller/UtilityController.java | 5 +++-- .../odewrapper/controller/WydotTimIncidentController.java | 5 +---- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/TimGenerationHelper.java b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/TimGenerationHelper.java index a887a0cc8..c42d47113 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/TimGenerationHelper.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/TimGenerationHelper.java @@ -352,7 +352,7 @@ private WydotTim getWydotTimFromTum(TimUpdateModel tum) { } private List getAllMps(WydotTim wydotTim) { - List allMps; + List allMps = new ArrayList<>(); log.info("Fetching mileposts for regular TIM with client id: {}", wydotTim.getClientId()); if (wydotTim.getEndPoint() != null) { diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/UtilityController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/UtilityController.java index 0ce1fca0a..035d9a1db 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/UtilityController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/UtilityController.java @@ -6,6 +6,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import com.trihydro.library.exceptionhandlers.IdenticalPointsExceptionHandler; import com.trihydro.library.helpers.MilepostReduction; import com.trihydro.library.helpers.TimGenerationHelper; import com.trihydro.library.helpers.Utility; @@ -58,9 +59,9 @@ class RsuClearSuccess { public UtilityController(BasicConfiguration _basicConfiguration, WydotTimService _wydotTimService, TimTypeService _timTypeService, SetItisCodes _setItisCodes, ActiveTimService _activeTimService, OdeService _odeService, RestTemplateProvider _restTemplateProvider, MilepostReduction _milepostReduction, - Utility _utility, TimGenerationHelper _timGenerationHelper, MilepostService _milepostService) { + Utility _utility, TimGenerationHelper _timGenerationHelper, MilepostService _milepostService, IdenticalPointsExceptionHandler identicalPointsExceptionHandler) { super(_basicConfiguration, _wydotTimService, _timTypeService, _setItisCodes, _activeTimService, - _restTemplateProvider, _milepostReduction, _utility, _timGenerationHelper, _milepostService); + _restTemplateProvider, _milepostReduction, _utility, _timGenerationHelper, _milepostService, identicalPointsExceptionHandler); this.odeService = _odeService; } diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java index 35db62e50..acb82a781 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java @@ -3,10 +3,7 @@ import com.trihydro.library.exceptionhandlers.IdenticalPointsExceptionHandler; import java.text.DateFormat; import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; +import java.util.*; import com.trihydro.library.helpers.MilepostReduction; import com.trihydro.library.helpers.TimGenerationHelper; From acac37150b789066e131682fdb69fa2649d89592 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Mon, 29 Sep 2025 15:51:48 -0600 Subject: [PATCH 126/168] test: fix failing unit tests in TimGenerationHelperTest --- .../com/trihydro/library/helpers/TimGenerationHelperTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cv-data-service-library/src/test/java/com/trihydro/library/helpers/TimGenerationHelperTest.java b/cv-data-service-library/src/test/java/com/trihydro/library/helpers/TimGenerationHelperTest.java index 45a28bc0c..8de027e45 100644 --- a/cv-data-service-library/src/test/java/com/trihydro/library/helpers/TimGenerationHelperTest.java +++ b/cv-data-service-library/src/test/java/com/trihydro/library/helpers/TimGenerationHelperTest.java @@ -802,7 +802,7 @@ public void resubmitToOde_IdenticalPointsException_SuccessfulRecovery() throws U verify(mockActiveTimHoldingService).insertActiveTimHolding(any()); verify(mockMilepostService).getMilepostsByStartEndPointDirection(any()); verify(mockMilepostReduction).applyMilepostReductionAlgorithm(any(), any()); - verifyNoMoreInteractions(mockMilepostService, mockMilepostReduction, mockDataFrameService, + verifyNoMoreInteractions(mockMilepostReduction, mockDataFrameService, mockRsuService, mockOdeService, mockActiveTimHoldingService); } @@ -827,7 +827,7 @@ public void resubmitToOde_IdenticalPointsException_FailureToRecover() throws Uti var ex = exceptions.get(0); Assertions.assertEquals(new ResubmitTimException(activeTimId, String.format("Unable to resubmit TIM, identical points found while calculating anchor point for Active_Tim %d", activeTimId)), ex); verifyNoInteractions(mockPathNodeXYService); - verifyNoMoreInteractions(mockMilepostService, mockMilepostReduction, mockDataFrameService, + verifyNoMoreInteractions(mockMilepostReduction, mockDataFrameService, mockRsuService, mockOdeService, mockActiveTimHoldingService); } From eb221a3a8c072fe2ad14401136b4c0a151e94a89 Mon Sep 17 00:00:00 2001 From: Paige Monington Date: Thu, 2 Oct 2025 12:22:03 -0600 Subject: [PATCH 127/168] chore: adjust application properties to use spring to load env variable --- .../main/resources/application-dev.properties | 2 +- .../src/main/resources/application.properties | 30 ------------------- 2 files changed, 1 insertion(+), 31 deletions(-) delete mode 100644 ode-wrapper/src/main/resources/application.properties diff --git a/ode-wrapper/src/main/resources/application-dev.properties b/ode-wrapper/src/main/resources/application-dev.properties index 228418409..ac3f25848 100644 --- a/ode-wrapper/src/main/resources/application-dev.properties +++ b/ode-wrapper/src/main/resources/application-dev.properties @@ -13,7 +13,7 @@ config.sdwApiKey= config.alertAddresses=user@example.com,user2@example.com config.fromEmail=support@example.com config.environmentName=DEV -config.dotGnisId=000000 +config.dotGnisId=${WRAPPER_CONFIG_DOT_GNIS_ID:000000} config.mailHost=localhost config.mailPort=25 config.defaultLaneWidth=50 diff --git a/ode-wrapper/src/main/resources/application.properties b/ode-wrapper/src/main/resources/application.properties deleted file mode 100644 index 228418409..000000000 --- a/ode-wrapper/src/main/resources/application.properties +++ /dev/null @@ -1,30 +0,0 @@ -server.port=7777 - -config.odeUrl=https://localhost:8443 -config.dbUrl=jdbc:postgresql://localhost:5432/dbname -config.dbUsername=username -config.dbPassword=password -config.maximumPoolSize=7 -config.connectionTimeout=300000 -config.env=dev - -config.sdwRestUrl=https://sdx.trihydro.com/ -config.sdwApiKey= -config.alertAddresses=user@example.com,user2@example.com -config.fromEmail=support@example.com -config.environmentName=DEV -config.dotGnisId=000000 -config.mailHost=localhost -config.mailPort=25 -config.defaultLaneWidth=50 -config.cvRestService=http://localhost:8888 -config.httpLoggingMaxSize=2000 -# Note the rsuRoutes will need to reflect what's passed in, and what is in the rsu_view view -config.rsuRoutes=route1, route2 -config.pointIncidentBufferMiles=1 -config.sdwTtl=oneyear - -# server.ssl.key-store: classpath:keystore.jks -# server.ssl.key-store-password:password -# server.ssl.keyStoreType: JKS -# server.ssl.keyAlias: some-alias \ No newline at end of file From e6671feb5fe291ae50c28005b0225402dd03db89 Mon Sep 17 00:00:00 2001 From: Paige Monington Date: Thu, 2 Oct 2025 13:08:37 -0600 Subject: [PATCH 128/168] chore: remove log based verification and replace utility with log --- cv-data-service-library/pom.xml | 5 +++++ .../java/com/trihydro/library/service/WydotTimService.java | 4 +++- .../com/trihydro/library/service/WydotTimServiceTest.java | 1 - 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/cv-data-service-library/pom.xml b/cv-data-service-library/pom.xml index 1127a39b3..3f1c20e13 100644 --- a/cv-data-service-library/pom.xml +++ b/cv-data-service-library/pom.xml @@ -116,6 +116,11 @@ jakarta.xml.bind-api 4.0.0 + + org.projectlombok + lombok + provided + diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java b/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java index 771fcfb41..d763995ca 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java @@ -11,6 +11,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpEntity; @@ -55,6 +56,7 @@ import us.dot.its.jpo.ode.plugin.j2735.timstorage.FrameType.TravelerInfoType; @Component +@Slf4j public class WydotTimService { protected EmailProps emailProps; @@ -151,7 +153,7 @@ public WydotTravelerInputData createTim(WydotTim wydotTim, String timTypeStr, St Random rand = new Random(); StringBuffer sb = new StringBuffer(); if (dotGnisId.equals("000000")) { - utility.logWithDate("WARNING: DOT GNIS ID is set to default value of 000000. This is not a valid GNIS ID and should be changed in the configuration."); + log.warn("DOT GNIS ID is set to default value of 000000. This is not a valid GNIS ID and should be changed in the configuration."); } sb.append(dotGnisId); while (sb.length() < 18) { diff --git a/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java b/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java index 03a15fc69..3d32d9b8c 100644 --- a/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java +++ b/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java @@ -366,7 +366,6 @@ public void createTim_SetsRandomPacketIdUnsetGNISId() { assertNotNull(result.getTim().getPacketID()); assertEquals(18, result.getTim().getPacketID().length()); assertTrue(result.getTim().getPacketID().matches("[0-9A-F]+")); - verify(mockUtility).logWithDate("WARNING: DOT GNIS ID is set to default value of 000000. This is not a valid GNIS ID and should be changed in the configuration."); } @Test From fc49b36b371fa41e8a4499c05be326485b5c7cc6 Mon Sep 17 00:00:00 2001 From: Paige Monington Date: Fri, 3 Oct 2025 15:40:53 -0600 Subject: [PATCH 129/168] chore: adjust whitespace --- .../controller/WydotTimBaseController.java | 86 +++++++++---------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java index 88a4cc625..1b31818b3 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java @@ -75,9 +75,9 @@ public abstract class WydotTimBaseController { protected final List bufferTimITISCodes; public WydotTimBaseController(BasicConfiguration _basicConfiguration, WydotTimService _wydotTimService, - TimTypeService _timTypeService, SetItisCodes _setItisCodes, ActiveTimService _activeTimService, - RestTemplateProvider _restTemplateProvider, MilepostReduction _milepostReduction, Utility _utility, - TimGenerationHelper _timGenerationHelper, MilepostService _milepostService, IdenticalPointsExceptionHandler identicalPointsExceptionHandler) { + TimTypeService _timTypeService, SetItisCodes _setItisCodes, ActiveTimService _activeTimService, + RestTemplateProvider _restTemplateProvider, MilepostReduction _milepostReduction, Utility _utility, + TimGenerationHelper _timGenerationHelper, MilepostService _milepostService, IdenticalPointsExceptionHandler identicalPointsExceptionHandler) { configuration = _basicConfiguration; wydotTimService = _wydotTimService; timTypeService = _timTypeService; @@ -133,8 +133,8 @@ protected ControllerResult validateInputParking(WydotTimParking tim) { } // if direction is not i/d/b fail if (!tim.getDirection().equalsIgnoreCase("i") && - !tim.getDirection().equalsIgnoreCase("d") && - !tim.getDirection().equalsIgnoreCase("b")) { + !tim.getDirection().equalsIgnoreCase("d") && + !tim.getDirection().equalsIgnoreCase("b")) { resultMessages.add("direction not supported"); } if (tim.getMileMarker() != null && tim.getMileMarker() < 0) { @@ -182,8 +182,8 @@ public ControllerResult validateInputIncident(WydotTimIncident tim) { // if direction is not i/d/b fail if (!tim.getDirection().equalsIgnoreCase("i") && - !tim.getDirection().equalsIgnoreCase("d") && - !tim.getDirection().equalsIgnoreCase("b")) { + !tim.getDirection().equalsIgnoreCase("d") && + !tim.getDirection().equalsIgnoreCase("b")) { resultMessages.add("direction not supported"); } if (tim.getIncidentId() == null) { @@ -225,8 +225,8 @@ protected ControllerResult validateInputRw(WydotTimRw tim) { // if direction is not i/d/b fail if (!tim.getDirection().equalsIgnoreCase("i") && - !tim.getDirection().equalsIgnoreCase("d") && - !tim.getDirection().equalsIgnoreCase("b")) { + !tim.getDirection().equalsIgnoreCase("d") && + !tim.getDirection().equalsIgnoreCase("b")) { resultMessages.add("direction not supported"); } @@ -253,27 +253,27 @@ protected ControllerResult validateInputRw(WydotTimRw tim) { } else { try { var convertedDate = - LocalDate.parse(tim.getSchedStart(), DateTimeFormatter.ISO_LOCAL_DATE); + LocalDate.parse(tim.getSchedStart(), DateTimeFormatter.ISO_LOCAL_DATE); var startOfDay = convertedDate.atStartOfDay(ZoneId.systemDefault()); tim.setSchedStart(getIsoDateTimeString(startOfDay)); } catch (DateTimeParseException e) { resultMessages.add( - "Bad value supplied for schedStart. Should follow the format: yyyy-MM-dd"); + "Bad value supplied for schedStart. Should follow the format: yyyy-MM-dd"); e.printStackTrace(); } } if (tim.getSchedEnd() != null) { try { var convertedDate = - LocalDate.parse(tim.getSchedEnd(), DateTimeFormatter.ISO_LOCAL_DATE); + LocalDate.parse(tim.getSchedEnd(), DateTimeFormatter.ISO_LOCAL_DATE); // LocalTime.MAX sets the time to 11:59 PM. This is especially important when // construction is only scheduled for a day (ex. 5-12 to 5-12) var endOfDay = ZonedDateTime.of(LocalDateTime.of(convertedDate, LocalTime.MAX), - ZoneId.systemDefault()); + ZoneId.systemDefault()); tim.setSchedEnd(getIsoDateTimeString(endOfDay)); } catch (DateTimeParseException e) { resultMessages.add( - "Bad value supplied for schedEnd. Should follow the format: yyyy-MM-dd"); + "Bad value supplied for schedEnd. Should follow the format: yyyy-MM-dd"); e.printStackTrace(); } } @@ -342,8 +342,8 @@ protected ControllerResult validateInputRc(WydotTimRc tim) { } // if direction is not i/d/b fail if (tim.getDirection() != null && !tim.getDirection().equalsIgnoreCase("i") && - !tim.getDirection().equalsIgnoreCase("d") && - !tim.getDirection().equalsIgnoreCase("b")) { + !tim.getDirection().equalsIgnoreCase("d") && + !tim.getDirection().equalsIgnoreCase("b")) { resultMessages.add("direction not supported"); } @@ -396,8 +396,8 @@ protected ControllerResult validateRcAc(WydotTimRc allClear) { if (allClear.getDirection() == null) { resultMessages.add("Null value for direction"); } else if (!allClear.getDirection().equalsIgnoreCase("i") && - !allClear.getDirection().equalsIgnoreCase("d") && - !allClear.getDirection().equalsIgnoreCase("b")) { + !allClear.getDirection().equalsIgnoreCase("d") && + !allClear.getDirection().equalsIgnoreCase("b")) { resultMessages.add("direction not supported"); } else { result.setDirection(allClear.getDirection()); @@ -425,8 +425,8 @@ protected ControllerResult validateInputVsl(WydotTimVsl tim) { // if direction is not i/d/b fail if (!tim.getDirection().equalsIgnoreCase("i") && - !tim.getDirection().equalsIgnoreCase("d") && - !tim.getDirection().equalsIgnoreCase("b")) { + !tim.getDirection().equalsIgnoreCase("d") && + !tim.getDirection().equalsIgnoreCase("b")) { resultMessages.add("direction not supported"); } if (tim.getRoute() == null) { @@ -478,8 +478,8 @@ protected ControllerResult validateInputCc(WydotTimRc tim) { // if direction is not i/d/b fail if (!tim.getDirection().equalsIgnoreCase("i") && - !tim.getDirection().equalsIgnoreCase("d") && - !tim.getDirection().equalsIgnoreCase("b")) { + !tim.getDirection().equalsIgnoreCase("d") && + !tim.getDirection().equalsIgnoreCase("b")) { resultMessages.add("direction not supported"); } if (tim.getStartPoint() == null || !tim.getStartPoint().isValid()) { @@ -569,8 +569,8 @@ protected ControllerResult validateInputBowr(WydotTimBowr tim) { toReturn.setDirection(tim.getDirection()); } if (tim.getDirection() != null && !tim.getDirection().equalsIgnoreCase("i") && - !tim.getDirection().equalsIgnoreCase("d") && - !tim.getDirection().equalsIgnoreCase("b")) { + !tim.getDirection().equalsIgnoreCase("d") && + !tim.getDirection().equalsIgnoreCase("b")) { resultMessages.add("direction not supported"); } @@ -649,13 +649,13 @@ public void processRequest(WydotTim wydotTim, TimType timType, String startDateT dTim.setDirection("D"); // I expireReduceCreateSendTims(iTim, timType, startDateTime, endDateTime, pk, content, - frameType); + frameType); // D expireReduceCreateSendTims(dTim, timType, startDateTime, endDateTime, pk, content, - frameType); + frameType); } else { expireReduceCreateSendTims(wydotTim, timType, startDateTime, endDateTime, pk, content, - frameType); + frameType); } } @@ -666,8 +666,8 @@ public TimType getTimType(String timTypeName) { } else { // get tim type timType = - getTimTypes().stream().filter(x -> x.getType().equals(timTypeName)).findFirst() - .orElse(null); + getTimTypes().stream().filter(x -> x.getType().equals(timTypeName)).findFirst() + .orElse(null); return timType; } @@ -688,8 +688,8 @@ protected void expireReduceCreateSendTims(WydotTim wydotTim, TimType timType, // Clear any existing TIMs with the same client id Long timTypeId = timType != null ? timType.getTimTypeId() : null; var existingTims = - activeTimService.getActiveTimsByClientIdDirection(wydotTim.getClientId(), timTypeId, - wydotTim.getDirection()); + activeTimService.getActiveTimsByClientIdDirection(wydotTim.getClientId(), timTypeId, + wydotTim.getDirection()); // Use wydotTimService to get all mileposts for the TIM List milepostsAll = wydotTimService.getAllMilepostsForTim(wydotTim); @@ -714,7 +714,7 @@ protected void expireReduceCreateSendTims(WydotTim wydotTim, TimType timType, try { Coordinate anchorCoordinate = utility.calculateAnchorCoordinate(firstPoint, secondPoint); anchor = new Milepost(null, firstPoint.getMilepost(), firstPoint.getDirection(), anchorCoordinate.getLatitude(), - anchorCoordinate.getLongitude()); + anchorCoordinate.getLongitude()); } catch (Utility.IdenticalPointsException e) { anchor = identicalPointsExceptionHandler.recover(milepostsAll); if (anchor == null) { @@ -724,10 +724,10 @@ protected void expireReduceCreateSendTims(WydotTim wydotTim, TimType timType, } var reducedMileposts = milepostReduction.applyMilepostReductionAlgorithm(milepostsAll, - configuration.getPathDistanceLimit()); + configuration.getPathDistanceLimit()); createSendTims(wydotTim, timType, startDateTime, endDateTime, pk, content, frameType, - milepostsAll, reducedMileposts, anchor); + milepostsAll, reducedMileposts, anchor); } // creates a TIM and sends it to RSUs and Satellite @@ -738,8 +738,8 @@ protected void createSendTims(WydotTim wydotTim, TimType timType, String startDa // create TIM WydotTravelerInputData timToSend = - wydotTimService.createTim(wydotTim, timType.getType(), startDateTime, endDateTime, - content, frameType, allMileposts, reducedMileposts, anchor, configuration.getDotGnisId()); + wydotTimService.createTim(wydotTim, timType.getType(), startDateTime, endDateTime, + content, frameType, allMileposts, reducedMileposts, anchor, configuration.getDotGnisId()); if (timToSend == null) { return; @@ -762,14 +762,14 @@ protected void createSendTims(WydotTim wydotTim, TimType timType, String startDa // remove rsus from TIM timToSend.getRequest().setRsus(null); wydotTimService.sendTimToSDW(wydotTim, timToSend, regionNamePrev, timType, pk, endPoint, - reducedMileposts); + reducedMileposts); } public List milepostToGeometry(List mileposts) { - var timGeometry = new ArrayList(); - for (Milepost milepost : mileposts) { - timGeometry.add(new Coordinate(milepost.getLatitude(), milepost.getLongitude())); - } - return timGeometry; - } + var timGeometry = new ArrayList(); + for (Milepost milepost : mileposts) { + timGeometry.add(new Coordinate(milepost.getLatitude(), milepost.getLongitude())); + } + return timGeometry; + } } \ No newline at end of file From 44553c372df5c94518af19ad6a3fe22353efb118 Mon Sep 17 00:00:00 2001 From: Paige Monington Date: Tue, 7 Oct 2025 09:01:00 -0600 Subject: [PATCH 130/168] chore: Require GNIS Packet ID to be set in environment variables --- .../java/com/trihydro/library/service/WydotTimService.java | 3 ++- .../com/trihydro/library/service/WydotTimServiceTest.java | 4 +--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java b/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java index d763995ca..40b8f0550 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java @@ -153,7 +153,8 @@ public WydotTravelerInputData createTim(WydotTim wydotTim, String timTypeStr, St Random rand = new Random(); StringBuffer sb = new StringBuffer(); if (dotGnisId.equals("000000")) { - log.warn("DOT GNIS ID is set to default value of 000000. This is not a valid GNIS ID and should be changed in the configuration."); + log.error("DOT GNIS ID is set to default value of 000000. This is not a valid GNIS ID and should be changed in the configuration."); + return null; } sb.append(dotGnisId); while (sb.length() < 18) { diff --git a/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java b/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java index 5db89bc13..f93cbc2b6 100644 --- a/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java +++ b/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java @@ -366,9 +366,7 @@ public void createTim_SetsRandomPacketIdUnsetGNISId() { WydotTravelerInputData result = uut.createTim(new WydotTim(), timTypeStr, startDateTime, endDateTime, content, frameType, allMileposts, reducedMileposts, anchor, dotGnisId); // Assert - assertNotNull(result.getTim().getPacketID()); - assertEquals(18, result.getTim().getPacketID().length()); - assertTrue(result.getTim().getPacketID().matches("[0-9A-F]+")); + assertNull(result.getTim()); } @Test From 3e2ba61daaca088abda33a89990d541851b7e875 Mon Sep 17 00:00:00 2001 From: Paige Monington Date: Tue, 7 Oct 2025 15:59:39 -0600 Subject: [PATCH 131/168] chore: Throw exception when GNIS ID not set --- .../trihydro/library/service/WydotTimService.java | 7 +++---- .../library/service/WydotTimServiceTest.java | 15 ++++++--------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java b/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java index 40b8f0550..dee5febe7 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java @@ -151,16 +151,15 @@ public WydotTravelerInputData createTim(WydotTim wydotTim, String timTypeStr, St // Set PacketId as an 18-character hex string: DOT GNIS ID + random hex suffix Random rand = new Random(); - StringBuffer sb = new StringBuffer(); + StringBuilder sb = new StringBuilder(); if (dotGnisId.equals("000000")) { - log.error("DOT GNIS ID is set to default value of 000000. This is not a valid GNIS ID and should be changed in the configuration."); - return null; + throw new IllegalStateException("DOT GNIS ID is set to default value of 000000. This is not a valid GNIS ID and should be changed in the configuration."); } sb.append(dotGnisId); while (sb.length() < 18) { sb.append(Integer.toHexString(rand.nextInt())); } - timToSend.getTim().setPacketID(sb.toString().substring(0, 18).toUpperCase()); + timToSend.getTim().setPacketID(sb.substring(0, 18).toUpperCase()); return timToSend; } diff --git a/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java b/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java index f93cbc2b6..ad4cb8f33 100644 --- a/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java +++ b/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java @@ -1,9 +1,7 @@ package com.trihydro.library.service; import static org.junit.Assert.assertNull; -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 static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyList; @@ -346,7 +344,7 @@ public void createTim_SetsRandomPacketIdWithGnisIdPrefix() { } @Test - public void createTim_SetsRandomPacketIdUnsetGNISId() { + public void createTim_ThrowsExceptionPacketIdUnsetGNISId() { // Arrange String timTypeStr = "A"; String startDateTime = "2023-01-01T00:00:00.000Z"; @@ -362,11 +360,10 @@ public void createTim_SetsRandomPacketIdUnsetGNISId() { when(mockCreateBaseTimUtil.buildTim(any(), any(), any(), any(), any(), any(), any())).thenReturn(timToSend); - // Act - WydotTravelerInputData result = uut.createTim(new WydotTim(), timTypeStr, startDateTime, endDateTime, content, frameType, allMileposts, reducedMileposts, anchor, dotGnisId); - - // Assert - assertNull(result.getTim()); + // Act & Assert + assertThrows(IllegalStateException.class, () -> { + uut.createTim(new WydotTim(), timTypeStr, startDateTime, endDateTime, content, frameType, allMileposts, reducedMileposts, anchor, dotGnisId); + }); } @Test From 3b3f84cde1581fc9cf065bb10fce6fb6983d64e4 Mon Sep 17 00:00:00 2001 From: Paige Monington Date: Wed, 15 Oct 2025 11:01:41 -0600 Subject: [PATCH 132/168] refactor: extract duplicate one way TIM generation logic into BufferTimFactory --- .../controller/BufferTimFactory.java | 76 +++++ .../WydotTimIncidentController.java | 88 +---- .../controller/WydotTimRwController.java | 74 +--- .../controller/WydotTimVslController.java | 315 +++++++----------- 4 files changed, 223 insertions(+), 330 deletions(-) create mode 100644 ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/BufferTimFactory.java diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/BufferTimFactory.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/BufferTimFactory.java new file mode 100644 index 000000000..faece818d --- /dev/null +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/BufferTimFactory.java @@ -0,0 +1,76 @@ +package com.trihydro.odewrapper.controller; + +import com.trihydro.library.model.Coordinate; +import com.trihydro.library.model.Milepost; +import com.trihydro.library.model.WydotTim; +import com.trihydro.library.service.MilepostService; +import com.trihydro.odewrapper.helpers.SetItisCodes; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public interface BufferTimFactory { + default List makeIncreasingTims(WydotTim wydotTim, List bufferTimITISCodes, MilepostService milepostService) { + return makeOneWayTims("I", wydotTim, bufferTimITISCodes, milepostService); + } + + default List milepostToGeometry(List mileposts) { + var timGeometry = new ArrayList(); + for (Milepost milepost : mileposts) { + timGeometry.add(new Coordinate(milepost.getLatitude(), milepost.getLongitude())); + } + return timGeometry; + } + + default List makeDecreasingTims(WydotTim wydotTim, List bufferTimITISCodes, MilepostService milepostService) { + return makeOneWayTims("d", wydotTim, bufferTimITISCodes, milepostService); + } + + private List makeOneWayTims(String direction, WydotTim wydotTim, List bufferTimITISCodes, MilepostService milepostService) { + var timOneWay = wydotTim.copy(); + timOneWay.setDirection(direction); + + var timsFromItisCodes = buildTimsFromItisCodes(timOneWay, bufferTimITISCodes, false); + var timsToSend = new ArrayList<>(timsFromItisCodes); + + var bufferTims = makeBufferTims(wydotTim, bufferTimITISCodes, milepostService); + timsToSend.addAll(bufferTims); + return timsToSend; + } + + default List makeBufferTims(WydotTim wydotTim, List bufferTimITISCodes, MilepostService milepostService) { + List bufferMps = milepostService.getBufferForPath(wydotTim.getRoute().replace('-', '_'), 1.0, wydotTim.toMileposts()); + wydotTim.setGeometry(milepostToGeometry(bufferMps)); + wydotTim.setClientId(wydotTim.getClientId() + "%BUFF"); + + return buildTimsFromItisCodes(wydotTim, bufferTimITISCodes,true); + } + + default List buildTimsFromItisCodes(WydotTim tim, List bufferTimITISCodes, boolean isBuffer) { + var timsToSend = new ArrayList(); + for (String itisCodeEntry : tim.getItisCodes()) { + // CTW Update requires that individual TIMs are created for each ITIS ordering + List itisCodes = Arrays.asList(itisCodeEntry.split(" ")); + + // only generate appropriate TIMs for geometry list (buffer, workZone) + String lastItisCode = itisCodes.get(itisCodes.size() - 1); + boolean isBufferTim = bufferTimITISCodes.contains(Integer.valueOf(lastItisCode)); + if (isBuffer && !isBufferTim) { + continue; + } else if (!isBuffer && isBufferTim) { + continue; + } + + WydotTim timToSend = tim.copy(); + timToSend.setItisCodes(itisCodes); + var itisCodeAbb = SetItisCodes.getItisCodeAbbreviation(itisCodeEntry); + String clientIdWithItis = tim.getClientId() + '-' + tim.getDirection() + '-' + itisCodeAbb; + timToSend.setClientId(clientIdWithItis); + timsToSend.add(timToSend); + } + + return timsToSend; + } + +} diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java index acb82a781..9c37f4140 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java @@ -1,47 +1,37 @@ package com.trihydro.odewrapper.controller; import com.trihydro.library.exceptionhandlers.IdenticalPointsExceptionHandler; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.*; - import com.trihydro.library.helpers.MilepostReduction; import com.trihydro.library.helpers.TimGenerationHelper; import com.trihydro.library.helpers.Utility; import com.trihydro.library.model.ActiveTim; import com.trihydro.library.model.ContentEnum; -import com.trihydro.library.model.Milepost; -import com.trihydro.library.service.ActiveTimService; -import com.trihydro.library.service.RestTemplateProvider; -import com.trihydro.library.service.TimTypeService; -import com.trihydro.library.service.WydotTimService; +import com.trihydro.library.service.*; import com.trihydro.odewrapper.config.BasicConfiguration; import com.trihydro.odewrapper.helpers.SetItisCodes; import com.trihydro.odewrapper.model.ControllerResult; import com.trihydro.odewrapper.model.TimIncidentList; import com.trihydro.odewrapper.model.WydotTimIncident; - +import io.swagger.annotations.Api; 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.CrossOrigin; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -import com.trihydro.library.service.MilepostService; - -import io.swagger.annotations.Api; +import org.springframework.web.bind.annotation.*; import us.dot.its.jpo.ode.plugin.j2735.timstorage.FrameType.TravelerInfoType; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.List; + @CrossOrigin @RestController @Api(description = "Incidents") @Slf4j -public class WydotTimIncidentController extends WydotTimBaseController { +public class WydotTimIncidentController extends WydotTimBaseController implements BufferTimFactory { private final String type = "I"; List timsToSend = new ArrayList<>(); @@ -74,10 +64,10 @@ public ResponseEntity createIncidentTim(@RequestBody TimIncidentList tim resultTim = validateInputIncident(wydotTim); if (wydotTim.getDirection().equalsIgnoreCase("i")) { - makeIncreasingTims(wydotTim); + makeIncreasingTims(wydotTim, bufferTimITISCodes, milepostService); } else { - makeDecreasingTims(wydotTim); + makeDecreasingTims(wydotTim, bufferTimITISCodes, milepostService); } resultTim.getResultMessages().add("success"); @@ -90,58 +80,6 @@ public ResponseEntity createIncidentTim(@RequestBody TimIncidentList tim return ResponseEntity.status(HttpStatus.OK).body(responseMessage); } - public void makeIncreasingTims(WydotTimIncident wydotTim) { - // i - add buffer for point TIMs - WydotTimIncident timOneWay = wydotTim.copy(); - timOneWay.setDirection("I"); - - addTimsToSend(timOneWay, false); - - makeBufferTims(timOneWay); - } - - public void makeDecreasingTims(WydotTimIncident wydotTim) { - // d - add buffer for point TIMs - WydotTimIncident timOneWay = wydotTim.copy(); - timOneWay.setDirection("D"); - - addTimsToSend(timOneWay, false); - - makeBufferTims(timOneWay); - } - - private void addTimsToSend(WydotTimIncident tim, boolean isBuffer) { - for (String itisCodeEntry : tim.getItisCodes()) { - // CTW Update requires that individual TIMs are created for each ITIS ordering - List itisCodes = Arrays.asList(itisCodeEntry.split(" ")); - - // only generate appropriate TIMs for geometry list (buffer, workZone) - String lastItisCode = itisCodes.get(itisCodes.size() - 1); - boolean isBufferTim = bufferTimITISCodes.contains(Integer.valueOf(lastItisCode)); - if (isBuffer && !isBufferTim) { - continue; - } else if (!isBuffer && isBufferTim) { - continue; - } - - WydotTimIncident timToSend = tim.copy(); - timToSend.setItisCodes(itisCodes); - var itisCodeAbb = SetItisCodes.getItisCodeAbbreviation(itisCodeEntry); - String clientIdWithItis = tim.getClientId() + '-' + tim.getDirection() + '-' + itisCodeAbb; - timToSend.setClientId(clientIdWithItis); - timsToSend.add(timToSend); - } - } - - public void makeBufferTims(WydotTimIncident wydotTim) { - // get mileposts for buffer - List bufferMps = milepostService.getBufferForPath(wydotTim.getRoute().replace('-', '_'), 1.0, wydotTim.toMileposts()); - wydotTim.setGeometry(milepostToGeometry(bufferMps)); - wydotTim.setClientId(wydotTim.getClientId() + "%BUFF"); - - addTimsToSend(wydotTim, true); - } - @RequestMapping(value = "/incident-tim", method = RequestMethod.PUT, headers = "Accept=application/json") public ResponseEntity updateIncidentTim(@RequestBody TimIncidentList timIncidentList) { diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java index bf8a10616..361886c31 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java @@ -44,7 +44,7 @@ @CrossOrigin @RestController @Api(description = "Road Construction") -public class WydotTimRwController extends WydotTimBaseController { +public class WydotTimRwController extends WydotTimBaseController implements BufferTimFactory { private final String type = "RW"; List timsToSend; @@ -86,19 +86,15 @@ public ResponseEntity createRoadContructionTim(@RequestBody TimRwList ti if (wydotTim.getBuffers() != null) wydotTim.getBuffers().sort(Comparator.comparingDouble(Buffer::getDistance)); - // if bi-directional + if (wydotTim.getDirection().equalsIgnoreCase("b")) { - // make i TIMs - makeIncreasingTims(wydotTim); - // make d TIMs - makeDecreasingTims(wydotTim); - } - // else make one direction TIMs - else if (wydotTim.getDirection().equalsIgnoreCase("i")) { - makeIncreasingTims(wydotTim); - } - else { - makeDecreasingTims(wydotTim); + // if bi-directional, make both increasing and decreasing TIMs + makeIncreasingTims(wydotTim, bufferTimITISCodes, milepostService); + makeDecreasingTims(wydotTim, bufferTimITISCodes, milepostService); + } else if (wydotTim.getDirection().equalsIgnoreCase("i")) { + makeIncreasingTims(wydotTim, bufferTimITISCodes, milepostService); + } else { + makeDecreasingTims(wydotTim, bufferTimITISCodes, milepostService); } // compile result messages for user @@ -112,26 +108,6 @@ else if (wydotTim.getDirection().equalsIgnoreCase("i")) { return ResponseEntity.status(HttpStatus.OK).body(responseMessage); } - public void makeIncreasingTims(WydotTimRw wydotTim) { - // i - add buffer for point TIMs - WydotTimRw timOneWay = copyTimWithStartDate(wydotTim); - timOneWay.setDirection("I"); - - addTimsToSend(timOneWay, false); - - makeBufferTims(timOneWay); - } - - public void makeDecreasingTims(WydotTimRw wydotTim) { - // d - add buffer for point TIMs - WydotTimRw timOneWay = copyTimWithStartDate(wydotTim); - timOneWay.setDirection("D"); - - addTimsToSend(timOneWay, false); - - makeBufferTims(timOneWay); - } - private WydotTimRw copyTimWithStartDate(WydotTimRw wydotTim) { WydotTimRw timOneWay = wydotTim.copy(); if (StringUtils.isBlank(timOneWay.getSchedStart())) { @@ -141,38 +117,6 @@ private WydotTimRw copyTimWithStartDate(WydotTimRw wydotTim) { return timOneWay; } - private void addTimsToSend(WydotTimRw tim, boolean isBuffer) { - for (String itisCodeEntry : tim.getItisCodes()) { - // CTW Update requires that individual TIMs are created for each ITIS ordering - List itisCodes = Arrays.asList(itisCodeEntry.split(" ")); - - // only generate appropriate TIMs for geometry list (buffer, workZone) - String lastItisCode = itisCodes.get(itisCodes.size() - 1); - boolean isBufferTim = bufferTimITISCodes.contains(Integer.valueOf(lastItisCode)); - if (isBuffer && !isBufferTim) { - continue; - } else if (!isBuffer && isBufferTim) { - continue; - } - - WydotTimRw timToSend = tim.copy(); - timToSend.setItisCodes(itisCodes); - var itisCodeAbb = SetItisCodes.getItisCodeAbbreviation(itisCodeEntry); - String clientIdWithItis = tim.getClientId() + '-' + tim.getDirection() + '-' + itisCodeAbb; - timToSend.setClientId(clientIdWithItis); - timsToSend.add(timToSend); - } - } - - public void makeBufferTims(WydotTimRw wydotTim) { - // get mileposts for buffer - List bufferMps = milepostService.getBufferForPath(wydotTim.getRoute().replace('-', '_'), 1.0, wydotTim.toMileposts()); - wydotTim.setGeometry(milepostToGeometry(bufferMps)); - wydotTim.setClientId(wydotTim.getClientId() + "%BUFF"); - - addTimsToSend(wydotTim, true); - } - public void processRequestAsync() { // An Async task always executes in new thread new Thread(() -> { diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimVslController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimVslController.java index 6ba9d2299..e1e37e92d 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimVslController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimVslController.java @@ -1,190 +1,125 @@ -package com.trihydro.odewrapper.controller; - -import com.trihydro.library.exceptionhandlers.IdenticalPointsExceptionHandler; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Date; -import java.util.List; - -import com.trihydro.library.helpers.MilepostReduction; -import com.trihydro.library.helpers.TimGenerationHelper; -import com.trihydro.library.helpers.Utility; -import com.trihydro.library.model.ActiveTim; -import com.trihydro.library.model.ContentEnum; -import com.trihydro.library.model.Milepost; -import com.trihydro.library.model.WydotTim; -import com.trihydro.library.service.ActiveTimService; -import com.trihydro.library.service.MilepostService; -import com.trihydro.library.service.RestTemplateProvider; -import com.trihydro.library.service.TimTypeService; -import com.trihydro.library.service.WydotTimService; -import com.trihydro.odewrapper.config.BasicConfiguration; -import com.trihydro.odewrapper.helpers.SetItisCodes; -import com.trihydro.odewrapper.model.ControllerResult; -import com.trihydro.odewrapper.model.TimVslList; -import com.trihydro.odewrapper.model.WydotTimVsl; - -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.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -import io.swagger.annotations.Api; -import us.dot.its.jpo.ode.plugin.j2735.timstorage.FrameType.TravelerInfoType; - -@CrossOrigin -@RestController -@Api(description = "Variable Speed Limits") -public class WydotTimVslController extends WydotTimBaseController { - - private final String type = "VSL"; - List timsToSend = new ArrayList<>(); - - @Autowired - public WydotTimVslController(BasicConfiguration _basicConfiguration, WydotTimService _wydotTimService, - TimTypeService _timTypeService, SetItisCodes _setItisCodes, ActiveTimService _activeTimService, - RestTemplateProvider _restTemplateProvider, MilepostReduction _milepostReduction, Utility _utility, - TimGenerationHelper _timGenerationHelper, MilepostService _milepostService, IdenticalPointsExceptionHandler identicalPointsExceptionHandler) { - super(_basicConfiguration, _wydotTimService, _timTypeService, _setItisCodes, _activeTimService, - _restTemplateProvider, _milepostReduction, _utility, _timGenerationHelper, _milepostService, identicalPointsExceptionHandler); - } - - @RequestMapping(value = "/vsl-tim", method = RequestMethod.POST, headers = "Accept=application/json") - public ResponseEntity createUpdateVslTim(@RequestBody TimVslList timVslList) { - - DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); - Date date = new Date(); - - utility.logWithDate(dateFormat.format(date) + " - Create/Update VSL TIM", this.getClass()); - String post = gson.toJson(timVslList); - utility.logWithDate(post, this.getClass()); - - List resultList = new ArrayList<>(); - ControllerResult resultTim; - - // build TIM - for (WydotTimVsl wydotTim : timVslList.getTimVslList()) { - resultTim = validateInputVsl(wydotTim); - - if (!resultTim.getResultMessages().isEmpty()) { - resultList.add(resultTim); - continue; - } - - if (wydotTim.getDirection().equalsIgnoreCase("i")) { - makeIncreasingTims(wydotTim); - } - else { - makeDecreasingTims(wydotTim); - } - - resultTim.getResultMessages().add("success"); - resultList.add(resultTim); - } - - processRequestAsync(timsToSend); - String responseMessage = gson.toJson(resultList); - return ResponseEntity.status(HttpStatus.OK).body(responseMessage); - } - - public void makeIncreasingTims(WydotTimVsl wydotTim) { - // i - add buffer for point TIMs - WydotTimVsl timOneWay = wydotTim.copy(); - timOneWay.setDirection("I"); - - addTimsToSend(timOneWay, false); - - makeBufferTims(timOneWay); - } - - public void makeDecreasingTims(WydotTimVsl wydotTim) { - // d - add buffer for point TIMs - WydotTimVsl timOneWay = wydotTim.copy(); - timOneWay.setDirection("D"); - - addTimsToSend(timOneWay, false); - - makeBufferTims(timOneWay); - } - - private void addTimsToSend(WydotTimVsl tim, boolean isBuffer) { - for (String itisCodeEntry : tim.getItisCodes()) { - // CTW Update requires that individual TIMs are created for each ITIS ordering - List itisCodes = Arrays.asList(itisCodeEntry.split(" ")); - - // only generate appropriate TIMs for geometry list (buffer, workZone) - String lastItisCode = itisCodes.get(itisCodes.size() - 1); - boolean isBufferTim = bufferTimITISCodes.contains(Integer.valueOf(lastItisCode)); - if (isBuffer && !isBufferTim) { - continue; - } else if (!isBuffer && isBufferTim) { - continue; - } - - WydotTimVsl timToSend = tim.copy(); - timToSend.setItisCodes(itisCodes); - var itisCodeAbb = SetItisCodes.getItisCodeAbbreviation(itisCodeEntry); - String clientIdWithItis = tim.getClientId() + '-' + tim.getDirection() + '-' + itisCodeAbb; - timToSend.setClientId(clientIdWithItis); - timsToSend.add(timToSend); - } - } - - public void makeBufferTims(WydotTimVsl wydotTim) { - // get mileposts for buffer - List bufferMps = milepostService.getBufferForPath(wydotTim.getRoute().replace('-', '_'), 1.0, wydotTim.toMileposts()); - wydotTim.setGeometry(milepostToGeometry(bufferMps)); - wydotTim.setClientId(wydotTim.getClientId() + "%BUFF"); - - addTimsToSend(wydotTim, true); - } - - public void processRequestAsync(List wydotTims) { - // An Async task always executes in new thread - new Thread(() -> { - var startTime = getStartTime(); - for (WydotTim tim : wydotTims) { - processRequest(tim, getTimType(type), startTime, null, null, ContentEnum.speedLimit, - TravelerInfoType.roadSignage); - } - }).start(); - } - - @RequestMapping(value = "/vsl-tim/{vslTimId}", method = RequestMethod.DELETE, headers = "Accept=application/json") - public ResponseEntity deleteVslTim(@PathVariable String vslTimId) { - - DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); - Date date = new Date(); - - utility.logWithDate(dateFormat.format(date) + " - Delete VSL TIM", this.getClass()); - - // expire and clear TIM - wydotTimService.clearTimsById("VSL", vslTimId, null, true); - - String responseMessage = "success"; - return ResponseEntity.status(HttpStatus.OK).body(responseMessage); - } - - @RequestMapping(value = "/vsl-tim", method = RequestMethod.GET, headers = "Accept=application/json") - public Collection getVslTims() { - - // get active TIMs - List activeTims = wydotTimService.selectTimsByType(type); - - // add ITIS codes to TIMs - for (ActiveTim activeTim : activeTims) { - activeTimService.addItisCodesToActiveTim(activeTim); - } - - return activeTims; - } - -} +package com.trihydro.odewrapper.controller; + +import com.trihydro.library.exceptionhandlers.IdenticalPointsExceptionHandler; +import com.trihydro.library.helpers.MilepostReduction; +import com.trihydro.library.helpers.TimGenerationHelper; +import com.trihydro.library.helpers.Utility; +import com.trihydro.library.model.ActiveTim; +import com.trihydro.library.model.ContentEnum; +import com.trihydro.library.model.WydotTim; +import com.trihydro.library.service.*; +import com.trihydro.odewrapper.config.BasicConfiguration; +import com.trihydro.odewrapper.helpers.SetItisCodes; +import com.trihydro.odewrapper.model.ControllerResult; +import com.trihydro.odewrapper.model.TimVslList; +import com.trihydro.odewrapper.model.WydotTimVsl; +import io.swagger.annotations.Api; +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.plugin.j2735.timstorage.FrameType.TravelerInfoType; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.List; + +@CrossOrigin +@RestController +@Api(description = "Variable Speed Limits") +public class WydotTimVslController extends WydotTimBaseController implements BufferTimFactory { + + private final String type = "VSL"; + List timsToSend = new ArrayList<>(); + + @Autowired + public WydotTimVslController(BasicConfiguration _basicConfiguration, WydotTimService _wydotTimService, + TimTypeService _timTypeService, SetItisCodes _setItisCodes, ActiveTimService _activeTimService, + RestTemplateProvider _restTemplateProvider, MilepostReduction _milepostReduction, Utility _utility, + TimGenerationHelper _timGenerationHelper, MilepostService _milepostService, IdenticalPointsExceptionHandler identicalPointsExceptionHandler) { + super(_basicConfiguration, _wydotTimService, _timTypeService, _setItisCodes, _activeTimService, + _restTemplateProvider, _milepostReduction, _utility, _timGenerationHelper, _milepostService, identicalPointsExceptionHandler); + } + + @RequestMapping(value = "/vsl-tim", method = RequestMethod.POST, headers = "Accept=application/json") + public ResponseEntity createUpdateVslTim(@RequestBody TimVslList timVslList) { + + DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); + Date date = new Date(); + + utility.logWithDate(dateFormat.format(date) + " - Create/Update VSL TIM", this.getClass()); + String post = gson.toJson(timVslList); + utility.logWithDate(post, this.getClass()); + + List resultList = new ArrayList<>(); + ControllerResult resultTim; + + // build TIM + for (WydotTimVsl wydotTim : timVslList.getTimVslList()) { + resultTim = validateInputVsl(wydotTim); + + if (!resultTim.getResultMessages().isEmpty()) { + resultList.add(resultTim); + continue; + } + + if (wydotTim.getDirection().equalsIgnoreCase("i")) { + makeIncreasingTims(wydotTim, bufferTimITISCodes, milepostService); + } + else { + makeDecreasingTims(wydotTim, bufferTimITISCodes, milepostService); + } + + resultTim.getResultMessages().add("success"); + resultList.add(resultTim); + } + + processRequestAsync(timsToSend); + String responseMessage = gson.toJson(resultList); + return ResponseEntity.status(HttpStatus.OK).body(responseMessage); + } + + public void processRequestAsync(List wydotTims) { + // An Async task always executes in new thread + new Thread(() -> { + var startTime = getStartTime(); + for (WydotTim tim : wydotTims) { + processRequest(tim, getTimType(type), startTime, null, null, ContentEnum.speedLimit, + TravelerInfoType.roadSignage); + } + }).start(); + } + + @RequestMapping(value = "/vsl-tim/{vslTimId}", method = RequestMethod.DELETE, headers = "Accept=application/json") + public ResponseEntity deleteVslTim(@PathVariable String vslTimId) { + + DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); + Date date = new Date(); + + utility.logWithDate(dateFormat.format(date) + " - Delete VSL TIM", this.getClass()); + + // expire and clear TIM + wydotTimService.clearTimsById("VSL", vslTimId, null, true); + + String responseMessage = "success"; + return ResponseEntity.status(HttpStatus.OK).body(responseMessage); + } + + @RequestMapping(value = "/vsl-tim", method = RequestMethod.GET, headers = "Accept=application/json") + public Collection getVslTims() { + + // get active TIMs + List activeTims = wydotTimService.selectTimsByType(type); + + // add ITIS codes to TIMs + for (ActiveTim activeTim : activeTims) { + activeTimService.addItisCodesToActiveTim(activeTim); + } + + return activeTims; + } + +} From e880748263212e0191224c0116dcdec8b2436130 Mon Sep 17 00:00:00 2001 From: Paige Monington Date: Wed, 15 Oct 2025 11:17:40 -0600 Subject: [PATCH 133/168] fix: add return values to timstosend --- .../WydotTimIncidentController.java | 16 ++++++---- .../controller/WydotTimRwController.java | 32 ++++++++----------- .../controller/WydotTimVslController.java | 4 +-- 3 files changed, 25 insertions(+), 27 deletions(-) diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java index 9c37f4140..af5856927 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java @@ -6,6 +6,7 @@ import com.trihydro.library.helpers.Utility; import com.trihydro.library.model.ActiveTim; import com.trihydro.library.model.ContentEnum; +import com.trihydro.library.model.WydotTim; import com.trihydro.library.service.*; import com.trihydro.odewrapper.config.BasicConfiguration; import com.trihydro.odewrapper.helpers.SetItisCodes; @@ -34,7 +35,7 @@ public class WydotTimIncidentController extends WydotTimBaseController implements BufferTimFactory { private final String type = "I"; - List timsToSend = new ArrayList<>(); + List timsToSend = new ArrayList<>(); @Autowired public WydotTimIncidentController(BasicConfiguration _basicConfiguration, WydotTimService _wydotTimService, @@ -64,10 +65,10 @@ public ResponseEntity createIncidentTim(@RequestBody TimIncidentList tim resultTim = validateInputIncident(wydotTim); if (wydotTim.getDirection().equalsIgnoreCase("i")) { - makeIncreasingTims(wydotTim, bufferTimITISCodes, milepostService); + timsToSend.addAll(makeIncreasingTims(wydotTim, bufferTimITISCodes, milepostService)); } else { - makeDecreasingTims(wydotTim, bufferTimITISCodes, milepostService); + timsToSend.addAll(makeDecreasingTims(wydotTim, bufferTimITISCodes, milepostService)); } resultTim.getResultMessages().add("success"); @@ -118,14 +119,15 @@ public ResponseEntity updateIncidentTim(@RequestBody TimIncidentList tim return ResponseEntity.status(HttpStatus.OK).body(responseMessage); } - public void makeTimsAsync(List wydotTims) { + public void makeTimsAsync(List wydotTims) { new Thread(() -> { var startTime = getStartTime(); - for (WydotTimIncident wydotTim : wydotTims) { + for (var wydotTim : wydotTims) { + var wydotTimIncident = (WydotTimIncident)wydotTim; // set route - wydotTim.setRoute(wydotTim.getRoute()); - processRequest(wydotTim, getTimType(type), startTime, null, wydotTim.getPk(), ContentEnum.advisory, + wydotTim.setRoute(wydotTimIncident.getRoute()); + processRequest(wydotTimIncident, getTimType(type), startTime, null, wydotTimIncident.getPk(), ContentEnum.advisory, TravelerInfoType.advisory); } }).start(); diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java index 361886c31..e56eaf6ea 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java @@ -11,12 +11,7 @@ import com.trihydro.library.helpers.MilepostReduction; import com.trihydro.library.helpers.TimGenerationHelper; import com.trihydro.library.helpers.Utility; -import com.trihydro.library.model.ActiveTim; -import com.trihydro.library.model.Buffer; -import com.trihydro.library.model.ContentEnum; -import com.trihydro.library.model.Milepost; -import com.trihydro.library.model.TimRwList; -import com.trihydro.library.model.WydotTimRw; +import com.trihydro.library.model.*; import com.trihydro.library.service.ActiveTimService; import com.trihydro.library.service.RestTemplateProvider; import com.trihydro.library.service.TimTypeService; @@ -47,7 +42,7 @@ public class WydotTimRwController extends WydotTimBaseController implements BufferTimFactory { private final String type = "RW"; - List timsToSend; + List timsToSend; @Autowired public WydotTimRwController(BasicConfiguration _basicConfiguration, WydotTimService _wydotTimService, @@ -89,12 +84,12 @@ public ResponseEntity createRoadContructionTim(@RequestBody TimRwList ti if (wydotTim.getDirection().equalsIgnoreCase("b")) { // if bi-directional, make both increasing and decreasing TIMs - makeIncreasingTims(wydotTim, bufferTimITISCodes, milepostService); - makeDecreasingTims(wydotTim, bufferTimITISCodes, milepostService); + timsToSend.addAll(makeIncreasingTims(wydotTim, bufferTimITISCodes, milepostService)); + timsToSend.addAll(makeDecreasingTims(wydotTim, bufferTimITISCodes, milepostService)); } else if (wydotTim.getDirection().equalsIgnoreCase("i")) { - makeIncreasingTims(wydotTim, bufferTimITISCodes, milepostService); + timsToSend.addAll(makeIncreasingTims(wydotTim, bufferTimITISCodes, milepostService)); } else { - makeDecreasingTims(wydotTim, bufferTimITISCodes, milepostService); + timsToSend.addAll(makeDecreasingTims(wydotTim, bufferTimITISCodes, milepostService)); } // compile result messages for user @@ -120,19 +115,20 @@ private WydotTimRw copyTimWithStartDate(WydotTimRw wydotTim) { public void processRequestAsync() { // An Async task always executes in new thread new Thread(() -> { - for (WydotTimRw tim : timsToSend) { + for (var tim : timsToSend) { + WydotTimRw timRw = (WydotTimRw) tim; // check for reduce speed, itis code 7443 - if (tim.getItisCodes() != null && tim.getItisCodes().size() == 3 - && tim.getItisCodes().get(0).equals("7443")) { - processRequest(tim, getTimType(type), tim.getSchedStart(), tim.getSchedEnd(), null, + if (timRw.getItisCodes() != null && timRw.getItisCodes().size() == 3 + && timRw.getItisCodes().get(0).equals("7443")) { + processRequest(timRw, getTimType(type), timRw.getSchedStart(), timRw.getSchedEnd(), null, ContentEnum.speedLimit, TravelerInfoType.advisory); - } else if (tim.getItisCodes() != null && tim.getItisCodes().get(0).equals("7186")) { + } else if (timRw.getItisCodes() != null && timRw.getItisCodes().get(0).equals("7186")) { // prepare to stop - processRequest(tim, getTimType(type), tim.getSchedStart(), tim.getSchedEnd(), null, + processRequest(timRw, getTimType(type), timRw.getSchedStart(), timRw.getSchedEnd(), null, ContentEnum.advisory, TravelerInfoType.advisory); } else { // the rest are content=workZone - processRequest(tim, getTimType(type), tim.getSchedStart(), tim.getSchedEnd(), null, + processRequest(timRw, getTimType(type), timRw.getSchedStart(), timRw.getSchedEnd(), null, ContentEnum.workZone, TravelerInfoType.advisory); } } diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimVslController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimVslController.java index e1e37e92d..6e461c960 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimVslController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimVslController.java @@ -67,10 +67,10 @@ public ResponseEntity createUpdateVslTim(@RequestBody TimVslList timVslL } if (wydotTim.getDirection().equalsIgnoreCase("i")) { - makeIncreasingTims(wydotTim, bufferTimITISCodes, milepostService); + timsToSend.addAll(makeIncreasingTims(wydotTim, bufferTimITISCodes, milepostService)); } else { - makeDecreasingTims(wydotTim, bufferTimITISCodes, milepostService); + timsToSend.addAll(makeDecreasingTims(wydotTim, bufferTimITISCodes, milepostService)); } resultTim.getResultMessages().add("success"); From 267d846b3850fdf7648aca0668532c7671c44ae5 Mon Sep 17 00:00:00 2001 From: Paige Monington Date: Thu, 16 Oct 2025 08:18:24 -0600 Subject: [PATCH 134/168] test: add unit tests for buffer tim logic refactor --- .../controller/BufferTimFactoryTest.java | 213 ++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 ode-wrapper/src/test/java/com/trihydro/odewrapper/controller/BufferTimFactoryTest.java diff --git a/ode-wrapper/src/test/java/com/trihydro/odewrapper/controller/BufferTimFactoryTest.java b/ode-wrapper/src/test/java/com/trihydro/odewrapper/controller/BufferTimFactoryTest.java new file mode 100644 index 000000000..9ab46125d --- /dev/null +++ b/ode-wrapper/src/test/java/com/trihydro/odewrapper/controller/BufferTimFactoryTest.java @@ -0,0 +1,213 @@ +package com.trihydro.odewrapper.controller; + +import com.trihydro.library.model.Coordinate; +import com.trihydro.library.model.ItisCode; +import com.trihydro.library.model.Milepost; +import com.trihydro.library.model.WydotTim; +import com.trihydro.library.service.MilepostService; +import com.trihydro.odewrapper.helpers.SetItisCodes; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +public class BufferTimFactoryTest implements BufferTimFactory { + @Mock + private MilepostService milepostService; + @Mock + private SetItisCodes setItisCodes; + private WydotTim wydotTim; + + @BeforeEach + void setUp() { + milepostService = mock(MilepostService.class); + + wydotTim = new WydotTim(); + wydotTim.setStartPoint(new Coordinate()); + wydotTim.setEndPoint(new Coordinate(BigDecimal.valueOf(1), BigDecimal.valueOf(2))); + var wydotTimItisCodes = new ArrayList(); + wydotTimItisCodes.add("1309"); + wydotTim.setItisCodes(wydotTimItisCodes); + wydotTim.setClientId("testclientid"); + wydotTim.setRoute("I-80"); + wydotTim.setDirection("I"); + + List itisCodes = new ArrayList<>(); + ItisCode ic = new ItisCode(); + ic.setCategoryId(-1); + ic.setDescription("description"); + ic.setItisCode(-2); + ic.setItisCodeId(-3); + itisCodes.add(ic); + + lenient().doReturn(wydotTimItisCodes).when(setItisCodes).setItisCodes(any()); + lenient().doReturn(itisCodes).when(setItisCodes).getItisCodes(); + } + + private List getMileposts() { + List mileposts = new ArrayList<>();; + + var mp = new Milepost(); + mp = new Milepost(); + mp.setLatitude(BigDecimal.valueOf(200)); + mp.setLongitude(BigDecimal.valueOf(300)); + mileposts.add(mp); + + + mp = new Milepost(); + mp.setLatitude(BigDecimal.valueOf(300)); + mp.setLongitude(BigDecimal.valueOf(300)); + mileposts.add(mp); + + mp = new Milepost(); + mp.setLatitude(BigDecimal.valueOf(400)); + mp.setLongitude(BigDecimal.valueOf(400)); + mileposts.add(mp); + + mp = new Milepost(); + mp.setLatitude(BigDecimal.valueOf(500)); + mp.setLongitude(BigDecimal.valueOf(500)); + mileposts.add(mp); + return mileposts; + } + + @Test + void testMilepostToGeometry() { + // Arrange + List mileposts = getMileposts(); + + // Act + List geometry = milepostToGeometry(mileposts); + + // Assert + assertEquals(4, geometry.size()); + assertEquals(BigDecimal.valueOf(200), geometry.get(0).getLatitude()); + assertEquals(BigDecimal.valueOf(300), geometry.get(0).getLongitude()); + } + + @Test + void testBuildTimsFromItisCodes_withNonBufferCode() { + // Arrange + List bufferCodes = List.of(7364); + + // Act + List tims = buildTimsFromItisCodes(wydotTim, bufferCodes, false); + + // Assert + assertEquals(1, tims.size()); + assertEquals("testclientid-I-1309", tims.get(0).getClientId()); + } + + @Test + void testBuildTimsFromItisCodes_withBufferCode() { + // Arrange + var wydotTimItisCodes = new ArrayList(); + wydotTimItisCodes.add("1309 7364"); + wydotTim.setItisCodes(wydotTimItisCodes); + List bufferCodes = List.of(7364); + + // Act + List tims = buildTimsFromItisCodes(wydotTim, bufferCodes, true); + + // Assert + assertEquals(1, tims.size()); + assertEquals("testclientid-I-1309-7364", tims.get(0).getClientId()); + } + + + @Test + void testBuildTimsFromItisCodes_excludesBufferCodeWhenNotisBufferAndBufferTim() { + // Arrange + var wydotTimItisCodes = new ArrayList(); + wydotTimItisCodes.add("1309 7364"); + wydotTim.setItisCodes(wydotTimItisCodes); + List bufferCodes = List.of(7364); // different from last code 7342 + + // Act + List tims = buildTimsFromItisCodes(wydotTim, bufferCodes, false); + + // Assert + assertTrue(tims.isEmpty()); + } + + @Test + void testBuildTimsFromItisCodes_excludesBufferCodeWhenisBufferAndNotBufferTim() { + // Arrange + List bufferCodes = List.of(7364); // different from last code 7342 + + // Act + List tims = buildTimsFromItisCodes(wydotTim, bufferCodes, true); + + // Assert + assertTrue(tims.isEmpty()); + } + + @Test + void testMakeIncreasingTims_callsMakeOneWayWithI() { + // Arrange + List bufferCodes = List.of(7364); // unrelated + + // Act + List result = makeIncreasingTims(wydotTim, bufferCodes, milepostService); + + // Assert + for (WydotTim tim : result) { + assertEquals("I", tim.getDirection()); + } + } + + @Test + void testMakeDecreasingTims_callsMakeOneWayWithD() { + // Arrange + when(milepostService.getBufferForPath(any(), eq(1.0), any())) + .thenReturn(getMileposts()); + List bufferCodes = List.of(7364); // unrelated + + // Act + List result = makeDecreasingTims(wydotTim, bufferCodes, milepostService); + + // Assert + for (WydotTim tim : result) { + assertEquals("d", tim.getDirection()); + } + } + + @Test + void testMakeBufferTims_createsBufferTimsWithUpdatedClientIdAndGeometry() { + // Arrange + when(milepostService.getBufferForPath(any(), eq(1.0), any())) + .thenReturn(getMileposts()); + // Set a buffer ITIS code that matches the end of an ITIS entry + List bufferCodes = List.of(7364); + wydotTim.setItisCodes(List.of("1309 7364")); // Ends in 7364 -> matches buffer code + + // Act + List result = makeBufferTims(wydotTim, bufferCodes, milepostService); + + // Assert + assertEquals(1, result.size()); + WydotTim tim = result.get(0); + + // Assert that clientId has been updated with "%BUFF" + assertTrue(tim.getClientId().contains("%BUFF")); + + // Assert geometry was set correctly + assertNotNull(wydotTim.getGeometry()); + assertEquals(4, wydotTim.getGeometry().size()); + assertEquals(BigDecimal.valueOf(200), wydotTim.getGeometry().get(0).getLatitude()); + assertEquals(BigDecimal.valueOf(300), wydotTim.getGeometry().get(0).getLongitude()); + + // Assert direction and ITIS code structure + assertEquals("I", tim.getDirection()); + assertEquals(List.of("1309", "7364"), tim.getItisCodes()); + } +} From 5b92eecfa17471df9c78d7629a4f77579eb7cef7 Mon Sep 17 00:00:00 2001 From: Paige Monington Date: Thu, 16 Oct 2025 08:22:49 -0600 Subject: [PATCH 135/168] refactor: move BufferTimFactory to factory package --- .../odewrapper/controller/WydotTimIncidentController.java | 1 + .../trihydro/odewrapper/controller/WydotTimRwController.java | 4 ++-- .../trihydro/odewrapper/controller/WydotTimVslController.java | 1 + .../odewrapper/{controller => factory}/BufferTimFactory.java | 2 +- .../{controller => factory}/BufferTimFactoryTest.java | 4 ++-- 5 files changed, 7 insertions(+), 5 deletions(-) rename ode-wrapper/src/main/java/com/trihydro/odewrapper/{controller => factory}/BufferTimFactory.java (98%) rename ode-wrapper/src/test/java/com/trihydro/odewrapper/{controller => factory}/BufferTimFactoryTest.java (98%) diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java index af5856927..019a6e018 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java @@ -9,6 +9,7 @@ import com.trihydro.library.model.WydotTim; import com.trihydro.library.service.*; import com.trihydro.odewrapper.config.BasicConfiguration; +import com.trihydro.odewrapper.factory.BufferTimFactory; import com.trihydro.odewrapper.helpers.SetItisCodes; import com.trihydro.odewrapper.model.ControllerResult; import com.trihydro.odewrapper.model.TimIncidentList; diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java index e56eaf6ea..2cf126edc 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java @@ -1,9 +1,8 @@ package com.trihydro.odewrapper.controller; import com.trihydro.library.exceptionhandlers.IdenticalPointsExceptionHandler; -import java.math.BigDecimal; + import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.Comparator; import java.util.List; @@ -17,6 +16,7 @@ import com.trihydro.library.service.TimTypeService; import com.trihydro.library.service.WydotTimService; import com.trihydro.odewrapper.config.BasicConfiguration; +import com.trihydro.odewrapper.factory.BufferTimFactory; import com.trihydro.odewrapper.helpers.SetItisCodes; import com.trihydro.odewrapper.model.ControllerResult; diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimVslController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimVslController.java index 6e461c960..a7adef336 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimVslController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimVslController.java @@ -9,6 +9,7 @@ import com.trihydro.library.model.WydotTim; import com.trihydro.library.service.*; import com.trihydro.odewrapper.config.BasicConfiguration; +import com.trihydro.odewrapper.factory.BufferTimFactory; import com.trihydro.odewrapper.helpers.SetItisCodes; import com.trihydro.odewrapper.model.ControllerResult; import com.trihydro.odewrapper.model.TimVslList; diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/BufferTimFactory.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/factory/BufferTimFactory.java similarity index 98% rename from ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/BufferTimFactory.java rename to ode-wrapper/src/main/java/com/trihydro/odewrapper/factory/BufferTimFactory.java index faece818d..06af97ea7 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/BufferTimFactory.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/factory/BufferTimFactory.java @@ -1,4 +1,4 @@ -package com.trihydro.odewrapper.controller; +package com.trihydro.odewrapper.factory; import com.trihydro.library.model.Coordinate; import com.trihydro.library.model.Milepost; diff --git a/ode-wrapper/src/test/java/com/trihydro/odewrapper/controller/BufferTimFactoryTest.java b/ode-wrapper/src/test/java/com/trihydro/odewrapper/factory/BufferTimFactoryTest.java similarity index 98% rename from ode-wrapper/src/test/java/com/trihydro/odewrapper/controller/BufferTimFactoryTest.java rename to ode-wrapper/src/test/java/com/trihydro/odewrapper/factory/BufferTimFactoryTest.java index 9ab46125d..2dbd81a09 100644 --- a/ode-wrapper/src/test/java/com/trihydro/odewrapper/controller/BufferTimFactoryTest.java +++ b/ode-wrapper/src/test/java/com/trihydro/odewrapper/factory/BufferTimFactoryTest.java @@ -1,4 +1,4 @@ -package com.trihydro.odewrapper.controller; +package com.trihydro.odewrapper.factory; import com.trihydro.library.model.Coordinate; import com.trihydro.library.model.ItisCode; @@ -54,7 +54,7 @@ void setUp() { } private List getMileposts() { - List mileposts = new ArrayList<>();; + List mileposts = new ArrayList<>(); var mp = new Milepost(); mp = new Milepost(); From a0ff8895193d9f56ad20988cc66924b00e912c91 Mon Sep 17 00:00:00 2001 From: Paige Monington Date: Thu, 16 Oct 2025 10:36:47 -0600 Subject: [PATCH 136/168] fix: adjust broken unit tests and address no supported route exception for buffered TIMs --- .../com/trihydro/library/model/WydotTim.java | 20 +++++---- .../controller/WydotTimBaseController.java | 16 ++----- .../odewrapper/factory/BufferTimFactory.java | 9 ++-- .../WydotTimIncidentControllerTest.java | 44 +++++++++++++++++-- .../odewrapper/WydotTimRwControllerTest.java | 11 +++-- .../odewrapper/WydotTimVslControllerTest.java | 19 ++++++-- .../odewrapper/helpers/SetItisCodesTest.java | 5 +-- 7 files changed, 85 insertions(+), 39 deletions(-) diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/model/WydotTim.java b/cv-data-service-library/src/main/java/com/trihydro/library/model/WydotTim.java index c2fe2d55f..7ace51f05 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/model/WydotTim.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/model/WydotTim.java @@ -127,7 +127,7 @@ public void setBearing(Integer bearing) { } public boolean isGeometryValid() { - if (this.geometry != null && this.geometry.size() > 0) { + if (this.geometry != null && !this.geometry.isEmpty()) { for (Coordinate coord : this.geometry) { if (!coord.isValid()) { return false; @@ -141,14 +141,16 @@ public boolean isGeometryValid() { public List toMileposts() { var mileposts = new ArrayList(); - for (Coordinate coordinate : this.getGeometry()) { - Milepost milepost = new Milepost(); - milepost.setLatitude(coordinate.getLatitude()); - milepost.setLongitude(coordinate.getLongitude()); - milepost.setDirection(this.getDirection()); - milepost.setCommonName(this.getRoute()); - milepost.setMilepost(0.0); - mileposts.add(milepost); + if (this.getGeometry() != null && this.getGeometry().size() > 1) { + for (Coordinate coordinate : this.getGeometry()) { + Milepost milepost = new Milepost(); + milepost.setLatitude(coordinate.getLatitude()); + milepost.setLongitude(coordinate.getLongitude()); + milepost.setDirection(this.getDirection()); + milepost.setCommonName(this.getRoute()); + milepost.setMilepost(0.0); + mileposts.add(milepost); + } } return mileposts; } diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java index 1b31818b3..9e24d4130 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java @@ -1,7 +1,6 @@ package com.trihydro.odewrapper.controller; import com.trihydro.library.exceptionhandlers.IdenticalPointsExceptionHandler; -import com.trihydro.library.model.TimUpdateModel; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.LocalDate; @@ -19,7 +18,6 @@ import java.util.TimeZone; import com.google.gson.Gson; -import com.trihydro.library.exceptionhandlers.IdenticalPointsExceptionHandler; import com.trihydro.library.helpers.MilepostReduction; import com.trihydro.library.helpers.TimGenerationHelper; import com.trihydro.library.helpers.Utility; @@ -176,8 +174,8 @@ public ControllerResult validateInputIncident(WydotTimIncident tim) { if (tim.getHighway() == null || !routeSupported(tim.getHighway())) { resultMessages.add("route not supported"); } else { - tim.setRoute(tim.getRoute()); - result.setRoute(tim.getRoute()); + tim.setRoute(tim.getHighway()); + result.setRoute(tim.getHighway()); } // if direction is not i/d/b fail @@ -230,7 +228,7 @@ protected ControllerResult validateInputRw(WydotTimRw tim) { resultMessages.add("direction not supported"); } - // if geometry isn't present check for start/end points + // if geometry isn't present, check for start/end points if (!tim.isGeometryValid()) { if (tim.getStartPoint() == null || !tim.getStartPoint().isValid()) { resultMessages.add("Invalid startPoint"); @@ -765,11 +763,5 @@ protected void createSendTims(WydotTim wydotTim, TimType timType, String startDa reducedMileposts); } - public List milepostToGeometry(List mileposts) { - var timGeometry = new ArrayList(); - for (Milepost milepost : mileposts) { - timGeometry.add(new Coordinate(milepost.getLatitude(), milepost.getLongitude())); - } - return timGeometry; - } + } \ No newline at end of file diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/factory/BufferTimFactory.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/factory/BufferTimFactory.java index 06af97ea7..e974dd04e 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/factory/BufferTimFactory.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/factory/BufferTimFactory.java @@ -40,9 +40,12 @@ private List makeOneWayTims(String direction, WydotTim wydotTim, List< } default List makeBufferTims(WydotTim wydotTim, List bufferTimITISCodes, MilepostService milepostService) { - List bufferMps = milepostService.getBufferForPath(wydotTim.getRoute().replace('-', '_'), 1.0, wydotTim.toMileposts()); - wydotTim.setGeometry(milepostToGeometry(bufferMps)); - wydotTim.setClientId(wydotTim.getClientId() + "%BUFF"); + if(wydotTim.getRoute() != null) { + // If the route of the TIM is supported, create buffer based on mileposts associated with that route + List bufferMps = milepostService.getBufferForPath(wydotTim.getRoute().replace('-', '_'), 1.0, wydotTim.toMileposts()); + wydotTim.setGeometry(milepostToGeometry(bufferMps)); + wydotTim.setClientId(wydotTim.getClientId() + "%BUFF"); + } return buildTimsFromItisCodes(wydotTim, bufferTimITISCodes,true); } diff --git a/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimIncidentControllerTest.java b/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimIncidentControllerTest.java index 4b424c0f3..274590f76 100644 --- a/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimIncidentControllerTest.java +++ b/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimIncidentControllerTest.java @@ -2,9 +2,9 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.isA; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.lenient; +import static org.mockito.Mockito.*; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -13,6 +13,8 @@ import com.trihydro.library.helpers.Utility; import com.trihydro.library.model.ActiveTim; import com.trihydro.library.model.ItisCode; +import com.trihydro.library.model.Milepost; +import com.trihydro.library.service.MilepostService; import com.trihydro.library.service.TimTypeService; import com.trihydro.library.service.WydotTimService; import com.trihydro.odewrapper.config.BasicConfiguration; @@ -45,6 +47,8 @@ public class WydotTimIncidentControllerTest { SetItisCodes setItisCodes; @Mock Utility utility; + @Mock + MilepostService milepostService; @InjectMocks @Spy @@ -54,6 +58,8 @@ public class WydotTimIncidentControllerTest { @BeforeEach public void setup() throws Exception { + milepostService = mock(MilepostService.class); + List itisCodes = new ArrayList<>(); ItisCode ic = new ItisCode(); ic.setCategoryId(-1); @@ -70,6 +76,33 @@ public void setup() throws Exception { lenient().doReturn(true).when(uut).routeSupported(isA(String.class)); } + private List getMileposts() { + List mileposts = new ArrayList<>(); + + var mp = new Milepost(); + mp = new Milepost(); + mp.setLatitude(BigDecimal.valueOf(200)); + mp.setLongitude(BigDecimal.valueOf(300)); + mileposts.add(mp); + + + mp = new Milepost(); + mp.setLatitude(BigDecimal.valueOf(300)); + mp.setLongitude(BigDecimal.valueOf(300)); + mileposts.add(mp); + + mp = new Milepost(); + mp.setLatitude(BigDecimal.valueOf(400)); + mp.setLongitude(BigDecimal.valueOf(400)); + mileposts.add(mp); + + mp = new Milepost(); + mp.setLatitude(BigDecimal.valueOf(500)); + mp.setLongitude(BigDecimal.valueOf(500)); + mileposts.add(mp); + return mileposts; + } + @Test public void testCreateIncidentTim_bothDirections_success() throws Exception { @@ -92,7 +125,7 @@ public void testCreateIncidentTim_bothDirections_success() throws Exception { } @Test - public void testCreateIncidentTim_bothDirections_NoMileposts() throws Exception { + public void testCreateIncidentTim_bothDirections_RouteNotSupported() throws Exception { // Arrange String incidentJson = "{\"timIncidentList\": [{ \"startPoint\": {\"latitude\": 41.161446, \"longitude\": -104.653162},\"endPoint\": {\"latitude\": 41.170465, \"longitude\": -104.085578}, \"impact\":\"L\", \"problem\": \"fire\", \"effect\": \"test\",\"action\": \"test\", \"pk\": 3622, \"highway\": \"I-25\", \"incidentId\":\"IN49251\", \"direction\": \"b\", \"ts\": \"2018-04-16T19:30:05.000Z\"}]}"; @@ -133,6 +166,7 @@ public void testCreateIncidentTim_bothDirections_NoItisCodes() throws Exception @Test public void testCreateIncidentTim_oneDirection_success() throws Exception { + //Arrange String incidentJson = "{\"timIncidentList\": [{ \"startPoint\": {\"latitude\": 41.161446, \"longitude\": -104.653162},\"endPoint\": {\"latitude\": 41.170465, \"longitude\": -104.085578}, \"impact\":\"L\", \"problem\": \"fire\", \"effect\": \"test\",\"action\": \"test\", \"pk\": 3622, \"highway\": \"I-80\", \"incidentId\":\"OD49251\", \"direction\": \"i\", \"ts\":\"2018-04-16T19:30:05.000Z\" }]}"; TimIncidentList til = gson.fromJson(incidentJson, TimIncidentList.class); @@ -150,8 +184,9 @@ public void testCreateIncidentTim_oneDirection_success() throws Exception { } @Test - public void testCreateIncidentTim_oneDirection_NoMileposts() throws Exception { + public void testCreateIncidentTim_oneDirection_RouteNotSupported() throws Exception { + // Arrange String incidentJson = "{\"timIncidentList\": [{ \"startPoint\": {\"latitude\": 41.161446, \"longitude\": -104.653162},\"endPoint\": {\"latitude\": 41.170465, \"longitude\": -104.085578}, \"impact\":\"L\", \"problem\": \"fire\", \"effect\": \"test\",\"action\": \"test\", \"pk\": 3622, \"highway\": \"I-25\", \"incidentId\":\"IN49251\", \"direction\": \"i\", \"ts\":\"2018-04-16T19:30:05.000Z\" }]}"; TimIncidentList til = gson.fromJson(incidentJson, TimIncidentList.class); doReturn(false).when(uut).routeSupported("I-25"); @@ -171,6 +206,7 @@ public void testCreateIncidentTim_oneDirection_NoMileposts() throws Exception { @Test public void testCreateIncidentTim_oneDirection_NoItisCodes() throws Exception { + // Arrange String incidentJson = "{\"timIncidentList\": [{ \"startPoint\": {\"latitude\": 41.161446, \"longitude\": -104.653162},\"endPoint\": {\"latitude\": 41.170465, \"longitude\": -104.085578}, \"impact\":\"L\", \"problem\": \"test\", \"effect\": \"test\",\"action\": \"test\", \"pk\": 3622, \"highway\": \"I-80\", \"incidentId\":\"IN49251\", \"direction\": \"i\", \"ts\":\"2018-04-16T19:30:05.000Z\" }]}"; TimIncidentList til = gson.fromJson(incidentJson, TimIncidentList.class); diff --git a/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimRwControllerTest.java b/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimRwControllerTest.java index b632f272d..d502d51df 100644 --- a/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimRwControllerTest.java +++ b/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimRwControllerTest.java @@ -2,9 +2,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.isA; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.lenient; -import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.*; import java.util.ArrayList; import java.util.Collection; @@ -16,6 +14,7 @@ import com.trihydro.library.model.ActiveTim; import com.trihydro.library.model.ItisCode; import com.trihydro.library.model.TimRwList; +import com.trihydro.library.service.MilepostService; import com.trihydro.library.service.TimTypeService; import com.trihydro.library.service.WydotTimService; import com.trihydro.odewrapper.config.BasicConfiguration; @@ -49,6 +48,8 @@ public class WydotTimRwControllerTest { SetItisCodes setItisCodes; @Mock Utility utility; + @Mock + private MilepostService milepostService; @InjectMocks @Spy @@ -58,6 +59,8 @@ public class WydotTimRwControllerTest { @BeforeEach public void setup() throws Exception { + milepostService = mock(MilepostService.class); + List itisCodes = new ArrayList<>(); ItisCode ic = new ItisCode(); ic.setCategoryId(-1); @@ -117,7 +120,7 @@ public void testCreateRwTim_bothDirections_NoMileposts() throws Exception { @Test public void testCreateRwTim_bothDirections_NoItisCodes() throws Exception { - + // Arrange String rwJson = "{ \"timRwList\": [ {\"startPoint\": {\"latitude\": 41.161446, \"longitude\": -104.653162},\"endPoint\": {\"latitude\": 41.170465, \"longitude\": -104.085578},\"highway\": \"I-80\",\"pk\": \"15917\",\"id\": \"15917\",\"projectKey\": 19185,\"direction\":\"d\",\"surface\": \"P\",\"schedStart\": \"2018-04-16\"}]}"; TimRwList timRwList = gson.fromJson(rwJson, TimRwList.class); diff --git a/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimVslControllerTest.java b/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimVslControllerTest.java index cb352011c..56b78aa9b 100644 --- a/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimVslControllerTest.java +++ b/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimVslControllerTest.java @@ -2,8 +2,8 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.isA; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.lenient; +import static org.mockito.Mockito.*; + import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -14,6 +14,7 @@ import com.trihydro.library.model.ActiveTim; import com.trihydro.library.model.ItisCode; import com.trihydro.library.service.ActiveTimService; +import com.trihydro.library.service.MilepostService; import com.trihydro.library.service.TimTypeService; import com.trihydro.library.service.WydotTimService; import com.trihydro.odewrapper.config.BasicConfiguration; @@ -50,6 +51,8 @@ public class WydotTimVslControllerTest { ActiveTimService mockActiveTimService; @Mock Utility utility; + @Mock + MilepostService milepostService; @InjectMocks @Spy @@ -71,8 +74,10 @@ public void setup() throws Exception { lenient().doReturn(itisCodesIncident).when(mockSetItisCodes).setItisCodes(any()); lenient().doReturn(itisCodes).when(mockSetItisCodes).getItisCodes(); - lenient().doNothing().when(uut).processRequestAsync(any()); + milepostService = mock(MilepostService.class); + lenient().doReturn(true).when(uut).routeSupported(isA(String.class)); + lenient().doNothing().when(uut).processRequestAsync(any()); } @Test @@ -131,4 +136,12 @@ public void getVslTims_SUCCESS() { Assertions.assertEquals(at, data.iterator().next()); } +// @ParameterizedTest +// @CsvSource({ +// "[268, 8720], []", +// "[268, 13569, 8720, 12302], []", +// "[268, 7712, 8720], []", +// }) +// void testCreateVSLTim_itisOrdering_success(String code, List expectedDescription) { + } diff --git a/ode-wrapper/src/test/java/com/trihydro/odewrapper/helpers/SetItisCodesTest.java b/ode-wrapper/src/test/java/com/trihydro/odewrapper/helpers/SetItisCodesTest.java index 130e51239..6f50e170e 100644 --- a/ode-wrapper/src/test/java/com/trihydro/odewrapper/helpers/SetItisCodesTest.java +++ b/ode-wrapper/src/test/java/com/trihydro/odewrapper/helpers/SetItisCodesTest.java @@ -1,10 +1,7 @@ package com.trihydro.odewrapper.helpers; import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.when; -import com.trihydro.library.model.IncidentChoice; -import com.trihydro.odewrapper.model.WydotTimIncident; import java.util.ArrayList; import java.util.List; @@ -102,7 +99,7 @@ public void setItisCodesRc_translated() { WydotTimRc tim = new WydotTimRc(); ArrayList itisCodes = new ArrayList<>(); itisCodes.add("4868"); - itisCodes.add("769"); + itisCodes.add("770"); tim.setItisCodes(itisCodes); // Act var result = uut.setItisCodes(tim); From 9e5e07bbd03a5cf567079bb59bd1fb0302c95f93 Mon Sep 17 00:00:00 2001 From: Paige Monington Date: Thu, 16 Oct 2025 10:44:15 -0600 Subject: [PATCH 137/168] chore: remove unused method --- .../controller/WydotTimRwController.java | 1 - .../WydotTimIncidentControllerTest.java | 27 ------------------- .../odewrapper/WydotTimVslControllerTest.java | 8 ------ 3 files changed, 36 deletions(-) diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java index 2cf126edc..d752c671b 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java @@ -81,7 +81,6 @@ public ResponseEntity createRoadContructionTim(@RequestBody TimRwList ti if (wydotTim.getBuffers() != null) wydotTim.getBuffers().sort(Comparator.comparingDouble(Buffer::getDistance)); - if (wydotTim.getDirection().equalsIgnoreCase("b")) { // if bi-directional, make both increasing and decreasing TIMs timsToSend.addAll(makeIncreasingTims(wydotTim, bufferTimITISCodes, milepostService)); diff --git a/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimIncidentControllerTest.java b/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimIncidentControllerTest.java index 274590f76..c9b7620e5 100644 --- a/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimIncidentControllerTest.java +++ b/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimIncidentControllerTest.java @@ -76,33 +76,6 @@ public void setup() throws Exception { lenient().doReturn(true).when(uut).routeSupported(isA(String.class)); } - private List getMileposts() { - List mileposts = new ArrayList<>(); - - var mp = new Milepost(); - mp = new Milepost(); - mp.setLatitude(BigDecimal.valueOf(200)); - mp.setLongitude(BigDecimal.valueOf(300)); - mileposts.add(mp); - - - mp = new Milepost(); - mp.setLatitude(BigDecimal.valueOf(300)); - mp.setLongitude(BigDecimal.valueOf(300)); - mileposts.add(mp); - - mp = new Milepost(); - mp.setLatitude(BigDecimal.valueOf(400)); - mp.setLongitude(BigDecimal.valueOf(400)); - mileposts.add(mp); - - mp = new Milepost(); - mp.setLatitude(BigDecimal.valueOf(500)); - mp.setLongitude(BigDecimal.valueOf(500)); - mileposts.add(mp); - return mileposts; - } - @Test public void testCreateIncidentTim_bothDirections_success() throws Exception { diff --git a/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimVslControllerTest.java b/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimVslControllerTest.java index 56b78aa9b..7f3f65451 100644 --- a/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimVslControllerTest.java +++ b/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimVslControllerTest.java @@ -136,12 +136,4 @@ public void getVslTims_SUCCESS() { Assertions.assertEquals(at, data.iterator().next()); } -// @ParameterizedTest -// @CsvSource({ -// "[268, 8720], []", -// "[268, 13569, 8720, 12302], []", -// "[268, 7712, 8720], []", -// }) -// void testCreateVSLTim_itisOrdering_success(String code, List expectedDescription) { - } From 0a91c27ba88de0912a18fdca9cf4c31a766d04ee Mon Sep 17 00:00:00 2001 From: Paige Monington Date: Fri, 17 Oct 2025 08:25:03 -0600 Subject: [PATCH 138/168] feat: apply CTW content standard to variable speed limit tims --- .../controller/WydotTimBaseController.java | 2 +- .../odewrapper/helpers/SetItisCodes.java | 216 ++++++++++-------- .../odewrapper/WydotTimVslControllerTest.java | 6 +- .../odewrapper/helpers/SetItisCodesTest.java | 213 +++++++++++------ 4 files changed, 266 insertions(+), 171 deletions(-) diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java index 9e24d4130..0427ea68d 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java @@ -440,7 +440,7 @@ protected ControllerResult validateInputVsl(WydotTimVsl tim) { } // set itis codes - List itisCodes = setItisCodes.setItisCodes(tim); + List itisCodes = setItisCodes.setItisCodesVsl(tim); if (itisCodes.isEmpty()) { resultMessages.add("No ITIS codes found"); } diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java index c95e25fe4..7b91655a3 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Optional; import com.trihydro.library.model.CustomItisEnum; import com.trihydro.library.model.IncidentChoice; @@ -23,42 +24,41 @@ @Component @Slf4j public class SetItisCodes { - private final IncidentChoicesService incidentChoicesService; - private final ItisCodeService itisCodeService; - - private List incidentProblems; - private List incidentEffects; - private List incidentActions; - - private List itisCodes; - - @Autowired - public SetItisCodes(ItisCodeService _itisCodeService, IncidentChoicesService _incidentChoicesService) { - itisCodeService = _itisCodeService; - incidentChoicesService = _incidentChoicesService; - } - - public List getItisCodes() { - if (itisCodes != null) { - return itisCodes; - } else { - itisCodes = itisCodeService.selectAll(); - return itisCodes; + private final IncidentChoicesService incidentChoicesService; + private final ItisCodeService itisCodeService; + + private List incidentProblems; + private List incidentEffects; + private List incidentActions; + + private List itisCodes; + + @Autowired + public SetItisCodes(ItisCodeService _itisCodeService, IncidentChoicesService _incidentChoicesService) { + itisCodeService = _itisCodeService; + incidentChoicesService = _incidentChoicesService; } - } - public List setItisCodesFromAdvisoryArray(WydotTimRc wydotTim) { + public List getItisCodes() { + if (itisCodes != null) { + return itisCodes; + } else { + itisCodes = itisCodeService.selectAll(); + return itisCodes; + } + } - // check to see if code exists + public List setItisCodesFromAdvisoryArray(WydotTimRc wydotTim) { - List items = new ArrayList<>(); - for (Integer item : wydotTim.getAdvisory()) { + // check to see if code exists + List items = new ArrayList<>(); + for (Integer item : wydotTim.getAdvisory()) { - getItisCodes().stream().filter(x -> x.getItisCode().equals(item)).findFirst().ifPresent(code -> items.add(item.toString())); + getItisCodes().stream().filter(x -> x.getItisCode().equals(item)).findFirst().ifPresent(code -> items.add(item.toString())); + } + return items; } - return items; - } public String getCustomAlphabetic(Integer itisCode) { String text = null; @@ -71,66 +71,66 @@ public String getCustomAlphabetic(Integer itisCode) { public List setItisCodesParking(WydotTimParking wydotTim) { - // check to see if code exists - List items = new ArrayList<>(); + // check to see if code exists + List items = new ArrayList<>(); - ItisCode code = getItisCodes().stream().filter(x -> x.getItisCode().equals(wydotTim.getAvailability())).findFirst().orElse(null); + ItisCode code = getItisCodes().stream().filter(x -> x.getItisCode().equals(wydotTim.getAvailability())).findFirst().orElse(null); - log.info("Availablity : {}", wydotTim.getAvailability()); - log.info("Exit : {}", wydotTim.getExit()); + log.info("Availablity : {}", wydotTim.getAvailability()); + log.info("Exit : {}", wydotTim.getExit()); - if (code != null) { - items.add(wydotTim.getAvailability().toString()); - } + if (code != null) { + items.add(wydotTim.getAvailability().toString()); + } - // for parking TIM, content=exitService, and includes additional itis codes - // depending on if rest area or exit number - if (wydotTim.getExit() != null) { - // if exit, the exit number should be a text value. - // This has some strange implications as seen here - // https://github.com/usdot-jpo-ode/jpo-ode/blob/540b79f1697f4d6464e8c4b8491666ec9cf08d8d/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverter.java#L337 - // the ODE translates a text value only if we start with a single quote to - // denote this. No ending quote is used - items.add("11794");// Exit Number - if (wydotTim.getExit().equalsIgnoreCase("turnout") || wydotTim.getExit().equalsIgnoreCase("parking")) { - items.add("'" + (int) Math.round(wydotTim.getMileMarker())); - } else { - items.add("'" + wydotTim.getExit()); - } - } else { - items.add("7986");// Rest Area - log.info("rest area"); - } + // for parking TIM, content=exitService, and includes additional itis codes + // depending on if rest area or exit number + if (wydotTim.getExit() != null) { + // if exit, the exit number should be a text value. + // This has some strange implications as seen here + // https://github.com/usdot-jpo-ode/jpo-ode/blob/540b79f1697f4d6464e8c4b8491666ec9cf08d8d/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverter.java#L337 + // the ODE translates a text value only if we start with a single quote to + // denote this. No ending quote is used + items.add("11794");// Exit Number + if (wydotTim.getExit().equalsIgnoreCase("turnout") || wydotTim.getExit().equalsIgnoreCase("parking")) { + items.add("'" + (int) Math.round(wydotTim.getMileMarker())); + } else { + items.add("'" + wydotTim.getExit()); + } + } else { + items.add("7986");// Rest Area + log.info("rest area"); + } return items; } - public List getIncidentProblems() { - if (incidentProblems != null) { - return incidentProblems; - } else { - incidentProblems = incidentChoicesService.selectAllIncidentProblems(); - return incidentProblems; + public List getIncidentProblems() { + if (incidentProblems != null) { + return incidentProblems; + } else { + incidentProblems = incidentChoicesService.selectAllIncidentProblems(); + return incidentProblems; + } } - } - - public List getIncidentEffects() { - if (incidentEffects != null) { - return incidentEffects; - } else { - incidentEffects = incidentChoicesService.selectAllIncidentEffects(); - return incidentEffects; + + public List getIncidentEffects() { + if (incidentEffects != null) { + return incidentEffects; + } else { + incidentEffects = incidentChoicesService.selectAllIncidentEffects(); + return incidentEffects; + } } - } - - public List getIncidentActions() { - if (incidentActions != null) { - return incidentActions; - } else { - incidentActions = incidentChoicesService.selectAllIncidentActions(); - return incidentActions; + + public List getIncidentActions() { + if (incidentActions != null) { + return incidentActions; + } else { + incidentActions = incidentChoicesService.selectAllIncidentActions(); + return incidentActions; + } } - } public List setItisCodes(WydotTim wydotTim) { @@ -163,24 +163,56 @@ public List setItisCodes(WydotTim wydotTim) { items.add(code.getItisCode().toString()); } - return items; - } + return items; + } + + public List setItisCodesVsl(WydotTimVsl wydotTim) { + + List items = new ArrayList(); + + List allItisCodes = getItisCodes(); + + // add advisory code first if advisory speed limit + wydotTim.getItisCodes().stream().filter(x -> x.contains("7712")).findFirst() + .ifPresent(items::add); + + // speed limit itis code + allItisCodes.stream().filter(x -> x.getDescription().equals("speed limit")).findFirst().ifPresent(mph -> items.add(mph.getItisCode().toString())); - public List setItisCodesBowr(WydotTimBowr tim) throws WeightNotSupportedException { - List itisCodes = new ArrayList<>(); + // add reduced code next if reduced speed + wydotTim.getItisCodes().stream().filter(x -> x.contains("12302")).findFirst() + .ifPresent(items::add); - int weightInPounds = tim.getData(); + // number e.g 50, convert to ITIS code + items.add(Integer.toString( + Optional.ofNullable(wydotTim.getSpeed()).orElse(0) + 12544 + )); - itisCodes.add("5127"); // Strong winds - itisCodes.add("2563"); // Truck restriction - itisCodes.add("2569"); // No high profile vehicles - itisCodes.add("7682"); // Below - itisCodes.add("2577"); // Gross-Weight-Limit - itisCodes.add(translateWeightToItisCode(weightInPounds)); // Weight, translated from pounds to ITIS code - itisCodes.add("8739"); // Pounds + // mph itis code + allItisCodes.stream().filter(x -> x.getDescription().equals("mph")).findFirst().ifPresent(mph -> items.add(mph.getItisCode().toString())); - return itisCodes; - } + // add ahead code next if tim includes ahead code last + wydotTim.getItisCodes().stream().filter(x -> x.contains("13569")).findFirst() + .ifPresent(items::add); + + return items; + } + + public List setItisCodesBowr(WydotTimBowr tim) throws WeightNotSupportedException { + List itisCodes = new ArrayList<>(); + + int weightInPounds = tim.getData(); + + itisCodes.add("5127"); // Strong winds + itisCodes.add("2563"); // Truck restriction + itisCodes.add("2569"); // No high profile vehicles + itisCodes.add("7682"); // Below + itisCodes.add("2577"); // Gross-Weight-Limit + itisCodes.add(translateWeightToItisCode(weightInPounds)); // Weight, translated from pounds to ITIS code + itisCodes.add("8739"); // Pounds + + return itisCodes; + } public static String getItisCodeAbbreviation(String itisCodes) { List words = Arrays.asList(itisCodes.split(" ")); diff --git a/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimVslControllerTest.java b/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimVslControllerTest.java index 7f3f65451..695905b8a 100644 --- a/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimVslControllerTest.java +++ b/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimVslControllerTest.java @@ -69,9 +69,9 @@ public void setup() throws Exception { ic.setItisCode(-2); ic.setItisCodeId(-3); itisCodes.add(ic); - List itisCodesIncident = new ArrayList<>(); - itisCodesIncident.add("531"); - lenient().doReturn(itisCodesIncident).when(mockSetItisCodes).setItisCodes(any()); + List itisCodesVsl = new ArrayList<>(); + itisCodesVsl.add("531"); + lenient().doReturn(itisCodesVsl).when(mockSetItisCodes).setItisCodesVsl(any()); lenient().doReturn(itisCodes).when(mockSetItisCodes).getItisCodes(); milepostService = mock(MilepostService.class); diff --git a/ode-wrapper/src/test/java/com/trihydro/odewrapper/helpers/SetItisCodesTest.java b/ode-wrapper/src/test/java/com/trihydro/odewrapper/helpers/SetItisCodesTest.java index 6f50e170e..ff362f362 100644 --- a/ode-wrapper/src/test/java/com/trihydro/odewrapper/helpers/SetItisCodesTest.java +++ b/ode-wrapper/src/test/java/com/trihydro/odewrapper/helpers/SetItisCodesTest.java @@ -13,6 +13,7 @@ import com.trihydro.odewrapper.model.WydotTimBowr; import com.trihydro.odewrapper.model.WydotTimRc; +import com.trihydro.odewrapper.model.WydotTimVsl; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -23,42 +24,53 @@ @ExtendWith(MockitoExtension.class) public class SetItisCodesTest { - @Mock - ItisCodeService mockItisCodeService; - @Mock - IncidentChoicesService mockIncidentChoicesService; - - @InjectMocks - SetItisCodes uut; - - public void setup() { - List itisCodes = new ArrayList<>(); - ItisCode code = new ItisCode(); - code.setItisCode(268);// speed limit - itisCodes.add(code); - - code = new ItisCode(); - code.setItisCode(770);// closed - itisCodes.add(code); - - code = new ItisCode(); - code.setItisCode(1309);// rockfall - itisCodes.add(code); - - code = new ItisCode(); - code.setItisCode(3084);// wildfire - itisCodes.add(code); - - code = new ItisCode(); - code.setItisCode(4868); // snow - itisCodes.add(code); - - code = new ItisCode(); - code.setItisCode(770); // closed - itisCodes.add(code); - - doReturn(itisCodes).when(mockItisCodeService).selectAll(); - } + @Mock + ItisCodeService mockItisCodeService; + @Mock + IncidentChoicesService mockIncidentChoicesService; + + @InjectMocks + SetItisCodes uut; + + public void setup() { + List itisCodes = new ArrayList<>(); + ItisCode code = new ItisCode(); + code.setItisCode(268); + code.setDescription("speed limit"); + itisCodes.add(code); + + code = new ItisCode(); + code.setItisCode(770); + code.setDescription("closed"); + itisCodes.add(code); + + code = new ItisCode(); + code.setItisCode(1309); + code.setDescription("rockfall"); + itisCodes.add(code); + + code = new ItisCode(); + code.setItisCode(3084); + code.setDescription("wildfire"); + itisCodes.add(code); + + code = new ItisCode(); + code.setItisCode(4868); + code.setDescription("snow"); + itisCodes.add(code); + + code = new ItisCode(); + code.setItisCode(770); + code.setDescription("closed"); + itisCodes.add(code); + + code = new ItisCode(); + code.setItisCode(8720); + code.setDescription("mph"); + itisCodes.add(code); + + doReturn(itisCodes).when(mockItisCodeService).selectAll(); + } @Test public void setItisCodesRc_numeric() { @@ -72,9 +84,9 @@ public void setItisCodesRc_numeric() { // Act var result = uut.setItisCodes(tim); - // Assert - Assertions.assertEquals(2, result.size()); - } + // Assert + Assertions.assertEquals(2, result.size()); + } @Test public void setItisCodesRc_nonExistent() { @@ -88,9 +100,9 @@ public void setItisCodesRc_nonExistent() { // Act var result = uut.setItisCodes(tim); - // Assert - Assertions.assertEquals(0, result.size()); - } + // Assert + Assertions.assertEquals(0, result.size()); + } @Test public void setItisCodesRc_translated() { @@ -104,10 +116,10 @@ public void setItisCodesRc_translated() { // Act var result = uut.setItisCodes(tim); - // Assert - Assertions.assertEquals(2, result.size()); - Assertions.assertTrue(result.contains("770")); - } + // Assert + Assertions.assertEquals(2, result.size()); + Assertions.assertTrue(result.contains("770")); + } @Test public void setItisCodesRc_alphabetic() { @@ -121,37 +133,88 @@ public void setItisCodesRc_alphabetic() { // Act var result = uut.setItisCodes(tim); - // Assert - Assertions.assertEquals(2, result.size()); - Assertions.assertTrue(result.contains("Extreme blow over risk")); - } - - @Test - public void setItisCodesBowr_SUCCESS() throws WeightNotSupportedException { - // Arrange - // calling setup() not necessary here - int weightInPounds = 20000; - String weightAsItisCode = "11589"; - WydotTimBowr tim = new WydotTimBowr(); - tim.setData(weightInPounds); - List expectedResult = List.of("5127", "2563", "2569", "7682", "2577", weightAsItisCode, "8739"); - - // Act - List result = uut.setItisCodesBowr(tim); - - // Assert - Assertions.assertEquals(expectedResult, result); - } - - @Test - public void setItisCodesBowr_FAILURE() { - // Arrange - // calling setup() not necessary here - int weightInPounds = 23456; - WydotTimBowr tim = new WydotTimBowr(); - tim.setData(weightInPounds); + // Assert + Assertions.assertEquals(2, result.size()); + Assertions.assertTrue(result.contains("Extreme blow over risk")); + } + + @Test + public void setItisCodesBowr_SUCCESS() throws WeightNotSupportedException { + // Arrange + // calling setup() not necessary here + int weightInPounds = 20000; + String weightAsItisCode = "11589"; + WydotTimBowr tim = new WydotTimBowr(); + tim.setData(weightInPounds); + List expectedResult = List.of("5127", "2563", "2569", "7682", "2577", weightAsItisCode, "8739"); + + // Act + List result = uut.setItisCodesBowr(tim); + + // Assert + Assertions.assertEquals(expectedResult, result); + } + + @Test + public void setItisCodesBowr_FAILURE() { + // Arrange + // calling setup() not necessary here + int weightInPounds = 23456; + WydotTimBowr tim = new WydotTimBowr(); + tim.setData(weightInPounds); // Act & Assert Assertions.assertThrows(WeightNotSupportedException.class, () -> uut.setItisCodesBowr(tim)); } + + @Test + public void setItisCodesVsl_Success() { + // Arrange + setup(); + int speedMph = 50; + WydotTimVsl tim = new WydotTimVsl(); + tim.setSpeed(speedMph); + tim.setItisCodes(List.of("268", "8720", "12594")); + List expectedResult = List.of("268", "12594", "8720"); + + // Act + var result = uut.setItisCodesVsl(tim); + + // Assert + Assertions.assertEquals(expectedResult, result); + } + + @Test + public void setItisCodes_reducedAhead_Success() { + // Arrange + setup(); + int speedMph = 50; + WydotTimVsl tim = new WydotTimVsl(); + tim.setSpeed(speedMph); + tim.setItisCodes(List.of("13569", "268", "12594", "8720", "12302")); + List expectedResult = List.of("268", "12302", "12594", "8720", "13569"); + + // Act + var result = uut.setItisCodesVsl(tim); + + // Assert + Assertions.assertEquals(expectedResult, result); + } + + @Test + public void setItisCodesVsl_advisorySpeedLimit_Success() { + // Arrange + setup(); + int speedMph = 50; + WydotTimVsl tim = new WydotTimVsl(); + tim.setSpeed(speedMph); + tim.setItisCodes(List.of("268", "7712", "12594", "8720")); + List expectedResult = List.of("7712", "268", "12594", "8720"); + + // Act + var result = uut.setItisCodesVsl(tim); + + // Assert + Assertions.assertEquals(expectedResult, result); + } } \ No newline at end of file From c299f801ccf617c3398d5532ea55945daf3dd42a Mon Sep 17 00:00:00 2001 From: Paige Monington Date: Fri, 17 Oct 2025 08:26:01 -0600 Subject: [PATCH 139/168] chore: remove unused import --- .../main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java | 1 - 1 file changed, 1 deletion(-) diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java index 7b91655a3..a1bce3db9 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java @@ -12,7 +12,6 @@ import com.trihydro.library.service.IncidentChoicesService; import com.trihydro.library.service.ItisCodeService; import com.trihydro.odewrapper.model.WydotTimBowr; -import com.trihydro.odewrapper.model.WydotTimIncident; import com.trihydro.odewrapper.model.WydotTimParking; import com.trihydro.odewrapper.model.WydotTimRc; import com.trihydro.odewrapper.model.WydotTimVsl; From 096f0a4f2c32722001e0dc654936380c26287560 Mon Sep 17 00:00:00 2001 From: pmonington <121187998+pmonington@users.noreply.github.com> Date: Fri, 17 Oct 2025 11:59:15 -0600 Subject: [PATCH 140/168] chore: make test name more specific Co-authored-by: Matt Cook --- .../com/trihydro/odewrapper/factory/BufferTimFactoryTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ode-wrapper/src/test/java/com/trihydro/odewrapper/factory/BufferTimFactoryTest.java b/ode-wrapper/src/test/java/com/trihydro/odewrapper/factory/BufferTimFactoryTest.java index 2dbd81a09..aebfbc74f 100644 --- a/ode-wrapper/src/test/java/com/trihydro/odewrapper/factory/BufferTimFactoryTest.java +++ b/ode-wrapper/src/test/java/com/trihydro/odewrapper/factory/BufferTimFactoryTest.java @@ -95,7 +95,7 @@ void testMilepostToGeometry() { } @Test - void testBuildTimsFromItisCodes_withNonBufferCode() { + void testBuildTimsFromItisCodes_withoutBufferCode() { // Arrange List bufferCodes = List.of(7364); From 07940bc6e39a3ea3a9113e3a4f4de9fcf1098576 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Fri, 17 Oct 2025 13:43:08 -0600 Subject: [PATCH 141/168] refactor: modify geometry validation logic in WydotTim and WydotTimService --- .../src/main/java/com/trihydro/library/model/WydotTim.java | 4 ++-- .../java/com/trihydro/library/service/WydotTimService.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/model/WydotTim.java b/cv-data-service-library/src/main/java/com/trihydro/library/model/WydotTim.java index 7ace51f05..700988d3c 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/model/WydotTim.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/model/WydotTim.java @@ -127,7 +127,7 @@ public void setBearing(Integer bearing) { } public boolean isGeometryValid() { - if (this.geometry != null && !this.geometry.isEmpty()) { + if (this.geometry != null && this.getGeometry().size() > 1) { // must have 2 or more points to be valid for (Coordinate coord : this.geometry) { if (!coord.isValid()) { return false; @@ -141,7 +141,7 @@ public boolean isGeometryValid() { public List toMileposts() { var mileposts = new ArrayList(); - if (this.getGeometry() != null && this.getGeometry().size() > 1) { + if (isGeometryValid()) { for (Coordinate coordinate : this.getGeometry()) { Milepost milepost = new Milepost(); milepost.setLatitude(coordinate.getLatitude()); diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java b/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java index dee5febe7..2e8aea117 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java @@ -173,7 +173,7 @@ public List getAllMilepostsForTim(WydotTim wydotTim) { return milepostsAll; } - if (wydotTim.getGeometry() != null && wydotTim.getGeometry().size() > 1) { + if (wydotTim.isGeometryValid()) { if (milepostsAll == null) { milepostsAll = new ArrayList<>(); } @@ -268,7 +268,7 @@ public void sendTimToRsus(WydotTim wydotTim, WydotTravelerInputData timToSend, S // if geometry exists, use it to find RSUs List rsus = new ArrayList<>(); - if (wydotTim.isGeometryValid() && wydotTim.getGeometry().size() > 1) { + if (wydotTim.isGeometryValid()) { rsus = rsuService.getRsusByGeometry(wydotTim.getGeometry()); utility.logWithDate("Found " + rsus.size() + " RSUs by geometry"); } else { From a983638bfd8216c3883e773bcd3636b95a02aa86 Mon Sep 17 00:00:00 2001 From: Paige Monington Date: Mon, 20 Oct 2025 14:18:08 -0600 Subject: [PATCH 142/168] fix: handle unspecified speed values in variable speed limit TIM --- .../controller/WydotTimBaseController.java | 11 +++++--- .../odewrapper/helpers/SetItisCodes.java | 3 +++ .../odewrapper/model/WydotTimVsl.java | 2 ++ .../odewrapper/helpers/SetItisCodesTest.java | 27 ++++++++++++------- 4 files changed, 31 insertions(+), 12 deletions(-) diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java index 0427ea68d..66187b0ff 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java @@ -440,9 +440,14 @@ protected ControllerResult validateInputVsl(WydotTimVsl tim) { } // set itis codes - List itisCodes = setItisCodes.setItisCodesVsl(tim); - if (itisCodes.isEmpty()) { - resultMessages.add("No ITIS codes found"); + List itisCodes = new ArrayList<>(); + try { + itisCodes= setItisCodes.setItisCodesVsl(tim); + if (itisCodes.isEmpty()) { + resultMessages.add("No ITIS codes found"); + } + } catch (Exception e) { + resultMessages.add("Could not determine speed for speed limit tim"); } result.setItisCodes(itisCodes); tim.setItisCodes(itisCodes); diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java index a1bce3db9..e3b4f8aa3 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java @@ -168,6 +168,9 @@ public List setItisCodes(WydotTim wydotTim) { public List setItisCodesVsl(WydotTimVsl wydotTim) { List items = new ArrayList(); + if (wydotTim.getSpeed() == null) { + throw new IllegalArgumentException("Cannot determine Speed limit. Speed cannot be null."); + } List allItisCodes = getItisCodes(); diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/model/WydotTimVsl.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/model/WydotTimVsl.java index 76af8a4fa..525b98d37 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/model/WydotTimVsl.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/model/WydotTimVsl.java @@ -1,9 +1,11 @@ package com.trihydro.odewrapper.model; import com.trihydro.library.model.WydotTim; +import io.swagger.annotations.ApiModelProperty; public class WydotTimVsl extends WydotTim { + @ApiModelProperty(required = true) private Integer speed; private String deviceId; diff --git a/ode-wrapper/src/test/java/com/trihydro/odewrapper/helpers/SetItisCodesTest.java b/ode-wrapper/src/test/java/com/trihydro/odewrapper/helpers/SetItisCodesTest.java index ff362f362..bff111c35 100644 --- a/ode-wrapper/src/test/java/com/trihydro/odewrapper/helpers/SetItisCodesTest.java +++ b/ode-wrapper/src/test/java/com/trihydro/odewrapper/helpers/SetItisCodesTest.java @@ -32,7 +32,7 @@ public class SetItisCodesTest { @InjectMocks SetItisCodes uut; - public void setup() { + public void setupItisCodeDefinitions() { List itisCodes = new ArrayList<>(); ItisCode code = new ItisCode(); code.setItisCode(268); @@ -75,9 +75,9 @@ public void setup() { @Test public void setItisCodesRc_numeric() { // Arrange - setup(); + setupItisCodeDefinitions(); WydotTimRc tim = new WydotTimRc(); - ArrayList itisCodes = new ArrayList(); + ArrayList itisCodes = new ArrayList<>(); itisCodes.add("4868"); itisCodes.add("1309"); tim.setItisCodes(itisCodes); @@ -91,7 +91,7 @@ public void setItisCodesRc_numeric() { @Test public void setItisCodesRc_nonExistent() { // Arrange - setup(); + setupItisCodeDefinitions(); WydotTimRc tim = new WydotTimRc(); ArrayList itisCodes = new ArrayList<>(); itisCodes.add("0"); @@ -107,7 +107,7 @@ public void setItisCodesRc_nonExistent() { @Test public void setItisCodesRc_translated() { // Arrange - setup(); + setupItisCodeDefinitions(); WydotTimRc tim = new WydotTimRc(); ArrayList itisCodes = new ArrayList<>(); itisCodes.add("4868"); @@ -124,7 +124,7 @@ public void setItisCodesRc_translated() { @Test public void setItisCodesRc_alphabetic() { // Arrange - setup(); + setupItisCodeDefinitions(); WydotTimRc tim = new WydotTimRc(); ArrayList itisCodes = new ArrayList<>(); itisCodes.add("4868"); @@ -170,7 +170,7 @@ public void setItisCodesBowr_FAILURE() { @Test public void setItisCodesVsl_Success() { // Arrange - setup(); + setupItisCodeDefinitions(); int speedMph = 50; WydotTimVsl tim = new WydotTimVsl(); tim.setSpeed(speedMph); @@ -184,10 +184,19 @@ public void setItisCodesVsl_Success() { Assertions.assertEquals(expectedResult, result); } + @Test + public void setItisCodesVsl_Failure() { + // Arrange + WydotTimVsl tim = new WydotTimVsl(); + + // Act and Assert + Assertions.assertThrows(IllegalArgumentException.class, () -> uut.setItisCodesVsl(tim)); + } + @Test public void setItisCodes_reducedAhead_Success() { // Arrange - setup(); + setupItisCodeDefinitions(); int speedMph = 50; WydotTimVsl tim = new WydotTimVsl(); tim.setSpeed(speedMph); @@ -204,7 +213,7 @@ public void setItisCodes_reducedAhead_Success() { @Test public void setItisCodesVsl_advisorySpeedLimit_Success() { // Arrange - setup(); + setupItisCodeDefinitions(); int speedMph = 50; WydotTimVsl tim = new WydotTimVsl(); tim.setSpeed(speedMph); From 46f3443aa14362e1a806914b67605d5d331e656f Mon Sep 17 00:00:00 2001 From: Paige Monington Date: Mon, 20 Oct 2025 14:20:37 -0600 Subject: [PATCH 143/168] chore: adjust ITIS code method for clarity --- .../com/trihydro/odewrapper/helpers/SetItisCodes.java | 10 +++++----- .../odewrapper/WydotTimIncidentControllerTest.java | 4 +--- .../odewrapper/WydotTimParkingControllerTest.java | 2 +- .../trihydro/odewrapper/WydotTimRcControllerTest.java | 3 +-- .../trihydro/odewrapper/WydotTimRwControllerTest.java | 2 +- .../trihydro/odewrapper/WydotTimVslControllerTest.java | 2 +- .../odewrapper/factory/BufferTimFactoryTest.java | 2 +- 7 files changed, 11 insertions(+), 14 deletions(-) diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java index e3b4f8aa3..2b76411ad 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java @@ -38,7 +38,7 @@ public SetItisCodes(ItisCodeService _itisCodeService, IncidentChoicesService _in incidentChoicesService = _incidentChoicesService; } - public List getItisCodes() { + public List getAllItisCodesFromDatabase() { if (itisCodes != null) { return itisCodes; } else { @@ -53,7 +53,7 @@ public List setItisCodesFromAdvisoryArray(WydotTimRc wydotTim) { List items = new ArrayList<>(); for (Integer item : wydotTim.getAdvisory()) { - getItisCodes().stream().filter(x -> x.getItisCode().equals(item)).findFirst().ifPresent(code -> items.add(item.toString())); + getAllItisCodesFromDatabase().stream().filter(x -> x.getItisCode().equals(item)).findFirst().ifPresent(code -> items.add(item.toString())); } return items; @@ -73,7 +73,7 @@ public List setItisCodesParking(WydotTimParking wydotTim) { // check to see if code exists List items = new ArrayList<>(); - ItisCode code = getItisCodes().stream().filter(x -> x.getItisCode().equals(wydotTim.getAvailability())).findFirst().orElse(null); + ItisCode code = getAllItisCodesFromDatabase().stream().filter(x -> x.getItisCode().equals(wydotTim.getAvailability())).findFirst().orElse(null); log.info("Availablity : {}", wydotTim.getAvailability()); log.info("Exit : {}", wydotTim.getExit()); @@ -156,7 +156,7 @@ public List setItisCodes(WydotTim wydotTim) { continue; } - code = getItisCodes().stream().filter(x -> x.getItisCode().equals(itisCode)).findFirst().orElse(null); + code = getAllItisCodesFromDatabase().stream().filter(x -> x.getItisCode().equals(itisCode)).findFirst().orElse(null); if (code != null) items.add(code.getItisCode().toString()); @@ -172,7 +172,7 @@ public List setItisCodesVsl(WydotTimVsl wydotTim) { throw new IllegalArgumentException("Cannot determine Speed limit. Speed cannot be null."); } - List allItisCodes = getItisCodes(); + List allItisCodes = getAllItisCodesFromDatabase(); // add advisory code first if advisory speed limit wydotTim.getItisCodes().stream().filter(x -> x.contains("7712")).findFirst() diff --git a/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimIncidentControllerTest.java b/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimIncidentControllerTest.java index c9b7620e5..5742d76e0 100644 --- a/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimIncidentControllerTest.java +++ b/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimIncidentControllerTest.java @@ -4,7 +4,6 @@ import static org.mockito.ArgumentMatchers.isA; import static org.mockito.Mockito.*; -import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -13,7 +12,6 @@ import com.trihydro.library.helpers.Utility; import com.trihydro.library.model.ActiveTim; import com.trihydro.library.model.ItisCode; -import com.trihydro.library.model.Milepost; import com.trihydro.library.service.MilepostService; import com.trihydro.library.service.TimTypeService; import com.trihydro.library.service.WydotTimService; @@ -70,7 +68,7 @@ public void setup() throws Exception { List itisCodesIncident = new ArrayList<>(); itisCodesIncident.add("531"); lenient().doReturn(itisCodesIncident).when(setItisCodes).setItisCodes(any()); - lenient().doReturn(itisCodes).when(setItisCodes).getItisCodes(); + lenient().doReturn(itisCodes).when(setItisCodes).getAllItisCodesFromDatabase(); lenient().doNothing().when(uut).makeTimsAsync(any()); lenient().doReturn(true).when(uut).routeSupported(isA(String.class)); diff --git a/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimParkingControllerTest.java b/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimParkingControllerTest.java index 80b7930b9..c00a1a487 100644 --- a/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimParkingControllerTest.java +++ b/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimParkingControllerTest.java @@ -69,7 +69,7 @@ public void setup() throws Exception { List itisCodesIncident = new ArrayList<>(); itisCodesIncident.add("531"); lenient().doReturn(itisCodesIncident).when(setItisCodes).setItisCodesParking(any()); - lenient().doReturn(itisCodes).when(setItisCodes).getItisCodes(); + lenient().doReturn(itisCodes).when(setItisCodes).getAllItisCodesFromDatabase(); lenient().doNothing().when(uut).processRequestAsync(any()); lenient().doReturn(true).when(uut).routeSupported(isA(String.class)); diff --git a/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimRcControllerTest.java b/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimRcControllerTest.java index c9ceb3bbb..485711a9f 100644 --- a/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimRcControllerTest.java +++ b/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimRcControllerTest.java @@ -4,7 +4,6 @@ import static org.mockito.ArgumentMatchers.isA; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.lenient; -import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -74,7 +73,7 @@ public void setup() throws Exception { List itisCodesIncident = new ArrayList<>(); itisCodesIncident.add("531"); lenient().doReturn(itisCodesIncident).when(setItisCodes).setItisCodes(any()); - lenient().doReturn(itisCodes).when(setItisCodes).getItisCodes(); + lenient().doReturn(itisCodes).when(setItisCodes).getAllItisCodesFromDatabase(); lenient().doReturn(true).when(uut).routeSupported(isA(String.class)); } diff --git a/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimRwControllerTest.java b/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimRwControllerTest.java index d502d51df..809504631 100644 --- a/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimRwControllerTest.java +++ b/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimRwControllerTest.java @@ -71,7 +71,7 @@ public void setup() throws Exception { List itisCodesIncident = new ArrayList<>(); itisCodesIncident.add("531"); lenient().doReturn(itisCodesIncident).when(setItisCodes).setItisCodes(any()); - lenient().doReturn(itisCodes).when(setItisCodes).getItisCodes(); + lenient().doReturn(itisCodes).when(setItisCodes).getAllItisCodesFromDatabase(); lenient().doReturn(true).when(uut).routeSupported(isA(String.class)); diff --git a/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimVslControllerTest.java b/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimVslControllerTest.java index 695905b8a..f639e14fd 100644 --- a/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimVslControllerTest.java +++ b/ode-wrapper/src/test/java/com/trihydro/odewrapper/WydotTimVslControllerTest.java @@ -72,7 +72,7 @@ public void setup() throws Exception { List itisCodesVsl = new ArrayList<>(); itisCodesVsl.add("531"); lenient().doReturn(itisCodesVsl).when(mockSetItisCodes).setItisCodesVsl(any()); - lenient().doReturn(itisCodes).when(mockSetItisCodes).getItisCodes(); + lenient().doReturn(itisCodes).when(mockSetItisCodes).getAllItisCodesFromDatabase(); milepostService = mock(MilepostService.class); diff --git a/ode-wrapper/src/test/java/com/trihydro/odewrapper/factory/BufferTimFactoryTest.java b/ode-wrapper/src/test/java/com/trihydro/odewrapper/factory/BufferTimFactoryTest.java index 2dbd81a09..6d39d0d6a 100644 --- a/ode-wrapper/src/test/java/com/trihydro/odewrapper/factory/BufferTimFactoryTest.java +++ b/ode-wrapper/src/test/java/com/trihydro/odewrapper/factory/BufferTimFactoryTest.java @@ -50,7 +50,7 @@ void setUp() { itisCodes.add(ic); lenient().doReturn(wydotTimItisCodes).when(setItisCodes).setItisCodes(any()); - lenient().doReturn(itisCodes).when(setItisCodes).getItisCodes(); + lenient().doReturn(itisCodes).when(setItisCodes).getAllItisCodesFromDatabase(); } private List getMileposts() { From 4bb6c3ff9739a7f079e38c6f5ffba9c1c2788c9f Mon Sep 17 00:00:00 2001 From: Paige Monington Date: Mon, 20 Oct 2025 14:39:50 -0600 Subject: [PATCH 144/168] docs: add clarifying comments and add documentation --- .../odewrapper/helpers/SetItisCodes.java | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java index 2b76411ad..dec02b646 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java @@ -32,6 +32,10 @@ public class SetItisCodes { private List itisCodes; + private final String AdvisoryItisCode = "7712"; + private final String ReducedItisCode = "12302"; + private final String AheadItisCode = "13569"; + @Autowired public SetItisCodes(ItisCodeService _itisCodeService, IncidentChoicesService _incidentChoicesService) { itisCodeService = _itisCodeService; @@ -165,6 +169,12 @@ public List setItisCodes(WydotTim wydotTim) { return items; } + /** + * Creates a properly ordered list of ITIS codes based on the TIM. + * + * @param wydotTim TIM to base the ITIS codes on + * @return Properly ordered list of ITIS codes to assign back to the TIM + */ public List setItisCodesVsl(WydotTimVsl wydotTim) { List items = new ArrayList(); @@ -175,17 +185,18 @@ public List setItisCodesVsl(WydotTimVsl wydotTim) { List allItisCodes = getAllItisCodesFromDatabase(); // add advisory code first if advisory speed limit - wydotTim.getItisCodes().stream().filter(x -> x.contains("7712")).findFirst() + wydotTim.getItisCodes().stream().filter(x -> x.contains(AdvisoryItisCode)).findFirst() .ifPresent(items::add); // speed limit itis code allItisCodes.stream().filter(x -> x.getDescription().equals("speed limit")).findFirst().ifPresent(mph -> items.add(mph.getItisCode().toString())); // add reduced code next if reduced speed - wydotTim.getItisCodes().stream().filter(x -> x.contains("12302")).findFirst() + wydotTim.getItisCodes().stream().filter(x -> x.contains(ReducedItisCode)).findFirst() .ifPresent(items::add); - // number e.g 50, convert to ITIS code + // J2540 small number ITIS codes start at 12,544 and increment by 1 to represent each number up to 255. + // To covert speed to an ITIS code, adding 12,544 is enough. items.add(Integer.toString( Optional.ofNullable(wydotTim.getSpeed()).orElse(0) + 12544 )); @@ -194,7 +205,7 @@ public List setItisCodesVsl(WydotTimVsl wydotTim) { allItisCodes.stream().filter(x -> x.getDescription().equals("mph")).findFirst().ifPresent(mph -> items.add(mph.getItisCode().toString())); // add ahead code next if tim includes ahead code last - wydotTim.getItisCodes().stream().filter(x -> x.contains("13569")).findFirst() + wydotTim.getItisCodes().stream().filter(x -> x.contains(AheadItisCode)).findFirst() .ifPresent(items::add); return items; From e93567e7152a3f4545563983a6bff885654f3950 Mon Sep 17 00:00:00 2001 From: Paige Monington Date: Tue, 21 Oct 2025 07:29:27 -0600 Subject: [PATCH 145/168] fix: CTW standard make content sub-element strictly advisory --- .../controller/ActiveTimController.java | 23 +----- .../controller/ActiveTimControllerTest.java | 64 ++++++++--------- .../library/helpers/CreateBaseTimUtil.java | 18 ++--- .../library/helpers/JsonToJavaConverter.java | 20 +++--- .../library/service/WydotTimService.java | 11 ++- .../helpers/CreateBaseTimUtilTest.java | 16 ++--- .../helpers/JsonToJavaConverterTest.java | 14 ++-- .../library/service/WydotTimServiceTest.java | 70 ++++++++----------- .../controller/WydotTimBaseController.java | 21 +++--- .../controller/WydotTimBowrController.java | 16 ++--- .../controller/WydotTimCcController.java | 7 +- .../WydotTimIncidentController.java | 3 +- .../controller/WydotTimParkingController.java | 7 +- .../controller/WydotTimRcController.java | 11 ++- .../controller/WydotTimRwController.java | 6 +- .../controller/WydotTimVslController.java | 3 +- 16 files changed, 127 insertions(+), 183 deletions(-) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java index 42999b1c3..842c734db 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java @@ -113,17 +113,7 @@ public ResponseEntity> GetExpiringActiveTims() { activeTim.setFrameType(TravelerInfoType.advisory); } - // set dataFrame content. it's required for the ODE, so if we didn't record it, - // assume Advisory - String serializedContent = rs.getString("DF_CONTENT"); - ContentEnum contentType; - if (serializedContent == null || serializedContent.isEmpty()) { - contentType = ContentEnum.advisory; - } else { - contentType = ContentEnum.fromString(serializedContent); - } - activeTim.setDfContent(contentType); - + activeTim.setDfContent(ContentEnum.advisory); activeTims.add(activeTim); } } catch (Exception e) { @@ -169,16 +159,7 @@ public ResponseEntity GetUpdateModelFromActiveTimId(@PathVariabl activeTim.setFrameType(TravelerInfoType.advisory); } - // set dataFrame content. it's required for the ODE, so if we didn't record it, - // assume Advisory - String serializedContent = rs.getString("DF_CONTENT"); - ContentEnum contentType; - if (serializedContent == null || serializedContent.isEmpty()) { - contentType = ContentEnum.advisory; - } else { - contentType = ContentEnum.fromString(serializedContent); - } - activeTim.setDfContent(contentType); + activeTim.setDfContent(ContentEnum.advisory); } } catch (Exception e) { log.error("Error getting active tim", e); diff --git a/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/ActiveTimControllerTest.java b/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/ActiveTimControllerTest.java index 230ead5d3..bf3a2cb49 100644 --- a/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/ActiveTimControllerTest.java +++ b/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/ActiveTimControllerTest.java @@ -57,7 +57,7 @@ private void setupPreparedStatement() { public void GetExpiringActiveTims_SUCCESS() throws SQLException { // Arrange // we only set one property to verify its returned - when(mockRs.getLong("ACTIVE_TIM_ID")).thenReturn(999l); + when(mockRs.getLong("ACTIVE_TIM_ID")).thenReturn(999L); when(mockRs.getInt(any())).thenReturn(0); when(mockRs.getInt("FRAME_TYPE")).thenReturn(FrameType.TravelerInfoType.advisory.ordinal()); String selectStatement = "SELECT atim.*, tt.type as tim_type_name, tt.description as tim_type_description"; @@ -108,8 +108,7 @@ public void GetExpiringActiveTims_FAIL() throws SQLException { public void GetExpiringActiveTims_CorrectContentType() throws SQLException { // Arrange when(mockRs.getString(any())).thenReturn(""); - when(mockRs.getString("DF_CONTENT")).thenReturn("workZone"); - when(mockRs.getLong("ACTIVE_TIM_ID")).thenReturn(999l); + when(mockRs.getLong("ACTIVE_TIM_ID")).thenReturn(999L); // Act ResponseEntity> tums = uut.GetExpiringActiveTims(); @@ -117,14 +116,14 @@ public void GetExpiringActiveTims_CorrectContentType() throws SQLException { // Assert Assertions.assertEquals(HttpStatus.OK, tums.getStatusCode()); Assertions.assertEquals(1, tums.getBody().size()); - Assertions.assertEquals(ContentEnum.workZone, tums.getBody().get(0).getDfContent()); + Assertions.assertEquals(ContentEnum.advisory, tums.getBody().get(0).getDfContent()); } @Test public void GetUpdateModelFromActiveTimId_SUCCESS() throws SQLException { // Arrange // we only set one property to verify its returned - when(mockRs.getLong("ACTIVE_TIM_ID")).thenReturn(999l); + when(mockRs.getLong("ACTIVE_TIM_ID")).thenReturn(999L); when(mockRs.getInt(any())).thenReturn(0); when(mockRs.getInt("FRAME_TYPE")).thenReturn(FrameType.TravelerInfoType.advisory.ordinal()); @@ -140,10 +139,10 @@ public void GetUpdateModelFromActiveTimId_SUCCESS() throws SQLException { selectStatement += " LEFT JOIN data_frame df on atim.tim_id = df.tim_id"; selectStatement += " LEFT JOIN region r on df.data_frame_id = r.data_frame_id"; selectStatement += " LEFT JOIN tim_type tt ON atim.tim_type_id = tt.tim_type_id"; - selectStatement += " WHERE atim.active_tim_id = " + 999l; + selectStatement += " WHERE atim.active_tim_id = " + 999L; // Act - ResponseEntity tum = uut.GetUpdateModelFromActiveTimId(999l); + ResponseEntity tum = uut.GetUpdateModelFromActiveTimId(999L); // Assert Assertions.assertEquals(HttpStatus.OK, tum.getStatusCode()); @@ -159,7 +158,7 @@ public void GetUpdateModelFromActiveTimId_FAIL() throws SQLException { when(mockRs.getLong("ACTIVE_TIM_ID")).thenThrow(new SQLException()); // Act - ResponseEntity tum = uut.GetUpdateModelFromActiveTimId(999l); + ResponseEntity tum = uut.GetUpdateModelFromActiveTimId(999L); // Assert Assertions.assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, tum.getStatusCode()); @@ -172,16 +171,15 @@ public void GetUpdateModelFromActiveTimId_FAIL() throws SQLException { public void GetUpdateModelFromActiveTimId_CorrectContentType() throws SQLException { // Arrange when(mockRs.getString(any())).thenReturn(""); - when(mockRs.getString("DF_CONTENT")).thenReturn("workZone"); - when(mockRs.getLong("ACTIVE_TIM_ID")).thenReturn(999l); + when(mockRs.getLong("ACTIVE_TIM_ID")).thenReturn(999L); // Act - ResponseEntity tum = uut.GetUpdateModelFromActiveTimId(999l); + ResponseEntity tum = uut.GetUpdateModelFromActiveTimId(999L); // Assert Assertions.assertEquals(HttpStatus.OK, tum.getStatusCode()); Assertions.assertNotNull(tum.getBody()); - Assertions.assertEquals(ContentEnum.workZone, tum.getBody().getDfContent()); + Assertions.assertEquals(ContentEnum.advisory, tum.getBody().getDfContent()); } @Test @@ -191,7 +189,7 @@ public void UpdateActiveTim_SatRecordId_FAIL() { doReturn(false).when(mockDbInteractions).updateOrDelete(mockPreparedStatement); // Act - ResponseEntity success = uut.updateActiveTim_SatRecordId(-1l, "asdf"); + ResponseEntity success = uut.updateActiveTim_SatRecordId(-1L, "asdf"); // Assert Assertions.assertFalse(success.getBody(), "UpdateActiveTim_SatRecordId succeeded when it should have failed"); @@ -204,7 +202,7 @@ public void UpdateActiveTim_SatRecordId_SUCCESS() { doReturn(true).when(mockDbInteractions).updateOrDelete(mockPreparedStatement); // Act - ResponseEntity success = uut.updateActiveTim_SatRecordId(-1l, "asdf"); + ResponseEntity success = uut.updateActiveTim_SatRecordId(-1L, "asdf"); // Assert Assertions.assertTrue(success.getBody(), "UpdateActiveTim_SatRecordId failed when it should have succeeded"); @@ -216,7 +214,7 @@ public void UpdateActiveTim_SatRecordId_EXCEPTION() throws SQLException { doThrow(new SQLException()).when(mockDbInteractions).getConnectionPool(); // Act - ResponseEntity success = uut.updateActiveTim_SatRecordId(-1l, "asdf"); + ResponseEntity success = uut.updateActiveTim_SatRecordId(-1L, "asdf"); // Assert Assertions.assertFalse(success.getBody(), "UpdateActiveTim_SatRecordId was successful during an error"); @@ -429,7 +427,7 @@ public void GetActiveTimIndicesByRsu_FAIL() throws SQLException { public void GetActiveTimsByClientIdDirection_SUCCESS() throws SQLException { // Arrange String clientId = "clientId"; - Long timTypeId = -1l; + Long timTypeId = -1L; String direction = "eastward"; String selectStatement = "select * from active_tim where CLIENT_ID like '" + clientId + "' and TIM_TYPE_ID = " + timTypeId; selectStatement += " and DIRECTION = '" + direction + "'"; @@ -463,7 +461,7 @@ public void GetActiveTimsByClientIdDirection_SUCCESS() throws SQLException { public void GetActiveTimsByClientIdDirection_FAIL() throws SQLException { // Arrange String clientId = "clientId"; - Long timTypeId = -1l; + Long timTypeId = -1L; String direction = "eastward"; String selectStatement = "select * from active_tim where CLIENT_ID like '" + clientId + "' and TIM_TYPE_ID = " + timTypeId; selectStatement += " and DIRECTION = '" + direction + "'"; @@ -536,7 +534,7 @@ public void GetBufferTimsByClientId_FAIL() throws SQLException { @Test public void GetItisCodesForActiveTim_SUCCESS() throws SQLException { // Arrange - Long activeTimId = -1l; + Long activeTimId = -1L; String selectStatement = "select itis_code from active_tim "; selectStatement += "inner join tim on tim.tim_id = active_tim.tim_id "; selectStatement += "inner join data_frame on tim.tim_id = data_frame.tim_id "; @@ -560,7 +558,7 @@ public void GetItisCodesForActiveTim_SUCCESS() throws SQLException { @Test public void GetItisCodesForActiveTim_FAIL() throws SQLException { // Arrange - Long activeTimId = -1l; + Long activeTimId = -1L; String selectStatement = "select itis_code from active_tim inner join tim on tim.tim_id = active_tim.tim_id inner join data_frame on tim.tim_id = data_frame.tim_id inner join data_frame_itis_code on data_frame_itis_code.data_frame_id = data_frame.data_frame_id inner join itis_code on data_frame_itis_code.itis_code_id = itis_code.itis_code_id where active_tim_id = " + activeTimId + " order by data_frame_itis_code.position asc"; @@ -580,7 +578,7 @@ public void GetItisCodesForActiveTim_FAIL() throws SQLException { @Test public void DeleteActiveTim_SUCCESS() throws SQLException { // Arrange - Long activeTimId = -1l; + Long activeTimId = -1L; // Act ResponseEntity data = uut.DeleteActiveTim(activeTimId); @@ -596,7 +594,7 @@ public void DeleteActiveTim_SUCCESS() throws SQLException { @Test public void DeleteActiveTim_FAIL() throws SQLException { // Arrange - Long activeTimId = -1l; + Long activeTimId = -1L; doThrow(new SQLException()).when(mockPreparedStatement).setLong(1, activeTimId); // Act @@ -624,7 +622,7 @@ public void DeleteActiveTimsById_SUCCESS() throws SQLException { Assertions.assertEquals(HttpStatus.OK, data.getStatusCode()); Assertions.assertTrue(data.getBody(), "Fail return on success"); verify(mockConnection).prepareStatement("DELETE FROM ACTIVE_TIM WHERE ACTIVE_TIM_ID in (?)"); - verify(mockPreparedStatement).setLong(1, -1l); + verify(mockPreparedStatement).setLong(1, -1L); verify(mockPreparedStatement).close(); verify(mockConnection).close(); } @@ -634,7 +632,7 @@ public void DeleteActiveTimsById_FAIL() throws SQLException { // Arrange List activeTimIds = new ArrayList<>(); activeTimIds.add(Long.valueOf(-1)); - doThrow(new SQLException()).when(mockPreparedStatement).setLong(1, -1l); + doThrow(new SQLException()).when(mockPreparedStatement).setLong(1, -1L); // Act ResponseEntity data = uut.DeleteActiveTimsById(activeTimIds); @@ -653,7 +651,7 @@ public void GetActiveTimsByIds_SUCCESS() throws SQLException { String query = "select * from active_tim where active_tim_id in (?, ?)"; // Act - var response = uut.GetActiveTimsByIds(Arrays.asList(-1l, -2l)); + var response = uut.GetActiveTimsByIds(Arrays.asList(-1L, -2L)); // Assert Assertions.assertEquals(HttpStatus.OK, response.getStatusCode()); @@ -666,10 +664,10 @@ public void GetActiveTimsByIds_SUCCESS() throws SQLException { public void GetActiveTimsByIds_FAIL() throws SQLException { // Arrange String query = "select * from active_tim where active_tim_id in (?, ?)"; - doThrow(new SQLException()).when(mockPreparedStatement).setLong(1, -1l); + doThrow(new SQLException()).when(mockPreparedStatement).setLong(1, -1L); // Act - var response = uut.GetActiveTimsByIds(Arrays.asList(-1l, -2l)); + var response = uut.GetActiveTimsByIds(Arrays.asList(-1L, -2L)); // Assert Assertions.assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode()); @@ -697,7 +695,7 @@ public void GetActiveTimsByWydotTim_SUCCESS() throws SQLException { wydotTim.setClientId("clientId"); wydotTim.setDirection("westward"); wydotTims.add(wydotTim); - Long timTypeId = -1l; + Long timTypeId = -1L; String query = "select * from active_tim where TIM_TYPE_ID = ? and ((CLIENT_ID like ? and DIRECTION = ?))"; // Act @@ -735,7 +733,7 @@ public void GetActiveTimsByWydotTim_BothDirections() throws SQLException { wydotTim.setClientId("clientId"); wydotTim.setDirection("B"); wydotTims.add(wydotTim); - Long timTypeId = -1l; + Long timTypeId = -1L; String query = "select * from active_tim where TIM_TYPE_ID = ? and ((CLIENT_ID like ?))"; // Act @@ -772,7 +770,7 @@ public void GetActiveTimsByWydotTim_FAIL() throws SQLException { wydotTim.setClientId("clientId"); wydotTim.setDirection("westward"); wydotTims.add(wydotTim); - Long timTypeId = -1l; + Long timTypeId = -1L; String query = "select * from active_tim where TIM_TYPE_ID = ? and ((CLIENT_ID like ? and DIRECTION = ?))"; doThrow(new SQLException()).when(mockPreparedStatement).setLong(1, timTypeId); @@ -790,7 +788,7 @@ public void GetActiveTimsByWydotTim_FAIL() throws SQLException { @Test public void GetActivesTimByType_SUCCESS() throws SQLException { // Arrange - Long timTypeId = -1l; + Long timTypeId = -1L; String query = "select * from active_tim where TIM_TYPE_ID = " + timTypeId; // Act @@ -822,7 +820,7 @@ public void GetActivesTimByType_SUCCESS() throws SQLException { @Test public void GetActivesTimByType_FAIL() throws SQLException { // Arrange - Long timTypeId = -1l; + Long timTypeId = -1L; String query = "select * from active_tim where TIM_TYPE_ID = " + timTypeId; doThrow(new SQLException()).when(mockRs).getLong("ACTIVE_TIM_ID"); @@ -1187,7 +1185,7 @@ public void ResetExpirationDate_SUCCESS() throws SQLException { Assertions.assertEquals(HttpStatus.OK, data.getStatusCode()); Assertions.assertTrue(data.getBody(), "Fail return on success"); verify(mockConnection).prepareStatement("UPDATE ACTIVE_TIM SET EXPIRATION_DATE = NULL WHERE ACTIVE_TIM_ID IN (?)"); - verify(mockPreparedStatement).setLong(1, -1l); + verify(mockPreparedStatement).setLong(1, -1L); verify(mockPreparedStatement).close(); verify(mockConnection).close(); } @@ -1237,7 +1235,7 @@ public void ResetExpirationDate_FAIL() throws SQLException { // Arrange List activeTimIds = new ArrayList<>(); activeTimIds.add(Long.valueOf(-1)); - doThrow(new SQLException()).when(mockPreparedStatement).setLong(1, -1l); + doThrow(new SQLException()).when(mockPreparedStatement).setLong(1, -1L); // Act ResponseEntity data = uut.ResetExpirationDate(activeTimIds); diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CreateBaseTimUtil.java b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CreateBaseTimUtil.java index 52174c1f5..c4803fb89 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CreateBaseTimUtil.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CreateBaseTimUtil.java @@ -42,16 +42,17 @@ public void InjectDependencies(Utility _utility) { * * @param wydotTim The WydotTim object containing the data for the TIM. * @param genProps The TimGenerationProps object containing the generation properties. - * @param content The ContentEnum object representing the content of the TIM. * @param frameType The TravelerInfoType object representing the frame type of the TIM. * @param allMileposts The list of Milepost objects representing all mileposts. * @param reducedMileposts The list of Milepost objects representing reduced mileposts. * @param anchor The Milepost object representing the anchor milepost. * @return The WydotTravelerInputData object containing the built TIM. */ - public WydotTravelerInputData buildTim(WydotTim wydotTim, TimGenerationProps genProps, ContentEnum content, + public WydotTravelerInputData buildTim(WydotTim wydotTim, TimGenerationProps genProps, TravelerInfoType frameType, List allMileposts, List reducedMileposts, Milepost anchor) { + ContentEnum content = ContentEnum.advisory; + // build TIM object with data WydotTravelerInputData timToSend = new WydotTravelerInputData(); OdeTravelerInformationMessage tim = new OdeTravelerInformationMessage(); @@ -83,7 +84,7 @@ public WydotTravelerInputData buildTim(WydotTim wydotTim, TimGenerationProps gen anchorPosition.setLongitude(anchor.getLongitude()); // build msgId - MsgId msgId = buildMsgId(anchorPosition, content, frameType); + MsgId msgId = buildMsgId(anchorPosition, frameType); dataFrame.setMsgId(msgId); // set regions. note that we now support multiple regions in a single TIM package @@ -195,7 +196,7 @@ protected OdeTravelerInformationMessage.DataFrame.Region buildSingleRegion(BigDe region.setDirection(directionString); // heading slice // set path nodes - if (reducedMileposts != null && reducedMileposts.size() > 0) { + if (reducedMileposts != null && !reducedMileposts.isEmpty()) { OdeTravelerInformationMessage.NodeXY[] nodes = buildNodePathFromMileposts(reducedMileposts, anchor); OdeTravelerInformationMessage.DataFrame.Region.Path path = new OdeTravelerInformationMessage.DataFrame.Region.Path(); path.setScale(0); @@ -243,7 +244,7 @@ public String buildHeadingSliceFromMileposts(List allMileposts, OdePos int timDirection = 0; // this is a regular tim, so we need to set the direction normally // path list - change later - if (allMileposts != null && allMileposts.size() > 0) { + if (allMileposts != null && !allMileposts.isEmpty()) { double startLat = anchorPosition.getLatitude().doubleValue(); double startLon = anchorPosition.getLongitude().doubleValue(); for (int j = 0; j < allMileposts.size(); j++) { @@ -271,18 +272,17 @@ public String buildHeadingSliceFromMileposts(List allMileposts, OdePos * Builds a message ID based on the provided anchor position, content, and frame type. * * @param anchorPosition The anchor position for the road sign. - * @param content The content of the message. * @param frameType The type of the frame. * @return The built message ID. */ - protected MsgId buildMsgId(OdePosition3D anchorPosition, ContentEnum content, TravelerInfoType frameType) { + protected MsgId buildMsgId(OdePosition3D anchorPosition, TravelerInfoType frameType) { MsgId msgId = new MsgId(); RoadSignID roadSignID = new RoadSignID(); roadSignID.setPosition(anchorPosition); - // if we are coming in with content=speedLimit and frameType=roadSignage, + // if we are coming in with frameType=roadSignage, // we need to set the mutcdCode to regulatory to display the regulatory signage - if (content == ContentEnum.speedLimit && frameType == TravelerInfoType.roadSignage) { + if (frameType == TravelerInfoType.roadSignage) { roadSignID.setMutcdCode(MutcdCodeEnum.regulatory); } else { roadSignID.setMutcdCode(MutcdCodeEnum.warning); diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/JsonToJavaConverter.java b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/JsonToJavaConverter.java index 533a82bfd..f7b545a90 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/JsonToJavaConverter.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/JsonToJavaConverter.java @@ -12,10 +12,8 @@ import java.util.Map; import org.springframework.stereotype.Component; -import java.util.Map; import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationFeature; @@ -33,8 +31,6 @@ 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.J2735SpecialVehicleExtensions; -import us.dot.its.jpo.ode.plugin.j2735.J2735SupplementalVehicleExtensions; 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.OdeTravelerInformationMessage.DataFrame.Region; @@ -261,16 +257,16 @@ public OdeTimPayload convertTimPayloadJsonToJava(String value) { dataFrame.setContent(ContentEnum.advisory.getStringValue()); } else if (contentNode.has(ContentEnum.speedLimit.getStringValue())) { sequenceArrNode = contentNode.get(ContentEnum.speedLimit.getStringValue()).get("SEQUENCE"); - dataFrame.setContent(ContentEnum.speedLimit.getStringValue()); + dataFrame.setContent(ContentEnum.advisory.getStringValue()); } else if (contentNode.has(ContentEnum.exitService.getStringValue())) { sequenceArrNode = contentNode.get(ContentEnum.exitService.getStringValue()).get("SEQUENCE"); - dataFrame.setContent(ContentEnum.exitService.getStringValue()); + dataFrame.setContent(ContentEnum.advisory.getStringValue()); } else if (contentNode.has(ContentEnum.genericSign.getStringValue())) { sequenceArrNode = contentNode.get(ContentEnum.genericSign.getStringValue()).get("SEQUENCE"); - dataFrame.setContent(ContentEnum.genericSign.getStringValue()); + dataFrame.setContent(ContentEnum.advisory.getStringValue()); } else if (contentNode.has(ContentEnum.workZone.getStringValue())) { sequenceArrNode = contentNode.get(ContentEnum.workZone.getStringValue()).get("SEQUENCE"); - dataFrame.setContent(ContentEnum.workZone.getStringValue()); + dataFrame.setContent(ContentEnum.advisory.getStringValue()); } LocalDate now = LocalDate.now(); @@ -480,16 +476,16 @@ public OdeTimPayload convertTmcTimTopicJsonToJava(String value) { dataFrame.setContent(ContentEnum.advisory.getStringValue()); } else if (contentNode.has(ContentEnum.speedLimit.getStringValue())) { sequenceArrNode = contentNode.get("speedLimit"); - dataFrame.setContent(ContentEnum.speedLimit.getStringValue()); + dataFrame.setContent(ContentEnum.advisory.getStringValue()); } else if (contentNode.has(ContentEnum.exitService.getStringValue())) { sequenceArrNode = contentNode.get("exitService"); - dataFrame.setContent(ContentEnum.exitService.getStringValue()); + dataFrame.setContent(ContentEnum.advisory.getStringValue()); } else if (contentNode.has(ContentEnum.genericSign.getStringValue())) { sequenceArrNode = contentNode.get("genericSign"); - dataFrame.setContent(ContentEnum.genericSign.getStringValue()); + dataFrame.setContent(ContentEnum.advisory.getStringValue()); } else if (contentNode.has(ContentEnum.workZone.getStringValue())) { sequenceArrNode = contentNode.get("workZone"); - dataFrame.setContent(ContentEnum.workZone.getStringValue()); + dataFrame.setContent(ContentEnum.advisory.getStringValue()); } List itemsList = new ArrayList<>(); diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java b/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java index 2e8aea117..120d4829e 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java @@ -30,7 +30,6 @@ import com.trihydro.library.model.ActiveRsuTimQueryModel; import com.trihydro.library.model.ActiveTim; import com.trihydro.library.model.ActiveTimHolding; -import com.trihydro.library.model.ContentEnum; import com.trihydro.library.model.Coordinate; import com.trihydro.library.model.EmailProps; import com.trihydro.library.model.Milepost; @@ -115,11 +114,11 @@ public void InjectDependencies(EmailProps _emailProps, OdeProps _odeProps, TimGe DateTimeFormatter utcformatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); public WydotTravelerInputData createTim(WydotTim wydotTim, String timTypeStr, String startDateTime, - String endDateTime, ContentEnum content, TravelerInfoType frameType, List allMileposts, + String endDateTime, TravelerInfoType frameType, List allMileposts, List reducedMileposts, Milepost anchor, String dotGnisId) { // build base TIM - WydotTravelerInputData timToSend = createBaseTimUtil.buildTim(wydotTim, genProps, content, frameType, + WydotTravelerInputData timToSend = createBaseTimUtil.buildTim(wydotTim, genProps, frameType, allMileposts, reducedMileposts, anchor); if (timToSend == null) { @@ -277,7 +276,7 @@ public void sendTimToRsus(WydotTim wydotTim, WydotTravelerInputData timToSend, S } // if no RSUs found - if (rsus.size() == 0) { + if (rsus.isEmpty()) { utility.logWithDate("No RSUs found to place TIM on, returning"); return; } @@ -419,7 +418,7 @@ public TimDeleteSummary deleteTimsFromRsusAndSdx(List activeTims) { List timRsus = timRsuService.getTimRsusByTimId(activeTim.getTimId()); // get full RSU - if (timRsus.size() > 0) { + if (!timRsus.isEmpty()) { for (TimRsu timRsu : timRsus) { rsu = getRsu(timRsu.getRsuId()); // delete tim off rsu @@ -438,7 +437,7 @@ public TimDeleteSummary deleteTimsFromRsusAndSdx(List activeTims) { } } - if (satTims != null && satTims.size() > 0) { + if (satTims != null && !satTims.isEmpty()) { // Get the sat_record_id values and active_tim_id values List satRecordIds = satTims.stream().map(ActiveTim::getSatRecordId).collect(Collectors.toList()); List activeSatTimIds = satTims.stream().map(ActiveTim::getActiveTimId).collect(Collectors.toList()); diff --git a/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CreateBaseTimUtilTest.java b/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CreateBaseTimUtilTest.java index 1a445ef04..07f8f1907 100644 --- a/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CreateBaseTimUtilTest.java +++ b/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CreateBaseTimUtilTest.java @@ -4,7 +4,6 @@ import java.util.ArrayList; import java.util.List; -import com.trihydro.library.model.ContentEnum; import com.trihydro.library.model.Coordinate; import com.trihydro.library.model.Milepost; import com.trihydro.library.model.WydotTim; @@ -106,11 +105,10 @@ public void buildTim_EndpointSUCCESS() { wydotTim.setItisCodes(itisCodes); wydotTim.setClientId("testclientid"); - var content = ContentEnum.advisory; var frameType = TravelerInfoType.advisory; // Act - var data = uut.buildTim(wydotTim, genProps, content, frameType, allMileposts, milepostsReduced, anchor); + var data = uut.buildTim(wydotTim, genProps, frameType, allMileposts, milepostsReduced, anchor); // Assert // validate dataFrame @@ -155,11 +153,10 @@ public void buildTim_singlePointSUCCESS() { wydotTim.setItisCodes(itisCodes); wydotTim.setClientId("testclientid"); - var content = ContentEnum.advisory; var frameType = TravelerInfoType.advisory; // Act - var data = uut.buildTim(wydotTim, genProps, content, frameType, allMileposts, milepostsReduced, anchor); + var data = uut.buildTim(wydotTim, genProps, frameType, allMileposts, milepostsReduced, anchor); // Assert // validate dataFrame @@ -204,11 +201,10 @@ public void buildTim_singleRegion_SUCCESS() { wydotTim.setItisCodes(itisCodes); wydotTim.setClientId("testclientid"); - var content = ContentEnum.advisory; var frameType = TravelerInfoType.advisory; // Act - var data = uut.buildTim(wydotTim, genProps, content, frameType, allMileposts, milepostsReduced, anchor); + var data = uut.buildTim(wydotTim, genProps, frameType, allMileposts, milepostsReduced, anchor); // Assert Assertions.assertEquals(1, data.getTim().getDataframes()[0].getRegions().length); @@ -235,11 +231,10 @@ public void buildTim_twoRegions_SUCCESS() { wydotTim.setItisCodes(itisCodes); wydotTim.setClientId("testclientid"); - var content = ContentEnum.advisory; var frameType = TravelerInfoType.advisory; // Act - var data = uut.buildTim(wydotTim, genProps, content, frameType, allMileposts, milepostsReduced, anchor); + var data = uut.buildTim(wydotTim, genProps, frameType, allMileposts, milepostsReduced, anchor); // Assert Assertions.assertEquals(2, data.getTim().getDataframes()[0].getRegions().length); @@ -278,11 +273,10 @@ public void buildTim_threeRegions_SUCCESS() { wydotTim.setItisCodes(itisCodes); wydotTim.setClientId("testclientid"); - var content = ContentEnum.advisory; var frameType = TravelerInfoType.advisory; // Act - var data = uut.buildTim(wydotTim, genProps, content, frameType, allMileposts, milepostsReduced, anchor); + var data = uut.buildTim(wydotTim, genProps, frameType, allMileposts, milepostsReduced, anchor); // Assert Assertions.assertEquals(3, data.getTim().getDataframes()[0].getRegions().length); diff --git a/cv-data-service-library/src/test/java/com/trihydro/library/helpers/JsonToJavaConverterTest.java b/cv-data-service-library/src/test/java/com/trihydro/library/helpers/JsonToJavaConverterTest.java index e89ca7501..9a36e171d 100644 --- a/cv-data-service-library/src/test/java/com/trihydro/library/helpers/JsonToJavaConverterTest.java +++ b/cv-data-service-library/src/test/java/com/trihydro/library/helpers/JsonToJavaConverterTest.java @@ -252,7 +252,7 @@ public void TestConvertTimPayloadJsonToJava_SpeedLimit() throws IOException, URI // Assert Assertions.assertNotNull(odeTimPayloadTest); Assertions.assertTrue(getTim(odeTimPayloadTest).getDataframes()[0].getItems().length > 0); - Assertions.assertEquals("speedLimit", getTim(odeTimPayloadTest).getDataframes()[0].getContent()); + Assertions.assertEquals("advisory", getTim(odeTimPayloadTest).getDataframes()[0].getContent()); Assertions.assertArrayEquals(new String[] { "13609", "268", "12554", "8720" }, getTim(odeTimPayloadTest).getDataframes()[0].getItems()); } @@ -388,7 +388,7 @@ public void TestConvertTmcTimTopicJsonToJava_HandlesVslContentType() throws IOEx // Assert Assertions.assertNotNull(tim_vsl); - Assertions.assertEquals("speedLimit", getTim(tim_vsl).getDataframes()[0].getContent()); + Assertions.assertEquals("advisory", getTim(tim_vsl).getDataframes()[0].getContent()); Assertions.assertArrayEquals(new String[] { "268", "12604", "8720" }, getTim(tim_vsl).getDataframes()[0].getItems()); @@ -406,7 +406,7 @@ public void TestConvertTmcTimTopicJsonToJava_HandlesVslContentType_MultipleRegio // Assert Assertions.assertNotNull(tim_vsl); - Assertions.assertEquals("speedLimit", getTim(tim_vsl).getDataframes()[0].getContent()); + Assertions.assertEquals("advisory", getTim(tim_vsl).getDataframes()[0].getContent()); Assertions.assertArrayEquals(new String[] { "268", "12604", "8720" }, getTim(tim_vsl).getDataframes()[0].getItems()); @@ -424,7 +424,7 @@ public void TestConvertTmcTimTopicJsonToJava_HandlesParkingContentType() throws // Assert Assertions.assertNotNull(tim_parking); - Assertions.assertEquals("exitService", getTim(tim_parking).getDataframes()[0].getContent()); + Assertions.assertEquals("advisory", getTim(tim_parking).getDataframes()[0].getContent()); Assertions.assertArrayEquals(new String[] { "4104", "11794", "345" }, getTim(tim_parking).getDataframes()[0].getItems()); @@ -442,7 +442,7 @@ public void TestConvertTmcTimTopicJsonToJava_HandlesParkingContentType_MultipleR // Assert Assertions.assertNotNull(tim_parking); - Assertions.assertEquals("exitService", getTim(tim_parking).getDataframes()[0].getContent()); + Assertions.assertEquals("advisory", getTim(tim_parking).getDataframes()[0].getContent()); Assertions.assertArrayEquals(new String[] { "4104", "11794", "345" }, getTim(tim_parking).getDataframes()[0].getItems()); @@ -461,7 +461,7 @@ public void TestConvertTmcTimTopicJsonToJava_HandlesConstructionContentType() th // Assert Assertions.assertNotNull(tim_construction); - Assertions.assertEquals("workZone", getTim(tim_construction).getDataframes()[0].getContent()); + Assertions.assertEquals("advisory", getTim(tim_construction).getDataframes()[0].getContent()); Assertions.assertArrayEquals(new String[] { "1537", "12554", "8728" }, getTim(tim_construction).getDataframes()[0].getItems()); @@ -480,7 +480,7 @@ public void TestConvertTmcTimTopicJsonToJava_HandlesConstructionContentType_Mult // Assert Assertions.assertNotNull(tim_construction); - Assertions.assertEquals("workZone", getTim(tim_construction).getDataframes()[0].getContent()); + Assertions.assertEquals("advisory", getTim(tim_construction).getDataframes()[0].getContent()); Assertions.assertArrayEquals(new String[] { "1537", "12554", "8728" }, getTim(tim_construction).getDataframes()[0].getItems()); diff --git a/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java b/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java index ad4cb8f33..9a202f877 100644 --- a/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java +++ b/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java @@ -15,9 +15,6 @@ import java.io.IOException; import java.math.BigDecimal; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -48,7 +45,6 @@ import com.trihydro.library.helpers.TimGenerationHelper; import com.trihydro.library.helpers.Utility; import com.trihydro.library.model.ActiveTim; -import com.trihydro.library.model.ContentEnum; import com.trihydro.library.model.Coordinate; import com.trihydro.library.model.EmailProps; import com.trihydro.library.model.Milepost; @@ -125,18 +121,18 @@ private List getActiveTims(boolean isSat) { List activeTims = new ArrayList(); ActiveTim aTim = new ActiveTim(); ActiveTim aTim2 = new ActiveTim(); - aTim.setActiveTimId(-1l); - aTim2.setActiveTimId(-2l); + aTim.setActiveTimId(-1L); + aTim2.setActiveTimId(-2L); if (isSat) { aTim.setSatRecordId("C27CBB9F"); aTim2.setSatRecordId("86E03786"); } else { aTim.setStartPoint(new Coordinate(BigDecimal.valueOf(1), BigDecimal.valueOf(2))); aTim.setEndPoint(new Coordinate(BigDecimal.valueOf(3), BigDecimal.valueOf(4))); - aTim.setTimId(-10l); + aTim.setTimId(-10L); aTim2.setStartPoint(new Coordinate(BigDecimal.valueOf(5), BigDecimal.valueOf(6))); aTim2.setEndPoint(new Coordinate(BigDecimal.valueOf(7), BigDecimal.valueOf(8))); - aTim2.setTimId(-20l); + aTim2.setTimId(-20L); } activeTims.add(aTim); activeTims.add(aTim2); @@ -227,17 +223,16 @@ public void createTim_ReturnsNull_WhenBuildTimReturnsNull() { String timTypeStr = "A"; String startDateTime = "2023-01-01T00:00:00.000Z"; String endDateTime = "2023-01-01T01:00:00.000Z"; - ContentEnum content = ContentEnum.workZone; TravelerInfoType frameType = TravelerInfoType.advisory; List allMileposts = new ArrayList<>(); List reducedMileposts = new ArrayList<>(); Milepost anchor = new Milepost(); String dotGnisId = "1B2843"; - when(mockCreateBaseTimUtil.buildTim(any(), any(), any(), any(), any(), any(), any())).thenReturn(null); + when(mockCreateBaseTimUtil.buildTim(any(), any(), any(), any(), any(), any())).thenReturn(null); // Act - WydotTravelerInputData result = uut.createTim(new WydotTim(), timTypeStr, startDateTime, endDateTime, content, frameType, allMileposts, reducedMileposts, anchor, dotGnisId); + WydotTravelerInputData result = uut.createTim(new WydotTim(), timTypeStr, startDateTime, endDateTime, frameType, allMileposts, reducedMileposts, anchor, dotGnisId); // Assert assertNull(result); @@ -249,7 +244,6 @@ public void createTim_SetsStartDateTime_WhenProvided() { String timTypeStr = "A"; String startDateTime = "2023-01-01T00:00:00.000Z"; String endDateTime = "2023-01-01T01:00:00.000Z"; - ContentEnum content = ContentEnum.workZone; TravelerInfoType frameType = TravelerInfoType.advisory; List allMileposts = new ArrayList<>(); List reducedMileposts = new ArrayList<>(); @@ -258,10 +252,10 @@ public void createTim_SetsStartDateTime_WhenProvided() { WydotTravelerInputData timToSend = getMockWydotTravelerInputDataWithDataFrame(); - when(mockCreateBaseTimUtil.buildTim(any(), any(), any(), any(), any(), any(), any())).thenReturn(timToSend); + when(mockCreateBaseTimUtil.buildTim(any(), any(), any(), any(), any(), any())).thenReturn(timToSend); // Act - WydotTravelerInputData result = uut.createTim(new WydotTim(), timTypeStr, startDateTime, endDateTime, content, frameType, allMileposts, reducedMileposts, anchor, dotGnisId); + WydotTravelerInputData result = uut.createTim(new WydotTim(), timTypeStr, startDateTime, endDateTime, frameType, allMileposts, reducedMileposts, anchor, dotGnisId); // Assert assertEquals(startDateTime, result.getTim().getDataframes()[0].getStartDateTime()); @@ -273,7 +267,6 @@ public void createTim_SetsDurationTime_WhenEndDateTimeProvided() { String timTypeStr = "A"; String startDateTime = "2023-01-01T00:00:00.000Z"; String endDateTime = "2023-01-01T01:00:00.000Z"; - ContentEnum content = ContentEnum.workZone; TravelerInfoType frameType = TravelerInfoType.advisory; List allMileposts = new ArrayList<>(); List reducedMileposts = new ArrayList<>(); @@ -282,11 +275,11 @@ public void createTim_SetsDurationTime_WhenEndDateTimeProvided() { WydotTravelerInputData timToSend = getMockWydotTravelerInputDataWithDataFrame(); - when(mockCreateBaseTimUtil.buildTim(any(), any(), any(), any(), any(), any(), any())).thenReturn(timToSend); + when(mockCreateBaseTimUtil.buildTim(any(), any(), any(), any(), any(), any())).thenReturn(timToSend); when(mockUtility.getMinutesDurationBetweenTwoDates(anyString(), anyString())).thenReturn(60); // Act - WydotTravelerInputData result = uut.createTim(new WydotTim(), timTypeStr, startDateTime, endDateTime, content, frameType, allMileposts, reducedMileposts, anchor, dotGnisId); + WydotTravelerInputData result = uut.createTim(new WydotTim(), timTypeStr, startDateTime, endDateTime, frameType, allMileposts, reducedMileposts, anchor, dotGnisId); // Assert assertEquals(60, result.getTim().getDataframes()[0].getDurationTime()); @@ -298,7 +291,6 @@ public void createTim_SetsDurationTimeTo120_ForParkingTim() { String timTypeStr = "P"; String startDateTime = "2023-01-01T00:00:00.000Z"; String endDateTime = "2023-01-01T01:00:00.000Z"; - ContentEnum content = ContentEnum.workZone; TravelerInfoType frameType = TravelerInfoType.advisory; List allMileposts = new ArrayList<>(); List reducedMileposts = new ArrayList<>(); @@ -307,10 +299,10 @@ public void createTim_SetsDurationTimeTo120_ForParkingTim() { WydotTravelerInputData timToSend = getMockWydotTravelerInputDataWithDataFrame(); - when(mockCreateBaseTimUtil.buildTim(any(), any(), any(), any(), any(), any(), any())).thenReturn(timToSend); + when(mockCreateBaseTimUtil.buildTim(any(), any(), any(), any(), any(), any())).thenReturn(timToSend); // Act - WydotTravelerInputData result = uut.createTim(new WydotTim(), timTypeStr, startDateTime, endDateTime, content, frameType, allMileposts, reducedMileposts, anchor, dotGnisId); + WydotTravelerInputData result = uut.createTim(new WydotTim(), timTypeStr, startDateTime, endDateTime, frameType, allMileposts, reducedMileposts, anchor, dotGnisId); // Assert assertEquals(120, result.getTim().getDataframes()[0].getDurationTime()); @@ -322,7 +314,6 @@ public void createTim_SetsRandomPacketIdWithGnisIdPrefix() { String timTypeStr = "A"; String startDateTime = "2023-01-01T00:00:00.000Z"; String endDateTime = "2023-01-01T01:00:00.000Z"; - ContentEnum content = ContentEnum.workZone; TravelerInfoType frameType = TravelerInfoType.advisory; List allMileposts = new ArrayList<>(); List reducedMileposts = new ArrayList<>(); @@ -331,10 +322,10 @@ public void createTim_SetsRandomPacketIdWithGnisIdPrefix() { WydotTravelerInputData timToSend = getMockWydotTravelerInputDataWithDataFrame(); - when(mockCreateBaseTimUtil.buildTim(any(), any(), any(), any(), any(), any(), any())).thenReturn(timToSend); + when(mockCreateBaseTimUtil.buildTim(any(), any(), any(), any(), any(), any())).thenReturn(timToSend); // Act - WydotTravelerInputData result = uut.createTim(new WydotTim(), timTypeStr, startDateTime, endDateTime, content, frameType, allMileposts, reducedMileposts, anchor, dotGnisId); + WydotTravelerInputData result = uut.createTim(new WydotTim(), timTypeStr, startDateTime, endDateTime, frameType, allMileposts, reducedMileposts, anchor, dotGnisId); // Assert assertNotNull(result.getTim().getPacketID()); @@ -349,7 +340,6 @@ public void createTim_ThrowsExceptionPacketIdUnsetGNISId() { String timTypeStr = "A"; String startDateTime = "2023-01-01T00:00:00.000Z"; String endDateTime = "2023-01-01T01:00:00.000Z"; - ContentEnum content = ContentEnum.workZone; TravelerInfoType frameType = TravelerInfoType.advisory; List allMileposts = new ArrayList<>(); List reducedMileposts = new ArrayList<>(); @@ -358,11 +348,11 @@ public void createTim_ThrowsExceptionPacketIdUnsetGNISId() { WydotTravelerInputData timToSend = getMockWydotTravelerInputDataWithDataFrame(); - when(mockCreateBaseTimUtil.buildTim(any(), any(), any(), any(), any(), any(), any())).thenReturn(timToSend); + when(mockCreateBaseTimUtil.buildTim(any(), any(), any(), any(), any(), any())).thenReturn(timToSend); // Act & Assert assertThrows(IllegalStateException.class, () -> { - uut.createTim(new WydotTim(), timTypeStr, startDateTime, endDateTime, content, frameType, allMileposts, reducedMileposts, anchor, dotGnisId); + uut.createTim(new WydotTim(), timTypeStr, startDateTime, endDateTime, frameType, allMileposts, reducedMileposts, anchor, dotGnisId); }); } @@ -580,11 +570,11 @@ public void deleteTimsFromRsusAndSdx_Rsu() { List activeTims = getActiveTims(false); List timRsus = new ArrayList<>(); TimRsu timRsu = new TimRsu(); - timRsu.setRsuId(-10l); + timRsu.setRsuId(-10L); timRsu.setRsuIndex(-1); timRsus.add(timRsu); - when(mockTimRsuService.getTimRsusByTimId(-10l)).thenReturn(new ArrayList<>()); - when(mockTimRsuService.getTimRsusByTimId(-20l)).thenReturn(timRsus); + when(mockTimRsuService.getTimRsusByTimId(-10L)).thenReturn(new ArrayList<>()); + when(mockTimRsuService.getTimRsusByTimId(-20L)).thenReturn(timRsus); ArrayList allRsus = new ArrayList<>(); WydotRsu wydotRsu = new WydotRsu(); wydotRsu.setRsuId(-10); @@ -600,8 +590,8 @@ public void deleteTimsFromRsusAndSdx_Rsu() { var result = uut.deleteTimsFromRsusAndSdx(activeTims); // Assert - verify(mockActiveTimService).deleteActiveTim(-1l); - verify(mockActiveTimService).deleteActiveTim(-2l); + verify(mockActiveTimService).deleteActiveTim(-1L); + verify(mockActiveTimService).deleteActiveTim(-2L); Assertions.assertEquals(result.getSuccessfulRsuDeletions().size(), 2); } @@ -624,7 +614,7 @@ public void deleteTimsFromRsusAndSdx_Sdx() throws MailException, MessagingExcept // Assert verify(mockEmailHelper).SendEmail(mockEmailProps.getAlertAddresses(), subject, body); List delIds = new ArrayList(); - delIds.add(-2l); + delIds.add(-2L); verify(mockActiveTimService).deleteActiveTimsById(delIds); verify(mockTimRsuService, never()).getTimRsusByTimId(isA(Long.class)); Assertions.assertEquals(1, result.getSuccessfulSatelliteDeletions().size()); @@ -644,8 +634,8 @@ public void deleteTimsFromRsusAndSdx_SdxNullValueInMap() throws MailException, M // Assert List delIds = new ArrayList(); - delIds.add(-1l); - delIds.add(-2l); + delIds.add(-1L); + delIds.add(-2L); verify(mockActiveTimService).deleteActiveTimsById(delIds); } @@ -655,11 +645,11 @@ public void deleteTimsFromRsusAndSdx_Exceptions() { List activeTims = getActiveTims(false); List timRsus = new ArrayList<>(); TimRsu timRsu = new TimRsu(); - timRsu.setRsuId(-10l); + timRsu.setRsuId(-10L); timRsu.setRsuIndex(-1); timRsus.add(timRsu); - when(mockTimRsuService.getTimRsusByTimId(-10l)).thenReturn(new ArrayList<>()); - when(mockTimRsuService.getTimRsusByTimId(-20l)).thenReturn(timRsus); + when(mockTimRsuService.getTimRsusByTimId(-10L)).thenReturn(new ArrayList<>()); + when(mockTimRsuService.getTimRsusByTimId(-20L)).thenReturn(timRsus); ArrayList allRsus = new ArrayList<>(); WydotRsu wydotRsu = new WydotRsu(); wydotRsu.setRsuId(-10); @@ -675,8 +665,8 @@ public void deleteTimsFromRsusAndSdx_Exceptions() { var result = uut.deleteTimsFromRsusAndSdx(activeTims); // Assert - verify(mockActiveTimService).deleteActiveTim(-1l); - verify(mockActiveTimService).deleteActiveTim(-2l); + verify(mockActiveTimService).deleteActiveTim(-1L); + verify(mockActiveTimService).deleteActiveTim(-2L); List timRsuJson = new ArrayList(); Gson gson = new Gson(); for (TimRsu tr : timRsus) { @@ -978,6 +968,6 @@ public void setBufferItisCodes_unrecognizedAction() { Integer[] result = uut.setBufferItisCodes(action); // Assert - Assertions.assertEquals(null, result); + Assertions.assertNull(result); } } \ No newline at end of file diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java index 9e24d4130..093b3c88c 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java @@ -23,7 +23,6 @@ import com.trihydro.library.helpers.Utility; import com.trihydro.library.model.ActiveTim; import com.trihydro.library.model.Buffer; -import com.trihydro.library.model.ContentEnum; import com.trihydro.library.model.Coordinate; import com.trihydro.library.model.Milepost; import com.trihydro.library.model.TimType; @@ -637,8 +636,7 @@ protected ControllerResult validateInputBowr(WydotTimBowr tim) { } public void processRequest(WydotTim wydotTim, TimType timType, String startDateTime, - String endDateTime, Integer pk, ContentEnum content, - TravelerInfoType frameType) { + String endDateTime, Integer pk, TravelerInfoType frameType) { if (wydotTim.getDirection().equalsIgnoreCase("b")) { var iTim = wydotTim.copy(); @@ -646,14 +644,11 @@ public void processRequest(WydotTim wydotTim, TimType timType, String startDateT iTim.setDirection("I"); dTim.setDirection("D"); // I - expireReduceCreateSendTims(iTim, timType, startDateTime, endDateTime, pk, content, - frameType); + expireReduceCreateSendTims(iTim, timType, startDateTime, endDateTime, pk, frameType); // D - expireReduceCreateSendTims(dTim, timType, startDateTime, endDateTime, pk, content, - frameType); + expireReduceCreateSendTims(dTim, timType, startDateTime, endDateTime, pk, frameType); } else { - expireReduceCreateSendTims(wydotTim, timType, startDateTime, endDateTime, pk, content, - frameType); + expireReduceCreateSendTims(wydotTim, timType, startDateTime, endDateTime, pk, frameType); } } @@ -682,7 +677,7 @@ public List getTimTypes() { protected void expireReduceCreateSendTims(WydotTim wydotTim, TimType timType, String startDateTime, String endDateTime, Integer pk, - ContentEnum content, TravelerInfoType frameType) { + TravelerInfoType frameType) { // Clear any existing TIMs with the same client id Long timTypeId = timType != null ? timType.getTimTypeId() : null; var existingTims = @@ -724,20 +719,20 @@ protected void expireReduceCreateSendTims(WydotTim wydotTim, TimType timType, var reducedMileposts = milepostReduction.applyMilepostReductionAlgorithm(milepostsAll, configuration.getPathDistanceLimit()); - createSendTims(wydotTim, timType, startDateTime, endDateTime, pk, content, frameType, + createSendTims(wydotTim, timType, startDateTime, endDateTime, pk, frameType, milepostsAll, reducedMileposts, anchor); } // creates a TIM and sends it to RSUs and Satellite protected void createSendTims(WydotTim wydotTim, TimType timType, String startDateTime, - String endDateTime, Integer pk, ContentEnum content, + String endDateTime, Integer pk, TravelerInfoType frameType, List allMileposts, List reducedMileposts, Milepost anchor) { // create TIM WydotTravelerInputData timToSend = wydotTimService.createTim(wydotTim, timType.getType(), startDateTime, endDateTime, - content, frameType, allMileposts, reducedMileposts, anchor, configuration.getDotGnisId()); + frameType, allMileposts, reducedMileposts, anchor, configuration.getDotGnisId()); if (timToSend == null) { return; diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBowrController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBowrController.java index c0b67822c..5f390a371 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBowrController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBowrController.java @@ -4,12 +4,10 @@ import java.util.ArrayList; import java.util.List; -import com.trihydro.library.exceptionhandlers.IdenticalPointsExceptionHandler; import com.trihydro.library.helpers.MilepostReduction; import com.trihydro.library.helpers.TimGenerationHelper; import com.trihydro.library.helpers.Utility; import com.trihydro.library.model.ActiveTim; -import com.trihydro.library.model.ContentEnum; import com.trihydro.library.model.WydotTim; import com.trihydro.library.service.ActiveTimService; import com.trihydro.library.service.MilepostService; @@ -64,7 +62,7 @@ public ResponseEntity createOrUpdateBowrTim(@RequestBody TimBowrList tim timResult = validateInputBowr(wydotTimBowr); - if (timResult.getResultMessages().size() > 0) { + if (!timResult.getResultMessages().isEmpty()) { results.add(timResult); errors.add(timResult); continue; @@ -78,7 +76,7 @@ public ResponseEntity createOrUpdateBowrTim(@RequestBody TimBowrList tim processRequestAsync(timsToSend); String responseMessage = gson.toJson(results); - if (errors.size() > 0) { + if (!errors.isEmpty()) { utility.logWithDate("Failed to send TIMs: " + gson.toJson(errors), this.getClass()); return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(responseMessage); } @@ -92,7 +90,7 @@ public ResponseEntity submitBowrClear(@PathVariable String clientId) { List existingTimIds = new ArrayList(); // validate client id - if (clientId == null || clientId.length() == 0) { + if (clientId == null || clientId.isEmpty()) { String responseMessage = "Null or empty value for client id"; return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(responseMessage); } @@ -101,7 +99,7 @@ public ResponseEntity submitBowrClear(@PathVariable String clientId) { var timType = getTimType(type); Long timTypeId = timType != null ? timType.getTimTypeId() : null; List existingActiveTims = activeTimService.getActiveTimsByClientIdDirection(clientId, timTypeId, null); - if (existingActiveTims.size() == 0) { + if (existingActiveTims.isEmpty()) { utility.logWithDate("No active TIMs found for client id: " + clientId, this.getClass()); String responseMessage = "No active TIMs found for client id: " + clientId; return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(responseMessage); @@ -113,9 +111,7 @@ public ResponseEntity submitBowrClear(@PathVariable String clientId) { } // expire existing tims - if (existingTimIds.size() > 0) { - timGenerationHelper.expireTimAndResubmitToOde(existingTimIds); - } + timGenerationHelper.expireTimAndResubmitToOde(existingTimIds); String responseMessage = "success"; return ResponseEntity.status(HttpStatus.OK).body(responseMessage); @@ -137,7 +133,7 @@ public void run() { // get end time String endTime = wydotTimBowr.getEndDateTime(); - processRequest(tim, getTimType(type), startTime, endTime, null, ContentEnum.advisory, + processRequest(tim, getTimType(type), startTime, endTime, null, TravelerInfoType.advisory); } } diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimCcController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimCcController.java index 9b8f564d7..53cca041c 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimCcController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimCcController.java @@ -10,7 +10,6 @@ import com.trihydro.library.helpers.MilepostReduction; import com.trihydro.library.helpers.TimGenerationHelper; import com.trihydro.library.helpers.Utility; -import com.trihydro.library.model.ContentEnum; import com.trihydro.library.model.WydotTim; import com.trihydro.library.service.ActiveTimService; import com.trihydro.library.service.MilepostService; @@ -60,7 +59,7 @@ public ResponseEntity createChainControlTim(@RequestBody TimRcList timRc utility.logWithDate(dateFormat.format(date) + " - CHAIN CONTROL TIM", this.getClass()); String post = gson.toJson(timRcList); - utility.logWithDate(post.toString(), this.getClass()); + utility.logWithDate(post, this.getClass()); List resultList = new ArrayList(); ControllerResult resultTim = null; @@ -76,7 +75,7 @@ public ResponseEntity createChainControlTim(@RequestBody TimRcList timRc resultTim = validateInputCc(wydotTim); - if (resultTim.getResultMessages().size() > 0) { + if (!resultTim.getResultMessages().isEmpty()) { resultList.add(resultTim); continue; } @@ -100,7 +99,7 @@ public void processRequestAsync(List wydotTims) { public void run() { var startTime = getStartTime(); for (WydotTim tim : wydotTims) { - processRequest(tim, getTimType(type), startTime, null, null, ContentEnum.advisory, + processRequest(tim, getTimType(type), startTime, null, null, TravelerInfoType.advisory); } } diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java index 019a6e018..b84cdf330 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java @@ -5,7 +5,6 @@ import com.trihydro.library.helpers.TimGenerationHelper; import com.trihydro.library.helpers.Utility; import com.trihydro.library.model.ActiveTim; -import com.trihydro.library.model.ContentEnum; import com.trihydro.library.model.WydotTim; import com.trihydro.library.service.*; import com.trihydro.odewrapper.config.BasicConfiguration; @@ -128,7 +127,7 @@ public void makeTimsAsync(List wydotTims) { var wydotTimIncident = (WydotTimIncident)wydotTim; // set route wydotTim.setRoute(wydotTimIncident.getRoute()); - processRequest(wydotTimIncident, getTimType(type), startTime, null, wydotTimIncident.getPk(), ContentEnum.advisory, + processRequest(wydotTimIncident, getTimType(type), startTime, null, wydotTimIncident.getPk(), TravelerInfoType.advisory); } }).start(); diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimParkingController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimParkingController.java index 2af6f58b9..f8074df0e 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimParkingController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimParkingController.java @@ -12,7 +12,6 @@ import com.trihydro.library.helpers.TimGenerationHelper; import com.trihydro.library.helpers.Utility; import com.trihydro.library.model.ActiveTim; -import com.trihydro.library.model.ContentEnum; import com.trihydro.library.service.ActiveTimService; import com.trihydro.library.service.MilepostService; import com.trihydro.library.service.RestTemplateProvider; @@ -61,7 +60,7 @@ public ResponseEntity createParkingTim(@RequestBody TimParkingList timPa utility.logWithDate(dateFormat.format(date) + " - Create Parking TIM", this.getClass()); String post = gson.toJson(timParkingList); - utility.logWithDate(post.toString(), this.getClass()); + utility.logWithDate(post, this.getClass()); List resultList = new ArrayList(); ControllerResult resultTim = null; @@ -72,7 +71,7 @@ public ResponseEntity createParkingTim(@RequestBody TimParkingList timPa resultTim = validateInputParking(wydotTim); - if (resultTim.getResultMessages().size() > 0) { + if (!resultTim.getResultMessages().isEmpty()) { resultList.add(resultTim); continue; } @@ -141,7 +140,7 @@ public void processRequestAsync(List wydotTims) { public void run() { var startTime = getStartTime(); for (WydotTimParking wydotTim : wydotTims) { - processRequest(wydotTim, getTimType(type), startTime, null, null, ContentEnum.exitService, + processRequest(wydotTim, getTimType(type), startTime, null, null, TravelerInfoType.advisory); } } diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRcController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRcController.java index 15d074554..85a98fcdc 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRcController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRcController.java @@ -12,7 +12,6 @@ import com.trihydro.library.helpers.TimGenerationHelper; import com.trihydro.library.helpers.Utility; import com.trihydro.library.model.ActiveTim; -import com.trihydro.library.model.ContentEnum; import com.trihydro.library.model.WydotTim; import com.trihydro.library.service.ActiveTimService; import com.trihydro.library.service.RestTemplateProvider; @@ -116,7 +115,7 @@ public ResponseEntity submitAllClearRoadConditionsTim(@RequestBody TimRc utility.logWithDate(dateFormat.format(date) + " - All Clear", this.getClass()); String post = gson.toJson(timRcList); - utility.logWithDate(post.toString(), this.getClass()); + utility.logWithDate(post, this.getClass()); List errList = new ArrayList(); ControllerResult resultTim = null; @@ -124,7 +123,7 @@ public ResponseEntity submitAllClearRoadConditionsTim(@RequestBody TimRc for (WydotTimRc wydotTim : timRcList.getTimRcList()) { resultTim = validateRcAc(wydotTim); - if (resultTim.getResultMessages().size() > 0) { + if (!resultTim.getResultMessages().isEmpty()) { resultList.add(resultTim); errList.add(resultTim); continue; @@ -155,12 +154,12 @@ public ResponseEntity submitAllClearRoadConditionsTim(@RequestBody TimRc } // Expire existing tims - if (existingTimIds.size() > 0) { + if (!existingTimIds.isEmpty()) { timGenerationHelper.expireTimAndResubmitToOde(existingTimIds); } String responseMessage = gson.toJson(resultList); - if (errList.size() > 0) { + if (!errList.isEmpty()) { utility.logWithDate("Failed to send TIMs: " + gson.toJson(errList), this.getClass()); } return ResponseEntity.status(HttpStatus.OK).body(responseMessage); @@ -171,7 +170,7 @@ public void processRequestAsync(List wydotTims) { new Thread(() -> { var startTime = getStartTime(); for (WydotTim tim : wydotTims) { - processRequest(tim, getTimType(type), startTime, null, null, ContentEnum.advisory, + processRequest(tim, getTimType(type), startTime, null, null, TravelerInfoType.advisory); } }).start(); diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java index d752c671b..42e28dfa9 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java @@ -120,15 +120,15 @@ public void processRequestAsync() { if (timRw.getItisCodes() != null && timRw.getItisCodes().size() == 3 && timRw.getItisCodes().get(0).equals("7443")) { processRequest(timRw, getTimType(type), timRw.getSchedStart(), timRw.getSchedEnd(), null, - ContentEnum.speedLimit, TravelerInfoType.advisory); + TravelerInfoType.advisory); } else if (timRw.getItisCodes() != null && timRw.getItisCodes().get(0).equals("7186")) { // prepare to stop processRequest(timRw, getTimType(type), timRw.getSchedStart(), timRw.getSchedEnd(), null, - ContentEnum.advisory, TravelerInfoType.advisory); + TravelerInfoType.advisory); } else { // the rest are content=workZone processRequest(timRw, getTimType(type), timRw.getSchedStart(), timRw.getSchedEnd(), null, - ContentEnum.workZone, TravelerInfoType.advisory); + TravelerInfoType.advisory); } } }).start(); diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimVslController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimVslController.java index a7adef336..d25c11e22 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimVslController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimVslController.java @@ -5,7 +5,6 @@ import com.trihydro.library.helpers.TimGenerationHelper; import com.trihydro.library.helpers.Utility; import com.trihydro.library.model.ActiveTim; -import com.trihydro.library.model.ContentEnum; import com.trihydro.library.model.WydotTim; import com.trihydro.library.service.*; import com.trihydro.odewrapper.config.BasicConfiguration; @@ -88,7 +87,7 @@ public void processRequestAsync(List wydotTims) { new Thread(() -> { var startTime = getStartTime(); for (WydotTim tim : wydotTims) { - processRequest(tim, getTimType(type), startTime, null, null, ContentEnum.speedLimit, + processRequest(tim, getTimType(type), startTime, null, null, TravelerInfoType.roadSignage); } }).start(); From 6855bf06f116e6d19eb2ab3535fe1c84c3c4ea97 Mon Sep 17 00:00:00 2001 From: Paige Monington Date: Tue, 21 Oct 2025 08:03:34 -0600 Subject: [PATCH 146/168] chore: fix constant variable casing --- .../trihydro/odewrapper/helpers/SetItisCodes.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java index dec02b646..73410821d 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java @@ -32,9 +32,9 @@ public class SetItisCodes { private List itisCodes; - private final String AdvisoryItisCode = "7712"; - private final String ReducedItisCode = "12302"; - private final String AheadItisCode = "13569"; + private final String ADVISORY_ITIS_CODE = "7712"; + private final String REDUCED_ITIS_CODE = "12302"; + private final String AHEAD_ITIS_CODE = "13569"; @Autowired public SetItisCodes(ItisCodeService _itisCodeService, IncidentChoicesService _incidentChoicesService) { @@ -185,14 +185,14 @@ public List setItisCodesVsl(WydotTimVsl wydotTim) { List allItisCodes = getAllItisCodesFromDatabase(); // add advisory code first if advisory speed limit - wydotTim.getItisCodes().stream().filter(x -> x.contains(AdvisoryItisCode)).findFirst() + wydotTim.getItisCodes().stream().filter(x -> x.contains(ADVISORY_ITIS_CODE)).findFirst() .ifPresent(items::add); // speed limit itis code allItisCodes.stream().filter(x -> x.getDescription().equals("speed limit")).findFirst().ifPresent(mph -> items.add(mph.getItisCode().toString())); // add reduced code next if reduced speed - wydotTim.getItisCodes().stream().filter(x -> x.contains(ReducedItisCode)).findFirst() + wydotTim.getItisCodes().stream().filter(x -> x.contains(REDUCED_ITIS_CODE)).findFirst() .ifPresent(items::add); // J2540 small number ITIS codes start at 12,544 and increment by 1 to represent each number up to 255. @@ -205,7 +205,7 @@ public List setItisCodesVsl(WydotTimVsl wydotTim) { allItisCodes.stream().filter(x -> x.getDescription().equals("mph")).findFirst().ifPresent(mph -> items.add(mph.getItisCode().toString())); // add ahead code next if tim includes ahead code last - wydotTim.getItisCodes().stream().filter(x -> x.contains(AheadItisCode)).findFirst() + wydotTim.getItisCodes().stream().filter(x -> x.contains(AHEAD_ITIS_CODE)).findFirst() .ifPresent(items::add); return items; From e274e9f22f2074b8b7c9515312d5a4f4e72dd916 Mon Sep 17 00:00:00 2001 From: Paige Monington Date: Wed, 22 Oct 2025 08:14:18 -0600 Subject: [PATCH 147/168] fix: move msgID to CTW standard and replace use of roadSignID with furtherInfoID set to default 0 --- .../library/helpers/CreateBaseTimUtil.java | 39 ++----------------- .../library/helpers/TimGenerationHelper.java | 26 ++----------- .../helpers/CreateBaseTimUtilTest.java | 2 + .../library/service/WydotTimServiceTest.java | 2 +- .../mockOdeTravelerInformationMessage.json | 11 +----- .../test/resources/rxMsg_TIM_OdeOutput.json | 12 +----- .../rxMsg_TIM_OdeOutput_Geometry.json | 12 +----- .../rxMsg_TIM_OdeOutput_MultipleRegions.json | 12 +----- .../test/resources/rxMsg_TIM_SpeedLimit.json | 12 +----- .../src/test/resources/sdxDecodeResponse.json | 2 +- .../src/test/resources/tim_construction.json | 23 +---------- .../tim_construction_MultipleRegions.json | 23 +---------- .../src/test/resources/tim_parking.json | 23 +---------- .../tim_parking_MultipleRegions.json | 23 +---------- .../src/test/resources/tim_vsl.json | 23 +---------- .../resources/tim_vsl_MultipleRegions.json | 23 +---------- .../geojson-from-ode-tim/sampledata.json | 9 +---- .../resources/TIM_odeTimStartDateTime.json | 26 +------------ .../src/test/resources/TIM_odeTim_Rsus.json | 26 +------------ .../test/resources/rxMsg_TIM_OdeOutput.json | 12 +----- .../rxMsg_TIM_OdeOutput_NullMetadata.json | 12 +----- 21 files changed, 28 insertions(+), 325 deletions(-) diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CreateBaseTimUtil.java b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CreateBaseTimUtil.java index 52174c1f5..780cc569b 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CreateBaseTimUtil.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CreateBaseTimUtil.java @@ -22,10 +22,8 @@ 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.OdeTravelerInformationMessage.DataFrame.MsgId; -import us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage.DataFrame.RoadSignID; import us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage.NodeXY; import us.dot.its.jpo.ode.plugin.j2735.timstorage.FrameType.TravelerInfoType; -import us.dot.its.jpo.ode.plugin.j2735.timstorage.MutcdCode.MutcdCodeEnum; @Component public class CreateBaseTimUtil { @@ -77,13 +75,10 @@ public WydotTravelerInputData buildTim(WydotTim wydotTim, TimGenerationProps gen // add itis codes to tim dataFrame.setItems(wydotTim.getItisCodes().toArray(new String[wydotTim.getItisCodes().size()])); - // create anchor for the msgId - OdePosition3D anchorPosition = new OdePosition3D(); - anchorPosition.setLatitude(anchor.getLatitude()); - anchorPosition.setLongitude(anchor.getLongitude()); - - // build msgId - MsgId msgId = buildMsgId(anchorPosition, content, frameType); + // Per CTW guidance, msgId must be populated using furtherInfoID (not roadSignID) + // Since furtherInfoID is not used, set it to the default value of 0 + MsgId msgId = new MsgId(); + msgId.setFurtherInfoID("0"); dataFrame.setMsgId(msgId); // set regions. note that we now support multiple regions in a single TIM package @@ -266,30 +261,4 @@ public String buildHeadingSliceFromMileposts(List allMileposts, OdePos headingSliceString = StringUtils.reverse(headingSliceString); return headingSliceString; } - - /** - * Builds a message ID based on the provided anchor position, content, and frame type. - * - * @param anchorPosition The anchor position for the road sign. - * @param content The content of the message. - * @param frameType The type of the frame. - * @return The built message ID. - */ - protected MsgId buildMsgId(OdePosition3D anchorPosition, ContentEnum content, TravelerInfoType frameType) { - MsgId msgId = new MsgId(); - RoadSignID roadSignID = new RoadSignID(); - roadSignID.setPosition(anchorPosition); - - // if we are coming in with content=speedLimit and frameType=roadSignage, - // we need to set the mutcdCode to regulatory to display the regulatory signage - if (content == ContentEnum.speedLimit && frameType == TravelerInfoType.roadSignage) { - roadSignID.setMutcdCode(MutcdCodeEnum.regulatory); - } else { - roadSignID.setMutcdCode(MutcdCodeEnum.warning); - } - // set view angle to 360 degrees - roadSignID.setViewAngle("1111111111111111"); - msgId.setRoadSignID(roadSignID); - return msgId; - } } \ No newline at end of file diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/TimGenerationHelper.java b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/TimGenerationHelper.java index c42d47113..9a4c4c103 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/TimGenerationHelper.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/TimGenerationHelper.java @@ -11,7 +11,6 @@ import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; -import java.util.Arrays; import java.util.Comparator; import java.util.Date; import java.util.List; @@ -20,7 +19,6 @@ import com.trihydro.library.model.ActiveTimError; import com.trihydro.library.model.ActiveTimHolding; import com.trihydro.library.model.ActiveTimValidationResult; -import com.trihydro.library.model.ContentEnum; import com.trihydro.library.model.Coordinate; import com.trihydro.library.model.Milepost; import com.trihydro.library.model.MilepostBuffer; @@ -56,10 +54,7 @@ import us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage.DataFrame.MsgId; import us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage.DataFrame.Region; import us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage.DataFrame.Region.Path; -import us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage.DataFrame.RoadSignID; -import us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage.NodeXY; -import us.dot.its.jpo.ode.plugin.j2735.timstorage.FrameType.TravelerInfoType; -import us.dot.its.jpo.ode.plugin.j2735.timstorage.MutcdCode.MutcdCodeEnum; +import us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage.NodeXY;; @Component @Slf4j @@ -700,7 +695,7 @@ private OdeTravelerInformationMessage getTim(TimUpdateModel aTim, List boolean resetStartTimes, boolean resetExpirationTime) { String nowAsISO = Instant.now().toString(); - DataFrame dataFrame = getDataFrame(aTim, anchor, resetStartTimes, resetExpirationTime); + DataFrame dataFrame = getDataFrame(aTim, resetStartTimes, resetExpirationTime); // check to see if we have any itis codes // if not, just continue on if (dataFrame.getItems() == null || dataFrame.getItems().length == 0) { @@ -832,25 +827,12 @@ protected int getNextMessageCount(int currentCount) { return ++currentCount; } - private DataFrame getDataFrame(TimUpdateModel aTim, Milepost anchor, boolean resetStartTimes, + private DataFrame getDataFrame(TimUpdateModel aTim, boolean resetStartTimes, boolean resetExpirationTime) { - // RoadSignID - RoadSignID rsid = new RoadSignID(); - rsid.setPosition(getAnchorPosition(anchor)); - rsid.setViewAngle("1111111111111111"); - - // if we are coming in with content=speedLimit and frameType=roadSignage, - // we need to set the mutcdCode to regulatory to display the regulatory signage - if (aTim.getDfContent() == ContentEnum.speedLimit && - aTim.getFrameType() == TravelerInfoType.roadSignage) { - rsid.setMutcdCode(MutcdCodeEnum.regulatory); - } else { - rsid.setMutcdCode(MutcdCodeEnum.warning); - } // MsgId MsgId msgId = new MsgId(); - msgId.setRoadSignID(rsid); + msgId.setFurtherInfoID("0"); // DataFrame DataFrame df = new DataFrame(); diff --git a/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CreateBaseTimUtilTest.java b/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CreateBaseTimUtilTest.java index 1a445ef04..fa3f48e68 100644 --- a/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CreateBaseTimUtilTest.java +++ b/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CreateBaseTimUtilTest.java @@ -118,6 +118,7 @@ public void buildTim_EndpointSUCCESS() { Assertions.assertNotNull(dataFrame); Assertions.assertEquals("advisory", dataFrame.getContent()); Assertions.assertEquals(32000, dataFrame.getDurationTime()); + Assertions.assertEquals("0", dataFrame.getMsgId().getFurtherInfoID()); var region = dataFrame.getRegions()[0]; Assertions.assertNotNull(region); @@ -167,6 +168,7 @@ public void buildTim_singlePointSUCCESS() { Assertions.assertNotNull(dataFrame); Assertions.assertEquals("advisory", dataFrame.getContent()); Assertions.assertEquals(32000, dataFrame.getDurationTime()); + Assertions.assertEquals("0", dataFrame.getMsgId().getFurtherInfoID()); var region = dataFrame.getRegions()[0]; Assertions.assertNotNull(region); diff --git a/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java b/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java index ad4cb8f33..2ffd32af7 100644 --- a/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java +++ b/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java @@ -145,7 +145,7 @@ private List getActiveTims(boolean isSat) { } private OdeTravelerInformationMessage getMockOdeTravelerInformationMessage() { - String timJson = "{\"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.0030982\",\"nodeLat\":\"0.0014562\",\"delta\":\"node-LL3\"},{\"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\"}]}"; + String timJson = "{\"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\":{\"furtherInfoID\":\"0\"},\"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.0030982\",\"nodeLat\":\"0.0014562\",\"delta\":\"node-LL3\"},{\"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\"}]}"; Gson gson = new Gson(); return gson.fromJson(timJson, OdeTravelerInformationMessage.class); } diff --git a/cv-data-service-library/src/test/resources/com/trihydro/library/service/mockOdeTravelerInformationMessage.json b/cv-data-service-library/src/test/resources/com/trihydro/library/service/mockOdeTravelerInformationMessage.json index 828c86c39..e350b63ef 100644 --- a/cv-data-service-library/src/test/resources/com/trihydro/library/service/mockOdeTravelerInformationMessage.json +++ b/cv-data-service-library/src/test/resources/com/trihydro/library/service/mockOdeTravelerInformationMessage.json @@ -10,16 +10,7 @@ "doNotUse1": "0", "frameType": "advisory", "msgId": { - "roadSignID": { - "position": { - "latitude": "41.678473", - "longitude": "-108.782775", - "elevation": "917.1432" - }, - "viewAngle": "1010101010101010", - "mutcdCode": "warning", - "crc": "0000" - } + "furtherInfoID": "0" }, "priority": "0", "doNotUse2": "3", diff --git a/cv-data-service-library/src/test/resources/rxMsg_TIM_OdeOutput.json b/cv-data-service-library/src/test/resources/rxMsg_TIM_OdeOutput.json index 169a60727..2f93bdc33 100644 --- a/cv-data-service-library/src/test/resources/rxMsg_TIM_OdeOutput.json +++ b/cv-data-service-library/src/test/resources/rxMsg_TIM_OdeOutput.json @@ -90,17 +90,7 @@ "roadSignage": "" }, "msgId": { - "roadSignID": { - "viewAngle": 1100000000000001, - "mutcdCode": { - "warning": "" - }, - "position": { - "elevation": 20, - "lat": 263055670, - "long": -801481500 - } - } + "furtherInfoID": "0" }, "startTime": 149760, "priority": 2, diff --git a/cv-data-service-library/src/test/resources/rxMsg_TIM_OdeOutput_Geometry.json b/cv-data-service-library/src/test/resources/rxMsg_TIM_OdeOutput_Geometry.json index cff628b73..c50d92da9 100644 --- a/cv-data-service-library/src/test/resources/rxMsg_TIM_OdeOutput_Geometry.json +++ b/cv-data-service-library/src/test/resources/rxMsg_TIM_OdeOutput_Geometry.json @@ -77,17 +77,7 @@ "roadSignage": "" }, "msgId": { - "roadSignID": { - "viewAngle": 1100000000000001, - "mutcdCode": { - "warning": "" - }, - "position": { - "elevation": 20, - "lat": 263055670, - "long": -801481500 - } - } + "furtherInfoID": "0" }, "startTime": 149760, "priority": 2, diff --git a/cv-data-service-library/src/test/resources/rxMsg_TIM_OdeOutput_MultipleRegions.json b/cv-data-service-library/src/test/resources/rxMsg_TIM_OdeOutput_MultipleRegions.json index 1549e6c85..b223fea56 100644 --- a/cv-data-service-library/src/test/resources/rxMsg_TIM_OdeOutput_MultipleRegions.json +++ b/cv-data-service-library/src/test/resources/rxMsg_TIM_OdeOutput_MultipleRegions.json @@ -134,17 +134,7 @@ "roadSignage": "" }, "msgId": { - "roadSignID": { - "viewAngle": 1100000000000001, - "mutcdCode": { - "warning": "" - }, - "position": { - "elevation": 20, - "lat": 263055670, - "long": -801481500 - } - } + "furtherInfoID": "0" }, "startTime": 149760, "priority": 2, diff --git a/cv-data-service-library/src/test/resources/rxMsg_TIM_SpeedLimit.json b/cv-data-service-library/src/test/resources/rxMsg_TIM_SpeedLimit.json index 4692d3167..6814be0e4 100644 --- a/cv-data-service-library/src/test/resources/rxMsg_TIM_SpeedLimit.json +++ b/cv-data-service-library/src/test/resources/rxMsg_TIM_SpeedLimit.json @@ -90,17 +90,7 @@ "roadSignage": "" }, "msgId": { - "roadSignID": { - "viewAngle": 1100000000000001, - "mutcdCode": { - "warning": "" - }, - "position": { - "elevation": 20, - "lat": 263055670, - "long": -801481500 - } - } + "furtherInfoID": "0" }, "startTime": 149760, "priority": 2, diff --git a/cv-data-service-library/src/test/resources/sdxDecodeResponse.json b/cv-data-service-library/src/test/resources/sdxDecodeResponse.json index 0ee50ee8c..1102aa065 100644 --- a/cv-data-service-library/src/test/resources/sdxDecodeResponse.json +++ b/cv-data-service-library/src/test/resources/sdxDecodeResponse.json @@ -1,4 +1,4 @@ { "messageType": "MessageFrame", - "decodedMessage": "3113469004null0414344751-1101051425111111111111111120194690043200050westbound_I80_39.9_53.31_SAT-4035A5DF_RC_LYMI80EGRAD00414344751-11010514253270000000011111100000-1048300445417415787-1101068786414338729-1048297813417401082-1101173822414302517-1048296846417313218-1101278808414263469-1048334156417231472-1101362065414212124-1048363596417151273-1048348231417067803-1101430219414153700-1101515051414095801-1048292665416990008-1101609734414047121-1048303785416903264-1101704290413998478-1048330081416818875-1101798529413950074-1048362115416736381-1048394037416654255-1101901550413914121-1102014424413891332-1048426742416569080-1102126907413868840-1048459137416484285-1102235582413840132-1048492892416400669-1102332568413793094-1048526150416318091-1048559229416236049-1102434259413752451-1102543983413731407-1048592545416153296-1102655116413714865-1048625771416070802-1102767179413702216-1048658799415988821-1102881705413689256-1048694127415905527-1048732305415821992-1102996201413671479-1103105581413647716-1048769216415741004-1103216030413622307-1048806392415659600-1103325763413587617-1048843990415577334-11033794134135705070058955907null" + "decodedMessage": "3113469004null0020194690043200050westbound_I80_39.9_53.31_SAT-4035A5DF_RC_LYMI80EGRAD00414344751-11010514253270000000011111100000-1048300445417415787-1101068786414338729-1048297813417401082-1101173822414302517-1048296846417313218-1101278808414263469-1048334156417231472-1101362065414212124-1048363596417151273-1048348231417067803-1101430219414153700-1101515051414095801-1048292665416990008-1101609734414047121-1048303785416903264-1101704290413998478-1048330081416818875-1101798529413950074-1048362115416736381-1048394037416654255-1101901550413914121-1102014424413891332-1048426742416569080-1102126907413868840-1048459137416484285-1102235582413840132-1048492892416400669-1102332568413793094-1048526150416318091-1048559229416236049-1102434259413752451-1102543983413731407-1048592545416153296-1102655116413714865-1048625771416070802-1102767179413702216-1048658799415988821-1102881705413689256-1048694127415905527-1048732305415821992-1102996201413671479-1103105581413647716-1048769216415741004-1103216030413622307-1048806392415659600-1103325763413587617-1048843990415577334-11033794134135705070058955907null" } diff --git a/cv-data-service-library/src/test/resources/tim_construction.json b/cv-data-service-library/src/test/resources/tim_construction.json index 8385e897d..8594cc3fb 100644 --- a/cv-data-service-library/src/test/resources/tim_construction.json +++ b/cv-data-service-library/src/test/resources/tim_construction.json @@ -39,28 +39,7 @@ "doNotUse1": 0, "frameType": "advisory", "msgId": { - "roadSignID": { - "position": { "lat": 417732928, "long": -1071000312 }, - "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" - } + "furtherInfoID": "0" }, "durationTime": 32000, "startYear": 2021, diff --git a/cv-data-service-library/src/test/resources/tim_construction_MultipleRegions.json b/cv-data-service-library/src/test/resources/tim_construction_MultipleRegions.json index 2b0d145ab..5661c16de 100644 --- a/cv-data-service-library/src/test/resources/tim_construction_MultipleRegions.json +++ b/cv-data-service-library/src/test/resources/tim_construction_MultipleRegions.json @@ -39,28 +39,7 @@ "doNotUse1": 0, "frameType": "advisory", "msgId": { - "roadSignID": { - "position": { "lat": 417732928, "long": -1071000312 }, - "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" - } + "furtherInfoID": "0" }, "durationTime": 32000, "startYear": 2021, diff --git a/cv-data-service-library/src/test/resources/tim_parking.json b/cv-data-service-library/src/test/resources/tim_parking.json index 519b60e3b..e96e1cb20 100644 --- a/cv-data-service-library/src/test/resources/tim_parking.json +++ b/cv-data-service-library/src/test/resources/tim_parking.json @@ -39,28 +39,7 @@ "doNotUse1": 0, "frameType": "advisory", "msgId": { - "roadSignID": { - "position": { "lat": 417732928, "long": -1071000312 }, - "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" - } + "furtherInfoID": "0" }, "durationTime": 32000, "startYear": 2021, diff --git a/cv-data-service-library/src/test/resources/tim_parking_MultipleRegions.json b/cv-data-service-library/src/test/resources/tim_parking_MultipleRegions.json index 594adfcc4..34b291a81 100644 --- a/cv-data-service-library/src/test/resources/tim_parking_MultipleRegions.json +++ b/cv-data-service-library/src/test/resources/tim_parking_MultipleRegions.json @@ -142,28 +142,7 @@ "doNotUse4": 0, "startYear": 2021, "msgId": { - "roadSignID": { - "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", - "position": { "lat": 410985067, "long": -1051331761 } - } + "furtherInfoID": "0" }, "priority": 5, "content": { diff --git a/cv-data-service-library/src/test/resources/tim_vsl.json b/cv-data-service-library/src/test/resources/tim_vsl.json index fde8dd0cb..881717ad8 100644 --- a/cv-data-service-library/src/test/resources/tim_vsl.json +++ b/cv-data-service-library/src/test/resources/tim_vsl.json @@ -39,28 +39,7 @@ "doNotUse1": 0, "frameType": "advisory", "msgId": { - "roadSignID": { - "position": { "lat": 417732928, "long": -1071000312 }, - "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" - } + "furtherInfoID": "0" }, "durationTime": 32000, "startYear": 2021, diff --git a/cv-data-service-library/src/test/resources/tim_vsl_MultipleRegions.json b/cv-data-service-library/src/test/resources/tim_vsl_MultipleRegions.json index e8220debf..9fe41d220 100644 --- a/cv-data-service-library/src/test/resources/tim_vsl_MultipleRegions.json +++ b/cv-data-service-library/src/test/resources/tim_vsl_MultipleRegions.json @@ -126,28 +126,7 @@ "doNotUse4": 1, "startYear": 2021, "msgId": { - "roadSignID": { - "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": "regulatory", - "position": { "lat": 428605724, "long": -1063379489 } - } + "furtherInfoID": "0" }, "priority": 5, "content": { diff --git a/developer-tools/geojson-from-ode-tim/sampledata.json b/developer-tools/geojson-from-ode-tim/sampledata.json index b8ec7a2fc..fab46f9c3 100644 --- a/developer-tools/geojson-from-ode-tim/sampledata.json +++ b/developer-tools/geojson-from-ode-tim/sampledata.json @@ -24,14 +24,7 @@ "doNotUse1": 0, "frameType": "advisory", "msgId": { - "roadSignID": { - "position": { - "latitude": 44.8062595, - "longitude": -107.3203401 - }, - "viewAngle": "1111111111111111", - "mutcdCode": "warning" - } + "furtherInfoID": "0" }, "startDateTime": "2024-10-02T11:00:50.814Z", "durationTime": 32000, diff --git a/logger-kafka-consumer/src/test/resources/TIM_odeTimStartDateTime.json b/logger-kafka-consumer/src/test/resources/TIM_odeTimStartDateTime.json index 4b66fec03..b8225015d 100644 --- a/logger-kafka-consumer/src/test/resources/TIM_odeTimStartDateTime.json +++ b/logger-kafka-consumer/src/test/resources/TIM_odeTimStartDateTime.json @@ -254,31 +254,7 @@ "doNotUse4": 0, "startYear": 2020, "msgId": { - "roadSignID": { - "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", - "position": { - "lat": 418082518, - "long": -1105341319 - } - } + "furtherInfoID": "0" }, "priority": 5, "content": { diff --git a/logger-kafka-consumer/src/test/resources/TIM_odeTim_Rsus.json b/logger-kafka-consumer/src/test/resources/TIM_odeTim_Rsus.json index 1c0e0c33b..562f5ec7d 100644 --- a/logger-kafka-consumer/src/test/resources/TIM_odeTim_Rsus.json +++ b/logger-kafka-consumer/src/test/resources/TIM_odeTim_Rsus.json @@ -60,31 +60,7 @@ "durationTime": 32000, "frameType": "advisory", "msgId": { - "roadSignID": { - "mutcdCode": "warning", - "position": { - "lat": 412696444, - "long": -1054796709 - }, - "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 - } - } + "furtherInfoID": "0" }, "priority": 5, "regions": [ diff --git a/logger-kafka-consumer/src/test/resources/rxMsg_TIM_OdeOutput.json b/logger-kafka-consumer/src/test/resources/rxMsg_TIM_OdeOutput.json index 169a60727..2f93bdc33 100644 --- a/logger-kafka-consumer/src/test/resources/rxMsg_TIM_OdeOutput.json +++ b/logger-kafka-consumer/src/test/resources/rxMsg_TIM_OdeOutput.json @@ -90,17 +90,7 @@ "roadSignage": "" }, "msgId": { - "roadSignID": { - "viewAngle": 1100000000000001, - "mutcdCode": { - "warning": "" - }, - "position": { - "elevation": 20, - "lat": 263055670, - "long": -801481500 - } - } + "furtherInfoID": "0" }, "startTime": 149760, "priority": 2, diff --git a/logger-kafka-consumer/src/test/resources/rxMsg_TIM_OdeOutput_NullMetadata.json b/logger-kafka-consumer/src/test/resources/rxMsg_TIM_OdeOutput_NullMetadata.json index 99c9e6fae..c51107342 100644 --- a/logger-kafka-consumer/src/test/resources/rxMsg_TIM_OdeOutput_NullMetadata.json +++ b/logger-kafka-consumer/src/test/resources/rxMsg_TIM_OdeOutput_NullMetadata.json @@ -62,17 +62,7 @@ "roadSignage": "" }, "msgId": { - "roadSignID": { - "viewAngle": 1100000000000001, - "mutcdCode": { - "warning": "" - }, - "position": { - "elevation": 20, - "lat": 263055670, - "long": -801481500 - } - } + "furtherInfoID": "0" }, "startTime": 149760, "priority": 2, From 9bc1e5938ec1b06445cd49252acd083690d423f7 Mon Sep 17 00:00:00 2001 From: Paige Monington Date: Thu, 23 Oct 2025 15:44:44 -0600 Subject: [PATCH 148/168] test: add unit tests ensuring RoadSignID is not set --- .../com/trihydro/library/helpers/CreateBaseTimUtilTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CreateBaseTimUtilTest.java b/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CreateBaseTimUtilTest.java index fa3f48e68..2e0c02e3d 100644 --- a/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CreateBaseTimUtilTest.java +++ b/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CreateBaseTimUtilTest.java @@ -119,6 +119,7 @@ public void buildTim_EndpointSUCCESS() { Assertions.assertEquals("advisory", dataFrame.getContent()); Assertions.assertEquals(32000, dataFrame.getDurationTime()); Assertions.assertEquals("0", dataFrame.getMsgId().getFurtherInfoID()); + Assertions.assertNull(dataFrame.getMsgId().getRoadSignID()); var region = dataFrame.getRegions()[0]; Assertions.assertNotNull(region); @@ -169,6 +170,7 @@ public void buildTim_singlePointSUCCESS() { Assertions.assertEquals("advisory", dataFrame.getContent()); Assertions.assertEquals(32000, dataFrame.getDurationTime()); Assertions.assertEquals("0", dataFrame.getMsgId().getFurtherInfoID()); + Assertions.assertNull(dataFrame.getMsgId().getRoadSignID()); var region = dataFrame.getRegions()[0]; Assertions.assertNotNull(region); From a7e7a4b49dc37d63641aecd1eac3368396be4ed4 Mon Sep 17 00:00:00 2001 From: Paige Monington Date: Tue, 28 Oct 2025 10:28:16 -0600 Subject: [PATCH 149/168] refactor: simplify TIM ITIS code handling by removing redundant condition checks --- .../controller/WydotTimRwController.java | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java index 42e28dfa9..29b92e882 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java @@ -116,20 +116,7 @@ public void processRequestAsync() { new Thread(() -> { for (var tim : timsToSend) { WydotTimRw timRw = (WydotTimRw) tim; - // check for reduce speed, itis code 7443 - if (timRw.getItisCodes() != null && timRw.getItisCodes().size() == 3 - && timRw.getItisCodes().get(0).equals("7443")) { - processRequest(timRw, getTimType(type), timRw.getSchedStart(), timRw.getSchedEnd(), null, - TravelerInfoType.advisory); - } else if (timRw.getItisCodes() != null && timRw.getItisCodes().get(0).equals("7186")) { - // prepare to stop - processRequest(timRw, getTimType(type), timRw.getSchedStart(), timRw.getSchedEnd(), null, - TravelerInfoType.advisory); - } else { - // the rest are content=workZone - processRequest(timRw, getTimType(type), timRw.getSchedStart(), timRw.getSchedEnd(), null, - TravelerInfoType.advisory); - } + processRequest(timRw, getTimType(type), timRw.getSchedStart(), timRw.getSchedEnd(), null, TravelerInfoType.advisory); } }).start(); From 5963a2688bceadf53e2fbb66d13a9e4518295e6b Mon Sep 17 00:00:00 2001 From: Paige Monington Date: Mon, 3 Nov 2025 08:56:59 -0700 Subject: [PATCH 150/168] feat: apply CTW FrameType requirement setting type to roadSignage --- .../controller/ActiveTimController.java | 23 +------------------ .../controller/DataFrameController.java | 7 +++--- .../library/helpers/CreateBaseTimUtil.java | 4 ++-- .../library/helpers/JsonToJavaConverter.java | 12 +--------- .../library/model/TimUpdateModel.java | 9 +++----- .../library/service/WydotTimService.java | 4 ++-- .../app/services/DataFrameService.java | 7 +++--- .../controller/WydotTimBaseController.java | 19 ++++++++------- .../controller/WydotTimBowrController.java | 3 +-- .../controller/WydotTimCcController.java | 3 +-- .../WydotTimIncidentController.java | 3 +-- .../controller/WydotTimParkingController.java | 3 +-- .../controller/WydotTimRcController.java | 3 +-- .../controller/WydotTimRwController.java | 2 +- .../controller/WydotTimVslController.java | 3 +-- 15 files changed, 31 insertions(+), 74 deletions(-) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java index 842c734db..3434ca210 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java @@ -102,17 +102,6 @@ public ResponseEntity> GetExpiringActiveTims() { while (rs.next()) { var activeTim = buildTimUpdateModelFromResultSet(rs); - int frameTypeValue = rs.getInt("FRAME_TYPE"); - if (!rs.wasNull() && frameTypeValue >= 0 && frameTypeValue < TravelerInfoType.values().length) { - activeTim.setFrameType(TravelerInfoType.values()[frameTypeValue]); - } - else { - log.warn("Could not set frame type from value {} for active tim id {}. Assuming Advisory.", frameTypeValue, - activeTim.getActiveTimId()); - // assume advisory - activeTim.setFrameType(TravelerInfoType.advisory); - } - activeTim.setDfContent(ContentEnum.advisory); activeTims.add(activeTim); } @@ -148,17 +137,6 @@ public ResponseEntity GetUpdateModelFromActiveTimId(@PathVariabl while (rs.next()) { // Active_Tim properties activeTim = buildTimUpdateModelFromResultSet(rs); - - int frameTypeValue = rs.getInt("FRAME_TYPE"); - if (!rs.wasNull() && frameTypeValue >= 0 && frameTypeValue < TravelerInfoType.values().length) { - activeTim.setFrameType(TravelerInfoType.values()[frameTypeValue]); - } - else { - log.warn("Could not set frame type from value {} for active tim id {}. Assuming Advisory.", frameTypeValue, activeTimId); - // assume advisory - activeTim.setFrameType(TravelerInfoType.advisory); - } - activeTim.setDfContent(ContentEnum.advisory); } } catch (Exception e) { @@ -1060,6 +1038,7 @@ private TimUpdateModel buildTimUpdateModelFromResultSet(ResultSet rs) throws SQL timUpdateModel.setDataFrameId(rs.getInt("DATA_FRAME_ID")); timUpdateModel.setDurationTime(rs.getInt("DURATION_TIME")); timUpdateModel.setUrl(rs.getString("URL")); + return timUpdateModel; } diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/DataFrameController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/DataFrameController.java index 2c8c3950b..a427d860d 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/DataFrameController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/DataFrameController.java @@ -29,6 +29,7 @@ import springfox.documentation.annotations.ApiIgnore; import us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage.DataFrame; +import us.dot.its.jpo.ode.plugin.j2735.timstorage.FrameType; @CrossOrigin @RestController @@ -112,10 +113,8 @@ public ResponseEntity AddDataFrame(@RequestBody DataFrame dFrame, @PathVar if (col.equals("TIM_ID")) { sqlNullHandler.setLongOrNull(preparedStatement, fieldNum, timId); } else if (col.equals("FRAME_TYPE")) { - Integer ordinal = null; - if (dFrame.getFrameType() != null) { - ordinal = dFrame.getFrameType().ordinal(); - } + // Always assign TravelerInfoType.roadSignage per CTW + Integer ordinal = FrameType.TravelerInfoType.roadSignage.ordinal(); sqlNullHandler.setIntegerOrNull(preparedStatement, fieldNum, ordinal); } else if (col.equals("DURATION_TIME")) { sqlNullHandler.setIntegerOrNull(preparedStatement, fieldNum, dFrame.getDurationTime()); diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CreateBaseTimUtil.java b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CreateBaseTimUtil.java index eab962ed8..99bf4b87f 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CreateBaseTimUtil.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CreateBaseTimUtil.java @@ -47,7 +47,7 @@ public void InjectDependencies(Utility _utility) { * @return The WydotTravelerInputData object containing the built TIM. */ public WydotTravelerInputData buildTim(WydotTim wydotTim, TimGenerationProps genProps, - TravelerInfoType frameType, List allMileposts, List reducedMileposts, Milepost anchor) { + List allMileposts, List reducedMileposts, Milepost anchor) { ContentEnum content = ContentEnum.advisory; @@ -71,7 +71,7 @@ public WydotTravelerInputData buildTim(WydotTim wydotTim, TimGenerationProps gen dataFrame.setPriority(5); dataFrame.setContent(content.getStringValue()); - dataFrame.setFrameType(frameType); + dataFrame.setFrameType(TravelerInfoType.roadSignage); dataFrame.setUrl("null"); // add itis codes to tim dataFrame.setItems(wydotTim.getItisCodes().toArray(new String[wydotTim.getItisCodes().size()])); diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/JsonToJavaConverter.java b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/JsonToJavaConverter.java index f7b545a90..07db6fe08 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/JsonToJavaConverter.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/JsonToJavaConverter.java @@ -511,17 +511,6 @@ else if (sequenceArrNode.get("item").get("text") != null) itemsList.add(item); } - // TravelerInfoType.valueOf(); - JsonNode frameTypeNode = travelerDataFrame.get("frameType"); - if (frameTypeNode != null) { - if (frameTypeNode.fieldNames().hasNext()) { - TravelerInfoType frameType = TravelerInfoType.valueOf(frameTypeNode.fieldNames().next()); - if (frameType != null) { - dataFrame.setFrameType(frameType); - } - } - } - JsonNode startTimeNode = travelerDataFrame.get("startTime"); JsonNode durationNode = travelerDataFrame.get("durationTime"); JsonNode priorityNode = travelerDataFrame.get("priority"); @@ -531,6 +520,7 @@ else if (sequenceArrNode.get("item").get("text") != null) dataFrame.setStartDateTime(startDate.toString() + "Z"); dataFrame.setDurationTime(durationNode.asInt()); dataFrame.setPriority(priorityNode.asInt()); + dataFrame.setFrameType(TravelerInfoType.roadSignage); String[] items = new String[itemsList.size()]; items = itemsList.toArray(items); diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/model/TimUpdateModel.java b/cv-data-service-library/src/main/java/com/trihydro/library/model/TimUpdateModel.java index 7333b268e..2d669c4d1 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/model/TimUpdateModel.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/model/TimUpdateModel.java @@ -30,7 +30,6 @@ public class TimUpdateModel extends ActiveTim { // DataFrame properties private int dataFrameId; - private TravelerInfoType frameType; private int durationTime; private short doNotUse2; private short doNotUse1; @@ -38,10 +37,12 @@ public class TimUpdateModel extends ActiveTim { private short doNotUse3; private ContentEnum dfContent; private String url; + // Per CTW, FrameType should be set to roadSignage when state or local deployment agency is generating the message + // which is all messages coming through the TIMM so always set to roadSignage + private final TravelerInfoType frameType = TravelerInfoType.roadSignage; public BigDecimal getLaneWidth() { return laneWidth; - // DataFrame df;df.setFrameType(frameType); } public String getRegionDirection() { @@ -168,10 +169,6 @@ public TravelerInfoType getFrameType() { return frameType; } - public void setFrameType(TravelerInfoType frameType) { - this.frameType = frameType; - } - public short getDoNotUse1() { return doNotUse1; } diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java b/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java index 120d4829e..4ac6a6d50 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java @@ -114,11 +114,11 @@ public void InjectDependencies(EmailProps _emailProps, OdeProps _odeProps, TimGe DateTimeFormatter utcformatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); public WydotTravelerInputData createTim(WydotTim wydotTim, String timTypeStr, String startDateTime, - String endDateTime, TravelerInfoType frameType, List allMileposts, + String endDateTime, List allMileposts, List reducedMileposts, Milepost anchor, String dotGnisId) { // build base TIM - WydotTravelerInputData timToSend = createBaseTimUtil.buildTim(wydotTim, genProps, frameType, + WydotTravelerInputData timToSend = createBaseTimUtil.buildTim(wydotTim, genProps, allMileposts, reducedMileposts, anchor); if (timToSend == null) { diff --git a/logger-kafka-consumer/src/main/java/com/trihydro/loggerkafkaconsumer/app/services/DataFrameService.java b/logger-kafka-consumer/src/main/java/com/trihydro/loggerkafkaconsumer/app/services/DataFrameService.java index 0506ac69c..93f6ae58e 100644 --- a/logger-kafka-consumer/src/main/java/com/trihydro/loggerkafkaconsumer/app/services/DataFrameService.java +++ b/logger-kafka-consumer/src/main/java/com/trihydro/loggerkafkaconsumer/app/services/DataFrameService.java @@ -18,6 +18,7 @@ import com.trihydro.library.tables.TimDbTables; import us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage.DataFrame; +import us.dot.its.jpo.ode.plugin.j2735.timstorage.FrameType; @Component @Slf4j @@ -48,10 +49,8 @@ public Long AddDataFrame(DataFrame dFrame, Long timId) { } else if (col.equals("SSP_TIM_RIGHTS")) { sqlNullHandler.setShortOrNull(preparedStatement, fieldNum, dFrame.getDoNotUse1()); } else if (col.equals("FRAME_TYPE")) { - Integer ordinal = null; - if (dFrame.getFrameType() != null) { - ordinal = dFrame.getFrameType().ordinal(); - } + // Always assign TravelerInfoType.roadSignage + Integer ordinal = FrameType.TravelerInfoType.roadSignage.ordinal(); sqlNullHandler.setIntegerOrNull(preparedStatement, fieldNum, ordinal); } else if (col.equals("DURATION_TIME")) { sqlNullHandler.setIntegerOrNull(preparedStatement, fieldNum, dFrame.getDurationTime()); diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java index 093b3c88c..0291589f8 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java @@ -636,7 +636,7 @@ protected ControllerResult validateInputBowr(WydotTimBowr tim) { } public void processRequest(WydotTim wydotTim, TimType timType, String startDateTime, - String endDateTime, Integer pk, TravelerInfoType frameType) { + String endDateTime, Integer pk) { if (wydotTim.getDirection().equalsIgnoreCase("b")) { var iTim = wydotTim.copy(); @@ -644,11 +644,11 @@ public void processRequest(WydotTim wydotTim, TimType timType, String startDateT iTim.setDirection("I"); dTim.setDirection("D"); // I - expireReduceCreateSendTims(iTim, timType, startDateTime, endDateTime, pk, frameType); + expireReduceCreateSendTims(iTim, timType, startDateTime, endDateTime, pk); // D - expireReduceCreateSendTims(dTim, timType, startDateTime, endDateTime, pk, frameType); + expireReduceCreateSendTims(dTim, timType, startDateTime, endDateTime, pk); } else { - expireReduceCreateSendTims(wydotTim, timType, startDateTime, endDateTime, pk, frameType); + expireReduceCreateSendTims(wydotTim, timType, startDateTime, endDateTime, pk); } } @@ -676,8 +676,7 @@ public List getTimTypes() { } protected void expireReduceCreateSendTims(WydotTim wydotTim, TimType timType, - String startDateTime, String endDateTime, Integer pk, - TravelerInfoType frameType) { + String startDateTime, String endDateTime, Integer pk) { // Clear any existing TIMs with the same client id Long timTypeId = timType != null ? timType.getTimTypeId() : null; var existingTims = @@ -719,20 +718,20 @@ protected void expireReduceCreateSendTims(WydotTim wydotTim, TimType timType, var reducedMileposts = milepostReduction.applyMilepostReductionAlgorithm(milepostsAll, configuration.getPathDistanceLimit()); - createSendTims(wydotTim, timType, startDateTime, endDateTime, pk, frameType, + createSendTims(wydotTim, timType, startDateTime, endDateTime, pk, milepostsAll, reducedMileposts, anchor); } // creates a TIM and sends it to RSUs and Satellite protected void createSendTims(WydotTim wydotTim, TimType timType, String startDateTime, String endDateTime, Integer pk, - TravelerInfoType frameType, List allMileposts, - List reducedMileposts, Milepost anchor) { + List allMileposts, List reducedMileposts, + Milepost anchor) { // create TIM WydotTravelerInputData timToSend = wydotTimService.createTim(wydotTim, timType.getType(), startDateTime, endDateTime, - frameType, allMileposts, reducedMileposts, anchor, configuration.getDotGnisId()); + allMileposts, reducedMileposts, anchor, configuration.getDotGnisId()); if (timToSend == null) { return; diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBowrController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBowrController.java index 5f390a371..5ee7c03cc 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBowrController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBowrController.java @@ -133,8 +133,7 @@ public void run() { // get end time String endTime = wydotTimBowr.getEndDateTime(); - processRequest(tim, getTimType(type), startTime, endTime, null, - TravelerInfoType.advisory); + processRequest(tim, getTimType(type), startTime, endTime, null); } } }).start(); diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimCcController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimCcController.java index 53cca041c..b94adaaa9 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimCcController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimCcController.java @@ -99,8 +99,7 @@ public void processRequestAsync(List wydotTims) { public void run() { var startTime = getStartTime(); for (WydotTim tim : wydotTims) { - processRequest(tim, getTimType(type), startTime, null, null, - TravelerInfoType.advisory); + processRequest(tim, getTimType(type), startTime, null, null); } } }).start(); diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java index b84cdf330..8f4067e39 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java @@ -127,8 +127,7 @@ public void makeTimsAsync(List wydotTims) { var wydotTimIncident = (WydotTimIncident)wydotTim; // set route wydotTim.setRoute(wydotTimIncident.getRoute()); - processRequest(wydotTimIncident, getTimType(type), startTime, null, wydotTimIncident.getPk(), - TravelerInfoType.advisory); + processRequest(wydotTimIncident, getTimType(type), startTime, null, wydotTimIncident.getPk()); } }).start(); } diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimParkingController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimParkingController.java index f8074df0e..a16af5bbe 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimParkingController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimParkingController.java @@ -140,8 +140,7 @@ public void processRequestAsync(List wydotTims) { public void run() { var startTime = getStartTime(); for (WydotTimParking wydotTim : wydotTims) { - processRequest(wydotTim, getTimType(type), startTime, null, null, - TravelerInfoType.advisory); + processRequest(wydotTim, getTimType(type), startTime, null, null); } } }).start(); diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRcController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRcController.java index 85a98fcdc..fef212131 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRcController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRcController.java @@ -170,8 +170,7 @@ public void processRequestAsync(List wydotTims) { new Thread(() -> { var startTime = getStartTime(); for (WydotTim tim : wydotTims) { - processRequest(tim, getTimType(type), startTime, null, null, - TravelerInfoType.advisory); + processRequest(tim, getTimType(type), startTime, null, null); } }).start(); } diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java index 29b92e882..a1222b86f 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java @@ -116,7 +116,7 @@ public void processRequestAsync() { new Thread(() -> { for (var tim : timsToSend) { WydotTimRw timRw = (WydotTimRw) tim; - processRequest(timRw, getTimType(type), timRw.getSchedStart(), timRw.getSchedEnd(), null, TravelerInfoType.advisory); + processRequest(timRw, getTimType(type), timRw.getSchedStart(), timRw.getSchedEnd(), null); } }).start(); diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimVslController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimVslController.java index d25c11e22..d48f6c684 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimVslController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimVslController.java @@ -87,8 +87,7 @@ public void processRequestAsync(List wydotTims) { new Thread(() -> { var startTime = getStartTime(); for (WydotTim tim : wydotTims) { - processRequest(tim, getTimType(type), startTime, null, null, - TravelerInfoType.roadSignage); + processRequest(tim, getTimType(type), startTime, null, null); } }).start(); } From 3755ffdc31313f5092de9de0e63ceb070195cccd Mon Sep 17 00:00:00 2001 From: Paige Monington Date: Mon, 3 Nov 2025 08:57:41 -0700 Subject: [PATCH 151/168] test: adjust unit tests for CTW FrameType requirement setting type to roadSignage --- .../controller/ActiveTimControllerTest.java | 6 ++-- .../helpers/CreateBaseTimUtilTest.java | 26 ++++----------- .../library/service/WydotTimServiceTest.java | 32 ++++++++----------- .../resources/broadcastTim_OdeOutput.json | 2 +- .../mockOdeTravelerInformationMessage.json | 2 +- .../src/test/resources/sdxDecodeResponse.json | 2 +- .../src/test/resources/tim_construction.json | 2 +- .../tim_construction_MultipleRegions.json | 2 +- .../src/test/resources/tim_parking.json | 2 +- .../tim_parking_MultipleRegions.json | 2 +- .../src/test/resources/tim_vsl.json | 2 +- .../geojson-from-ode-tim/sampledata.json | 2 +- .../app/services/DataFrameServiceTest.java | 10 +++--- .../resources/TIM_odeTimStartDateTime.json | 2 +- .../src/test/resources/TIM_odeTim_Rsus.json | 2 +- 15 files changed, 38 insertions(+), 58 deletions(-) diff --git a/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/ActiveTimControllerTest.java b/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/ActiveTimControllerTest.java index bf3a2cb49..3a4b08117 100644 --- a/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/ActiveTimControllerTest.java +++ b/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/ActiveTimControllerTest.java @@ -59,7 +59,6 @@ public void GetExpiringActiveTims_SUCCESS() throws SQLException { // we only set one property to verify its returned when(mockRs.getLong("ACTIVE_TIM_ID")).thenReturn(999L); when(mockRs.getInt(any())).thenReturn(0); - when(mockRs.getInt("FRAME_TYPE")).thenReturn(FrameType.TravelerInfoType.advisory.ordinal()); String selectStatement = "SELECT atim.*, tt.type as tim_type_name, tt.description as tim_type_description"; selectStatement += ", t.msg_cnt, t.url_b, t.is_satellite, t.sat_record_id, t.packet_id"; selectStatement += ", df.data_frame_id, df.frame_type, df.duration_time, df.ssp_tim_rights, df.ssp_location_rights"; @@ -83,7 +82,7 @@ public void GetExpiringActiveTims_SUCCESS() throws SQLException { Assertions.assertEquals(HttpStatus.OK, tums.getStatusCode()); Assertions.assertEquals(1, tums.getBody().size()); Assertions.assertEquals(Long.valueOf(999), tums.getBody().get(0).getActiveTimId()); - Assertions.assertEquals(FrameType.TravelerInfoType.advisory, tums.getBody().get(0).getFrameType()); + Assertions.assertEquals(FrameType.TravelerInfoType.roadSignage, tums.getBody().get(0).getFrameType()); verify(mockStatement).executeQuery(selectStatement); } @@ -125,7 +124,6 @@ public void GetUpdateModelFromActiveTimId_SUCCESS() throws SQLException { // we only set one property to verify its returned when(mockRs.getLong("ACTIVE_TIM_ID")).thenReturn(999L); when(mockRs.getInt(any())).thenReturn(0); - when(mockRs.getInt("FRAME_TYPE")).thenReturn(FrameType.TravelerInfoType.advisory.ordinal()); String selectStatement = "SELECT atim.*, tt.type AS tim_type_name, tt.description AS tim_type_description"; selectStatement += ", t.msg_cnt, t.url_b, t.is_satellite, t.sat_record_id, t.packet_id"; @@ -148,7 +146,7 @@ public void GetUpdateModelFromActiveTimId_SUCCESS() throws SQLException { Assertions.assertEquals(HttpStatus.OK, tum.getStatusCode()); Assertions.assertNotNull(tum.getBody()); Assertions.assertEquals(Long.valueOf(999), tum.getBody().getActiveTimId()); - Assertions.assertEquals(FrameType.TravelerInfoType.advisory, tum.getBody().getFrameType()); + Assertions.assertEquals(FrameType.TravelerInfoType.roadSignage, tum.getBody().getFrameType()); verify(mockStatement).executeQuery(selectStatement); } diff --git a/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CreateBaseTimUtilTest.java b/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CreateBaseTimUtilTest.java index d90f2e878..ef214b4e3 100644 --- a/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CreateBaseTimUtilTest.java +++ b/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CreateBaseTimUtilTest.java @@ -105,10 +105,8 @@ public void buildTim_EndpointSUCCESS() { wydotTim.setItisCodes(itisCodes); wydotTim.setClientId("testclientid"); - var frameType = TravelerInfoType.advisory; - // Act - var data = uut.buildTim(wydotTim, genProps, frameType, allMileposts, milepostsReduced, anchor); + var data = uut.buildTim(wydotTim, genProps, allMileposts, milepostsReduced, anchor); // Assert // validate dataFrame @@ -117,6 +115,7 @@ public void buildTim_EndpointSUCCESS() { Assertions.assertEquals("advisory", dataFrame.getContent()); Assertions.assertEquals(32000, dataFrame.getDurationTime()); Assertions.assertEquals("0", dataFrame.getMsgId().getFurtherInfoID()); + Assertions.assertEquals(TravelerInfoType.roadSignage, dataFrame.getFrameType()); Assertions.assertNull(dataFrame.getMsgId().getRoadSignID()); var region = dataFrame.getRegions()[0]; @@ -125,8 +124,6 @@ public void buildTim_EndpointSUCCESS() { // validate anchor var anchor = region.getAnchorPosition(); Assertions.assertNotNull(anchor); - Assertions.assertEquals(anchor.getLatitude(), anchor.getLatitude()); - Assertions.assertEquals(anchor.getLongitude(), anchor.getLongitude()); // validate path var path = region.getPath(); @@ -155,10 +152,8 @@ public void buildTim_singlePointSUCCESS() { wydotTim.setItisCodes(itisCodes); wydotTim.setClientId("testclientid"); - var frameType = TravelerInfoType.advisory; - // Act - var data = uut.buildTim(wydotTim, genProps, frameType, allMileposts, milepostsReduced, anchor); + var data = uut.buildTim(wydotTim, genProps, allMileposts, milepostsReduced, anchor); // Assert // validate dataFrame @@ -167,6 +162,7 @@ public void buildTim_singlePointSUCCESS() { Assertions.assertEquals("advisory", dataFrame.getContent()); Assertions.assertEquals(32000, dataFrame.getDurationTime()); Assertions.assertEquals("0", dataFrame.getMsgId().getFurtherInfoID()); + Assertions.assertEquals(TravelerInfoType.roadSignage, dataFrame.getFrameType()); Assertions.assertNull(dataFrame.getMsgId().getRoadSignID()); var region = dataFrame.getRegions()[0]; @@ -175,8 +171,6 @@ public void buildTim_singlePointSUCCESS() { // validate anchor var anchor = region.getAnchorPosition(); Assertions.assertNotNull(anchor); - Assertions.assertEquals(anchor.getLatitude(), anchor.getLatitude()); - Assertions.assertEquals(anchor.getLongitude(), anchor.getLongitude()); // validate path var path = region.getPath(); @@ -205,10 +199,8 @@ public void buildTim_singleRegion_SUCCESS() { wydotTim.setItisCodes(itisCodes); wydotTim.setClientId("testclientid"); - var frameType = TravelerInfoType.advisory; - // Act - var data = uut.buildTim(wydotTim, genProps, frameType, allMileposts, milepostsReduced, anchor); + var data = uut.buildTim(wydotTim, genProps, allMileposts, milepostsReduced, anchor); // Assert Assertions.assertEquals(1, data.getTim().getDataframes()[0].getRegions().length); @@ -235,10 +227,8 @@ public void buildTim_twoRegions_SUCCESS() { wydotTim.setItisCodes(itisCodes); wydotTim.setClientId("testclientid"); - var frameType = TravelerInfoType.advisory; - // Act - var data = uut.buildTim(wydotTim, genProps, frameType, allMileposts, milepostsReduced, anchor); + var data = uut.buildTim(wydotTim, genProps, allMileposts, milepostsReduced, anchor); // Assert Assertions.assertEquals(2, data.getTim().getDataframes()[0].getRegions().length); @@ -277,10 +267,8 @@ public void buildTim_threeRegions_SUCCESS() { wydotTim.setItisCodes(itisCodes); wydotTim.setClientId("testclientid"); - var frameType = TravelerInfoType.advisory; - // Act - var data = uut.buildTim(wydotTim, genProps, frameType, allMileposts, milepostsReduced, anchor); + var data = uut.buildTim(wydotTim, genProps, allMileposts, milepostsReduced, anchor); // Assert Assertions.assertEquals(3, data.getTim().getDataframes()[0].getRegions().length); diff --git a/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java b/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java index 854bd9ff7..899956c57 100644 --- a/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java +++ b/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java @@ -141,7 +141,7 @@ private List getActiveTims(boolean isSat) { } private OdeTravelerInformationMessage getMockOdeTravelerInformationMessage() { - String timJson = "{\"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\":{\"furtherInfoID\":\"0\"},\"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.0030982\",\"nodeLat\":\"0.0014562\",\"delta\":\"node-LL3\"},{\"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\"}]}"; + String timJson = "{\"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\":\"roadSignage\",\"msgId\":{\"furtherInfoID\":\"0\"},\"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.0030982\",\"nodeLat\":\"0.0014562\",\"delta\":\"node-LL3\"},{\"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\"}]}"; Gson gson = new Gson(); return gson.fromJson(timJson, OdeTravelerInformationMessage.class); } @@ -223,16 +223,15 @@ public void createTim_ReturnsNull_WhenBuildTimReturnsNull() { String timTypeStr = "A"; String startDateTime = "2023-01-01T00:00:00.000Z"; String endDateTime = "2023-01-01T01:00:00.000Z"; - TravelerInfoType frameType = TravelerInfoType.advisory; List allMileposts = new ArrayList<>(); List reducedMileposts = new ArrayList<>(); Milepost anchor = new Milepost(); String dotGnisId = "1B2843"; - when(mockCreateBaseTimUtil.buildTim(any(), any(), any(), any(), any(), any())).thenReturn(null); + when(mockCreateBaseTimUtil.buildTim(any(), any(), any(), any(), any())).thenReturn(null); // Act - WydotTravelerInputData result = uut.createTim(new WydotTim(), timTypeStr, startDateTime, endDateTime, frameType, allMileposts, reducedMileposts, anchor, dotGnisId); + WydotTravelerInputData result = uut.createTim(new WydotTim(), timTypeStr, startDateTime, endDateTime, allMileposts, reducedMileposts, anchor, dotGnisId); // Assert assertNull(result); @@ -244,7 +243,6 @@ public void createTim_SetsStartDateTime_WhenProvided() { String timTypeStr = "A"; String startDateTime = "2023-01-01T00:00:00.000Z"; String endDateTime = "2023-01-01T01:00:00.000Z"; - TravelerInfoType frameType = TravelerInfoType.advisory; List allMileposts = new ArrayList<>(); List reducedMileposts = new ArrayList<>(); Milepost anchor = new Milepost(); @@ -252,10 +250,10 @@ public void createTim_SetsStartDateTime_WhenProvided() { WydotTravelerInputData timToSend = getMockWydotTravelerInputDataWithDataFrame(); - when(mockCreateBaseTimUtil.buildTim(any(), any(), any(), any(), any(), any())).thenReturn(timToSend); + when(mockCreateBaseTimUtil.buildTim(any(), any(), any(), any(), any())).thenReturn(timToSend); // Act - WydotTravelerInputData result = uut.createTim(new WydotTim(), timTypeStr, startDateTime, endDateTime, frameType, allMileposts, reducedMileposts, anchor, dotGnisId); + WydotTravelerInputData result = uut.createTim(new WydotTim(), timTypeStr, startDateTime, endDateTime, allMileposts, reducedMileposts, anchor, dotGnisId); // Assert assertEquals(startDateTime, result.getTim().getDataframes()[0].getStartDateTime()); @@ -267,7 +265,6 @@ public void createTim_SetsDurationTime_WhenEndDateTimeProvided() { String timTypeStr = "A"; String startDateTime = "2023-01-01T00:00:00.000Z"; String endDateTime = "2023-01-01T01:00:00.000Z"; - TravelerInfoType frameType = TravelerInfoType.advisory; List allMileposts = new ArrayList<>(); List reducedMileposts = new ArrayList<>(); Milepost anchor = new Milepost(); @@ -275,11 +272,11 @@ public void createTim_SetsDurationTime_WhenEndDateTimeProvided() { WydotTravelerInputData timToSend = getMockWydotTravelerInputDataWithDataFrame(); - when(mockCreateBaseTimUtil.buildTim(any(), any(), any(), any(), any(), any())).thenReturn(timToSend); + when(mockCreateBaseTimUtil.buildTim(any(), any(), any(), any(), any())).thenReturn(timToSend); when(mockUtility.getMinutesDurationBetweenTwoDates(anyString(), anyString())).thenReturn(60); // Act - WydotTravelerInputData result = uut.createTim(new WydotTim(), timTypeStr, startDateTime, endDateTime, frameType, allMileposts, reducedMileposts, anchor, dotGnisId); + WydotTravelerInputData result = uut.createTim(new WydotTim(), timTypeStr, startDateTime, endDateTime, allMileposts, reducedMileposts, anchor, dotGnisId); // Assert assertEquals(60, result.getTim().getDataframes()[0].getDurationTime()); @@ -291,7 +288,6 @@ public void createTim_SetsDurationTimeTo120_ForParkingTim() { String timTypeStr = "P"; String startDateTime = "2023-01-01T00:00:00.000Z"; String endDateTime = "2023-01-01T01:00:00.000Z"; - TravelerInfoType frameType = TravelerInfoType.advisory; List allMileposts = new ArrayList<>(); List reducedMileposts = new ArrayList<>(); Milepost anchor = new Milepost(); @@ -299,10 +295,10 @@ public void createTim_SetsDurationTimeTo120_ForParkingTim() { WydotTravelerInputData timToSend = getMockWydotTravelerInputDataWithDataFrame(); - when(mockCreateBaseTimUtil.buildTim(any(), any(), any(), any(), any(), any())).thenReturn(timToSend); + when(mockCreateBaseTimUtil.buildTim(any(), any(), any(), any(), any())).thenReturn(timToSend); // Act - WydotTravelerInputData result = uut.createTim(new WydotTim(), timTypeStr, startDateTime, endDateTime, frameType, allMileposts, reducedMileposts, anchor, dotGnisId); + WydotTravelerInputData result = uut.createTim(new WydotTim(), timTypeStr, startDateTime, endDateTime, allMileposts, reducedMileposts, anchor, dotGnisId); // Assert assertEquals(120, result.getTim().getDataframes()[0].getDurationTime()); @@ -314,7 +310,6 @@ public void createTim_SetsRandomPacketIdWithGnisIdPrefix() { String timTypeStr = "A"; String startDateTime = "2023-01-01T00:00:00.000Z"; String endDateTime = "2023-01-01T01:00:00.000Z"; - TravelerInfoType frameType = TravelerInfoType.advisory; List allMileposts = new ArrayList<>(); List reducedMileposts = new ArrayList<>(); Milepost anchor = new Milepost(); @@ -322,10 +317,10 @@ public void createTim_SetsRandomPacketIdWithGnisIdPrefix() { WydotTravelerInputData timToSend = getMockWydotTravelerInputDataWithDataFrame(); - when(mockCreateBaseTimUtil.buildTim(any(), any(), any(), any(), any(), any())).thenReturn(timToSend); + when(mockCreateBaseTimUtil.buildTim(any(), any(), any(), any(), any())).thenReturn(timToSend); // Act - WydotTravelerInputData result = uut.createTim(new WydotTim(), timTypeStr, startDateTime, endDateTime, frameType, allMileposts, reducedMileposts, anchor, dotGnisId); + WydotTravelerInputData result = uut.createTim(new WydotTim(), timTypeStr, startDateTime, endDateTime, allMileposts, reducedMileposts, anchor, dotGnisId); // Assert assertNotNull(result.getTim().getPacketID()); @@ -340,7 +335,6 @@ public void createTim_ThrowsExceptionPacketIdUnsetGNISId() { String timTypeStr = "A"; String startDateTime = "2023-01-01T00:00:00.000Z"; String endDateTime = "2023-01-01T01:00:00.000Z"; - TravelerInfoType frameType = TravelerInfoType.advisory; List allMileposts = new ArrayList<>(); List reducedMileposts = new ArrayList<>(); Milepost anchor = new Milepost(); @@ -348,11 +342,11 @@ public void createTim_ThrowsExceptionPacketIdUnsetGNISId() { WydotTravelerInputData timToSend = getMockWydotTravelerInputDataWithDataFrame(); - when(mockCreateBaseTimUtil.buildTim(any(), any(), any(), any(), any(), any())).thenReturn(timToSend); + when(mockCreateBaseTimUtil.buildTim(any(), any(), any(), any(), any())).thenReturn(timToSend); // Act & Assert assertThrows(IllegalStateException.class, () -> { - uut.createTim(new WydotTim(), timTypeStr, startDateTime, endDateTime, frameType, allMileposts, reducedMileposts, anchor, dotGnisId); + uut.createTim(new WydotTim(), timTypeStr, startDateTime, endDateTime, allMileposts, reducedMileposts, anchor, dotGnisId); }); } diff --git a/cv-data-service-library/src/test/resources/broadcastTim_OdeOutput.json b/cv-data-service-library/src/test/resources/broadcastTim_OdeOutput.json index 6558c2134..c70a0362c 100644 --- a/cv-data-service-library/src/test/resources/broadcastTim_OdeOutput.json +++ b/cv-data-service-library/src/test/resources/broadcastTim_OdeOutput.json @@ -23,7 +23,7 @@ "dataframes": [ { "doNotUse1": 0, - "frameType": "advisory", + "frameType": "roadSignage", "msgId": { "furtherInfoID": "CDEF" }, diff --git a/cv-data-service-library/src/test/resources/com/trihydro/library/service/mockOdeTravelerInformationMessage.json b/cv-data-service-library/src/test/resources/com/trihydro/library/service/mockOdeTravelerInformationMessage.json index e350b63ef..7d00cbb01 100644 --- a/cv-data-service-library/src/test/resources/com/trihydro/library/service/mockOdeTravelerInformationMessage.json +++ b/cv-data-service-library/src/test/resources/com/trihydro/library/service/mockOdeTravelerInformationMessage.json @@ -8,7 +8,7 @@ "startDateTime": "2017-08-02T22:25:00.000Z", "durationTime": 1, "doNotUse1": "0", - "frameType": "advisory", + "frameType": "roadSignage", "msgId": { "furtherInfoID": "0" }, diff --git a/cv-data-service-library/src/test/resources/sdxDecodeResponse.json b/cv-data-service-library/src/test/resources/sdxDecodeResponse.json index 1102aa065..af7e8d397 100644 --- a/cv-data-service-library/src/test/resources/sdxDecodeResponse.json +++ b/cv-data-service-library/src/test/resources/sdxDecodeResponse.json @@ -1,4 +1,4 @@ { "messageType": "MessageFrame", - "decodedMessage": "3113469004null0020194690043200050westbound_I80_39.9_53.31_SAT-4035A5DF_RC_LYMI80EGRAD00414344751-11010514253270000000011111100000-1048300445417415787-1101068786414338729-1048297813417401082-1101173822414302517-1048296846417313218-1101278808414263469-1048334156417231472-1101362065414212124-1048363596417151273-1048348231417067803-1101430219414153700-1101515051414095801-1048292665416990008-1101609734414047121-1048303785416903264-1101704290413998478-1048330081416818875-1101798529413950074-1048362115416736381-1048394037416654255-1101901550413914121-1102014424413891332-1048426742416569080-1102126907413868840-1048459137416484285-1102235582413840132-1048492892416400669-1102332568413793094-1048526150416318091-1048559229416236049-1102434259413752451-1102543983413731407-1048592545416153296-1102655116413714865-1048625771416070802-1102767179413702216-1048658799415988821-1102881705413689256-1048694127415905527-1048732305415821992-1102996201413671479-1103105581413647716-1048769216415741004-1103216030413622307-1048806392415659600-1103325763413587617-1048843990415577334-11033794134135705070058955907null" + "decodedMessage": "3113469004null0020194690043200050westbound_I80_39.9_53.31_SAT-4035A5DF_RC_LYMI80EGRAD00414344751-11010514253270000000011111100000-1048300445417415787-1101068786414338729-1048297813417401082-1101173822414302517-1048296846417313218-1101278808414263469-1048334156417231472-1101362065414212124-1048363596417151273-1048348231417067803-1101430219414153700-1101515051414095801-1048292665416990008-1101609734414047121-1048303785416903264-1101704290413998478-1048330081416818875-1101798529413950074-1048362115416736381-1048394037416654255-1101901550413914121-1102014424413891332-1048426742416569080-1102126907413868840-1048459137416484285-1102235582413840132-1048492892416400669-1102332568413793094-1048526150416318091-1048559229416236049-1102434259413752451-1102543983413731407-1048592545416153296-1102655116413714865-1048625771416070802-1102767179413702216-1048658799415988821-1102881705413689256-1048694127415905527-1048732305415821992-1102996201413671479-1103105581413647716-1048769216415741004-1103216030413622307-1048806392415659600-1103325763413587617-1048843990415577334-11033794134135705070058955907null" } diff --git a/cv-data-service-library/src/test/resources/tim_construction.json b/cv-data-service-library/src/test/resources/tim_construction.json index 8594cc3fb..96339e630 100644 --- a/cv-data-service-library/src/test/resources/tim_construction.json +++ b/cv-data-service-library/src/test/resources/tim_construction.json @@ -37,7 +37,7 @@ "dataFrames": [ { "doNotUse1": 0, - "frameType": "advisory", + "frameType": "roadSignage", "msgId": { "furtherInfoID": "0" }, diff --git a/cv-data-service-library/src/test/resources/tim_construction_MultipleRegions.json b/cv-data-service-library/src/test/resources/tim_construction_MultipleRegions.json index 5661c16de..42187fc97 100644 --- a/cv-data-service-library/src/test/resources/tim_construction_MultipleRegions.json +++ b/cv-data-service-library/src/test/resources/tim_construction_MultipleRegions.json @@ -37,7 +37,7 @@ "dataFrames": [ { "doNotUse1": 0, - "frameType": "advisory", + "frameType": "roadSignage", "msgId": { "furtherInfoID": "0" }, diff --git a/cv-data-service-library/src/test/resources/tim_parking.json b/cv-data-service-library/src/test/resources/tim_parking.json index e96e1cb20..08625af36 100644 --- a/cv-data-service-library/src/test/resources/tim_parking.json +++ b/cv-data-service-library/src/test/resources/tim_parking.json @@ -37,7 +37,7 @@ "dataFrames": [ { "doNotUse1": 0, - "frameType": "advisory", + "frameType": "roadSignage", "msgId": { "furtherInfoID": "0" }, diff --git a/cv-data-service-library/src/test/resources/tim_parking_MultipleRegions.json b/cv-data-service-library/src/test/resources/tim_parking_MultipleRegions.json index 34b291a81..5e1bbaff4 100644 --- a/cv-data-service-library/src/test/resources/tim_parking_MultipleRegions.json +++ b/cv-data-service-library/src/test/resources/tim_parking_MultipleRegions.json @@ -155,7 +155,7 @@ "url": "null", "doNotUse1": 0, "doNotUse2": 0, - "frameType": "advisory", + "frameType": "roadSignage", "startTime": 117800 } ], diff --git a/cv-data-service-library/src/test/resources/tim_vsl.json b/cv-data-service-library/src/test/resources/tim_vsl.json index 881717ad8..151554b4b 100644 --- a/cv-data-service-library/src/test/resources/tim_vsl.json +++ b/cv-data-service-library/src/test/resources/tim_vsl.json @@ -37,7 +37,7 @@ "dataFrames": [ { "doNotUse1": 0, - "frameType": "advisory", + "frameType": "roadSignage", "msgId": { "furtherInfoID": "0" }, diff --git a/developer-tools/geojson-from-ode-tim/sampledata.json b/developer-tools/geojson-from-ode-tim/sampledata.json index fab46f9c3..42dc99378 100644 --- a/developer-tools/geojson-from-ode-tim/sampledata.json +++ b/developer-tools/geojson-from-ode-tim/sampledata.json @@ -22,7 +22,7 @@ "dataframes": [ { "doNotUse1": 0, - "frameType": "advisory", + "frameType": "roadSignage", "msgId": { "furtherInfoID": "0" }, diff --git a/logger-kafka-consumer/src/test/java/com/trihydro/loggerkafkaconsumer/app/services/DataFrameServiceTest.java b/logger-kafka-consumer/src/test/java/com/trihydro/loggerkafkaconsumer/app/services/DataFrameServiceTest.java index 663951b0d..ee1b98393 100644 --- a/logger-kafka-consumer/src/test/java/com/trihydro/loggerkafkaconsumer/app/services/DataFrameServiceTest.java +++ b/logger-kafka-consumer/src/test/java/com/trihydro/loggerkafkaconsumer/app/services/DataFrameServiceTest.java @@ -45,13 +45,13 @@ public void AddDataFrame_SUCCESS() throws SQLException, ParseException { Timestamp time = new Timestamp(dt.getTime()); // Act - Long data = uut.AddDataFrame(dFrame, -1l); + Long data = uut.AddDataFrame(dFrame, -1L); // Assert Assertions.assertEquals(Long.valueOf(-1), data); - verify(mockSqlNullHandler).setLongOrNull(mockPreparedStatement, 1, -1l);// TIM_ID + verify(mockSqlNullHandler).setLongOrNull(mockPreparedStatement, 1, -1L);// TIM_ID verify(mockSqlNullHandler).setShortOrNull(mockPreparedStatement, 2, dFrame.getDoNotUse1());// SSP_TIM_RIGHTS & NotUsed - verify(mockSqlNullHandler).setIntegerOrNull(mockPreparedStatement, 3, null);// FRAME_TYPE + verify(mockSqlNullHandler).setShortOrNull(mockPreparedStatement, 2, dFrame.getDoNotUse1());// FRAME_TYPE verify(mockSqlNullHandler).setIntegerOrNull(mockPreparedStatement, 4, dFrame.getDurationTime());// DURATION_TIME verify(mockSqlNullHandler).setIntegerOrNull(mockPreparedStatement, 5, dFrame.getPriority());// PRIORITY verify(mockSqlNullHandler).setShortOrNull(mockPreparedStatement, 6, dFrame.getDoNotUse2());// SSP_LOCATION_RIGHTS & NotUsed1 @@ -69,10 +69,10 @@ public void AddDataFrame_FAIL() throws SQLException, ParseException { // Arrange DataFrame dFrame = new DataFrame(); dFrame.setStartDateTime("2020-02-03T16:00Z"); - doThrow(new SQLException()).when(mockSqlNullHandler).setLongOrNull(mockPreparedStatement, 1, -1l); + doThrow(new SQLException()).when(mockSqlNullHandler).setLongOrNull(mockPreparedStatement, 1, -1L); // Act - Long data = uut.AddDataFrame(dFrame, -1l); + Long data = uut.AddDataFrame(dFrame, -1L); // Assert Assertions.assertEquals(Long.valueOf(0), data); diff --git a/logger-kafka-consumer/src/test/resources/TIM_odeTimStartDateTime.json b/logger-kafka-consumer/src/test/resources/TIM_odeTimStartDateTime.json index b8225015d..dd9dcef78 100644 --- a/logger-kafka-consumer/src/test/resources/TIM_odeTimStartDateTime.json +++ b/logger-kafka-consumer/src/test/resources/TIM_odeTimStartDateTime.json @@ -274,7 +274,7 @@ "url": null, "doNotUse1": 0, "doNotUse2": 0, - "frameType": "advisory", + "frameType": "roadSignage", "startTime": 454054 } ], diff --git a/logger-kafka-consumer/src/test/resources/TIM_odeTim_Rsus.json b/logger-kafka-consumer/src/test/resources/TIM_odeTim_Rsus.json index 562f5ec7d..ef1385977 100644 --- a/logger-kafka-consumer/src/test/resources/TIM_odeTim_Rsus.json +++ b/logger-kafka-consumer/src/test/resources/TIM_odeTim_Rsus.json @@ -58,7 +58,7 @@ ] }, "durationTime": 32000, - "frameType": "advisory", + "frameType": "roadSignage", "msgId": { "furtherInfoID": "0" }, From f37283e29ced70df072305b5717b6b0496f3284d Mon Sep 17 00:00:00 2001 From: Paige Monington Date: Mon, 3 Nov 2025 09:24:35 -0700 Subject: [PATCH 152/168] chore: remove unused imports --- .../cvdatacontroller/controller/ActiveTimController.java | 1 - .../com/trihydro/library/helpers/CreateBaseTimUtil.java | 1 - .../trihydro/library/helpers/JsonToJavaConverter.java | 6 +++--- .../com/trihydro/library/service/WydotTimService.java | 1 - .../odewrapper/controller/WydotTimBaseController.java | 2 -- .../odewrapper/controller/WydotTimBowrController.java | 1 - .../odewrapper/controller/WydotTimCcController.java | 1 - .../controller/WydotTimIncidentController.java | 1 - .../odewrapper/controller/WydotTimParkingController.java | 9 ++------- .../odewrapper/controller/WydotTimRcController.java | 1 - .../odewrapper/controller/WydotTimRwController.java | 1 - .../odewrapper/controller/WydotTimVslController.java | 1 - 12 files changed, 5 insertions(+), 21 deletions(-) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java index 3434ca210..26afc2d6a 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java @@ -43,7 +43,6 @@ import org.springframework.web.client.HttpServerErrorException; import springfox.documentation.annotations.ApiIgnore; -import us.dot.its.jpo.ode.plugin.j2735.timstorage.FrameType.TravelerInfoType; @CrossOrigin @RestController diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CreateBaseTimUtil.java b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CreateBaseTimUtil.java index 99bf4b87f..fe499c49a 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CreateBaseTimUtil.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CreateBaseTimUtil.java @@ -40,7 +40,6 @@ public void InjectDependencies(Utility _utility) { * * @param wydotTim The WydotTim object containing the data for the TIM. * @param genProps The TimGenerationProps object containing the generation properties. - * @param frameType The TravelerInfoType object representing the frame type of the TIM. * @param allMileposts The list of Milepost objects representing all mileposts. * @param reducedMileposts The list of Milepost objects representing reduced mileposts. * @param anchor The Milepost object representing the anchor milepost. diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/JsonToJavaConverter.java b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/JsonToJavaConverter.java index 07db6fe08..76824939f 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/JsonToJavaConverter.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/JsonToJavaConverter.java @@ -60,7 +60,7 @@ public OdeLogMetadata convertTimMetadataJsonToJava(String value) { // check for null rxSource for Distress Notifications if (receivedMessageDetailsNode != null) { String rxSource = mapper.treeToValue(receivedMessageDetailsNode.get("rxSource"), String.class); - if (rxSource.equals("")) { + if (rxSource.isEmpty()) { ((ObjectNode) receivedMessageDetailsNode).remove("rxSource"); ((ObjectNode) metaDataNode).replace("receivedMessageDetails", receivedMessageDetailsNode); } @@ -464,7 +464,7 @@ public OdeTimPayload convertTmcTimTopicJsonToJava(String value) { JsonNode timeStampNode = timNode.get("timeStamp"); if (timeStampNode != null) { LocalDateTime timeStampDate = firstDay.atStartOfDay().plus(timeStampNode.asInt(), ChronoUnit.MINUTES); - tim.setTimeStamp(timeStampDate.toString() + "Z"); + tim.setTimeStamp(timeStampDate + "Z"); } JsonNode travelerDataFrameArray = timNode.findValue("dataFrames"); @@ -517,7 +517,7 @@ else if (sequenceArrNode.get("item").get("text") != null) LocalDateTime startDate = firstDay.atStartOfDay().plus(startTimeNode.asInt(), ChronoUnit.MINUTES); - dataFrame.setStartDateTime(startDate.toString() + "Z"); + dataFrame.setStartDateTime(startDate + "Z"); dataFrame.setDurationTime(durationNode.asInt()); dataFrame.setPriority(priorityNode.asInt()); dataFrame.setFrameType(TravelerInfoType.roadSignage); diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java b/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java index 4ac6a6d50..2f3e0291e 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/service/WydotTimService.java @@ -52,7 +52,6 @@ import us.dot.its.jpo.ode.plugin.j2735.OdeGeoRegion; import us.dot.its.jpo.ode.plugin.j2735.OdePosition3D; import us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage.DataFrame; -import us.dot.its.jpo.ode.plugin.j2735.timstorage.FrameType.TravelerInfoType; @Component @Slf4j diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java index 0291589f8..2adef9413 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java @@ -48,8 +48,6 @@ import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Component; -import us.dot.its.jpo.ode.plugin.j2735.timstorage.FrameType.TravelerInfoType; - @Component @Slf4j public abstract class WydotTimBaseController { diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBowrController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBowrController.java index 5ee7c03cc..d50ca5fb3 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBowrController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBowrController.java @@ -31,7 +31,6 @@ import org.springframework.web.bind.annotation.RestController; import io.swagger.annotations.Api; -import us.dot.its.jpo.ode.plugin.j2735.timstorage.FrameType.TravelerInfoType; @CrossOrigin @RestController diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimCcController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimCcController.java index b94adaaa9..a66df66b8 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimCcController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimCcController.java @@ -32,7 +32,6 @@ import org.springframework.web.bind.annotation.RestController; import io.swagger.annotations.Api; -import us.dot.its.jpo.ode.plugin.j2735.timstorage.FrameType.TravelerInfoType; @CrossOrigin @RestController diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java index 8f4067e39..c26992588 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimIncidentController.java @@ -19,7 +19,6 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; -import us.dot.its.jpo.ode.plugin.j2735.timstorage.FrameType.TravelerInfoType; import java.text.DateFormat; import java.text.SimpleDateFormat; diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimParkingController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimParkingController.java index a16af5bbe..eb599310e 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimParkingController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimParkingController.java @@ -34,7 +34,6 @@ import org.springframework.web.bind.annotation.RestController; import io.swagger.annotations.Api; -import us.dot.its.jpo.ode.plugin.j2735.timstorage.FrameType.TravelerInfoType; @CrossOrigin @RestController @@ -93,18 +92,14 @@ public ResponseEntity createParkingTim(@RequestBody TimParkingList timPa public Collection getParkingTims() { // clear TIM - List activeTims = wydotTimService.selectTimsByType("P"); - - return activeTims; + return wydotTimService.selectTimsByType("P"); } @RequestMapping(value = "/parking-tim/{clientId}", method = RequestMethod.GET, headers = "Accept=application/json") public Collection getParkingTimById(@PathVariable String clientId) { // clear TIM - List activeTims = wydotTimService.selectTimByClientId("P", clientId); - - return activeTims; + return wydotTimService.selectTimByClientId("P", clientId); } @RequestMapping(value = "/parking-tim/itis-codes/{id}", method = RequestMethod.GET, headers = "Accept=application/json") diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRcController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRcController.java index fef212131..e2d5a39b6 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRcController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRcController.java @@ -35,7 +35,6 @@ import com.trihydro.library.service.MilepostService; import io.swagger.annotations.Api; -import us.dot.its.jpo.ode.plugin.j2735.timstorage.FrameType.TravelerInfoType; @CrossOrigin @RestController diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java index a1222b86f..d06b21e46 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimRwController.java @@ -34,7 +34,6 @@ import com.trihydro.library.service.MilepostService; import io.swagger.annotations.Api; -import us.dot.its.jpo.ode.plugin.j2735.timstorage.FrameType.TravelerInfoType; @CrossOrigin @RestController diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimVslController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimVslController.java index d48f6c684..ede3046e3 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimVslController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimVslController.java @@ -18,7 +18,6 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; -import us.dot.its.jpo.ode.plugin.j2735.timstorage.FrameType.TravelerInfoType; import java.text.DateFormat; import java.text.SimpleDateFormat; From 3c37925830347193630e09ebbe14de5d892cb1ce Mon Sep 17 00:00:00 2001 From: pmonington <121187998+pmonington@users.noreply.github.com> Date: Mon, 3 Nov 2025 10:10:14 -0700 Subject: [PATCH 153/168] chore: clean code by preventing unnecessary variable assignments Co-authored-by: Matt Cook --- .../odewrapper/controller/WydotTimBaseController.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java index 66187b0ff..1beecc2f4 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java @@ -441,11 +441,18 @@ protected ControllerResult validateInputVsl(WydotTimVsl tim) { // set itis codes List itisCodes = new ArrayList<>(); + try { + List itisCodes = new ArrayList<>(); try { itisCodes= setItisCodes.setItisCodesVsl(tim); if (itisCodes.isEmpty()) { resultMessages.add("No ITIS codes found"); } + result.setItisCodes(itisCodes); + tim.setItisCodes(itisCodes); + if (itisCodes.isEmpty()) { + resultMessages.add("No ITIS codes found"); + } } catch (Exception e) { resultMessages.add("Could not determine speed for speed limit tim"); } From 4232a6d2b6338f78d6699ab7ede971d3ee879a72 Mon Sep 17 00:00:00 2001 From: Paige Monington Date: Mon, 3 Nov 2025 10:14:05 -0700 Subject: [PATCH 154/168] chore: clean code by moving const number to const variable --- .../java/com/trihydro/odewrapper/helpers/SetItisCodes.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java index 73410821d..2b8723db8 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/helpers/SetItisCodes.java @@ -36,6 +36,8 @@ public class SetItisCodes { private final String REDUCED_ITIS_CODE = "12302"; private final String AHEAD_ITIS_CODE = "13569"; + private static final int SMALL_ITIS_CODE_MIN = 12544; + @Autowired public SetItisCodes(ItisCodeService _itisCodeService, IncidentChoicesService _incidentChoicesService) { itisCodeService = _itisCodeService; @@ -197,9 +199,7 @@ public List setItisCodesVsl(WydotTimVsl wydotTim) { // J2540 small number ITIS codes start at 12,544 and increment by 1 to represent each number up to 255. // To covert speed to an ITIS code, adding 12,544 is enough. - items.add(Integer.toString( - Optional.ofNullable(wydotTim.getSpeed()).orElse(0) + 12544 - )); + items.add(Integer.toString(wydotTim.getSpeed() + SMALL_ITIS_CODE_MIN)); // mph itis code allItisCodes.stream().filter(x -> x.getDescription().equals("mph")).findFirst().ifPresent(mph -> items.add(mph.getItisCode().toString())); From dfbc66bd87bb6518871c3841a9be10f71f59bcf8 Mon Sep 17 00:00:00 2001 From: Paige Monington Date: Mon, 3 Nov 2025 10:36:39 -0700 Subject: [PATCH 155/168] test: fix dataframe set to roadsignage for DataFrameServiceTest --- .../loggerkafkaconsumer/app/services/DataFrameServiceTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logger-kafka-consumer/src/test/java/com/trihydro/loggerkafkaconsumer/app/services/DataFrameServiceTest.java b/logger-kafka-consumer/src/test/java/com/trihydro/loggerkafkaconsumer/app/services/DataFrameServiceTest.java index ee1b98393..471d472d0 100644 --- a/logger-kafka-consumer/src/test/java/com/trihydro/loggerkafkaconsumer/app/services/DataFrameServiceTest.java +++ b/logger-kafka-consumer/src/test/java/com/trihydro/loggerkafkaconsumer/app/services/DataFrameServiceTest.java @@ -51,7 +51,7 @@ public void AddDataFrame_SUCCESS() throws SQLException, ParseException { Assertions.assertEquals(Long.valueOf(-1), data); verify(mockSqlNullHandler).setLongOrNull(mockPreparedStatement, 1, -1L);// TIM_ID verify(mockSqlNullHandler).setShortOrNull(mockPreparedStatement, 2, dFrame.getDoNotUse1());// SSP_TIM_RIGHTS & NotUsed - verify(mockSqlNullHandler).setShortOrNull(mockPreparedStatement, 2, dFrame.getDoNotUse1());// FRAME_TYPE + verify(mockSqlNullHandler).setIntegerOrNull(mockPreparedStatement, 3, 2);// FRAME_TYPE is RoadSignage verify(mockSqlNullHandler).setIntegerOrNull(mockPreparedStatement, 4, dFrame.getDurationTime());// DURATION_TIME verify(mockSqlNullHandler).setIntegerOrNull(mockPreparedStatement, 5, dFrame.getPriority());// PRIORITY verify(mockSqlNullHandler).setShortOrNull(mockPreparedStatement, 6, dFrame.getDoNotUse2());// SSP_LOCATION_RIGHTS & NotUsed1 From 1eab1eb6ae494336db471857f99a104d097c2222 Mon Sep 17 00:00:00 2001 From: Paige Monington Date: Mon, 3 Nov 2025 11:20:29 -0700 Subject: [PATCH 156/168] fix: adjust the itis codes to remove redundant try block --- .../odewrapper/controller/WydotTimBaseController.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java index 99fc7ef39..f2d09d880 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java @@ -437,10 +437,8 @@ protected ControllerResult validateInputVsl(WydotTimVsl tim) { } // set itis codes - List itisCodes = new ArrayList<>(); - try { - List itisCodes = new ArrayList<>(); try { + List itisCodes; itisCodes= setItisCodes.setItisCodesVsl(tim); if (itisCodes.isEmpty()) { resultMessages.add("No ITIS codes found"); @@ -453,8 +451,6 @@ protected ControllerResult validateInputVsl(WydotTimVsl tim) { } catch (Exception e) { resultMessages.add("Could not determine speed for speed limit tim"); } - result.setItisCodes(itisCodes); - tim.setItisCodes(itisCodes); result.setResultMessages(resultMessages); return result; From 6676228ebc3c4a3bbd98e6c67083776ed03ecee9 Mon Sep 17 00:00:00 2001 From: Paige Monington Date: Mon, 3 Nov 2025 12:24:00 -0700 Subject: [PATCH 157/168] fix: adjust sql RSU query to have proper syntax --- .../com/trihydro/cvdatacontroller/controller/RsuController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/RsuController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/RsuController.java index 7fad3078c..a238506e1 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/RsuController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/RsuController.java @@ -198,7 +198,7 @@ public ResponseEntity> SelectRsusByRoute(@PathVariable Strin // select all RSUs from RSU table rs = statement.executeQuery( - "select rsu_id, ST_X(ST_AsText(geography)) as longitude, ST_Y(ST_AsText(geography)) as latitude, ipv4_address, primary_route, milepost from rsus where primary_route like %'%" + route + "%'"); + "select rsu_id, ST_X(ST_AsText(geography)) as longitude, ST_Y(ST_AsText(geography)) as latitude, ipv4_address, primary_route, milepost from rsus where primary_route like '%" + route + "%'"); while (rs.next()) { WydotRsu rsu = new WydotRsu(); From 29a6aee2b417f8b3d8eaedfb8bc76c87a1f355ef Mon Sep 17 00:00:00 2001 From: Paige Monington Date: Mon, 3 Nov 2025 13:40:16 -0700 Subject: [PATCH 158/168] fix: adjust gnis configuration for local deployments --- docker-compose.yml | 2 +- local-deployment/docker-compose.yml | 1 + local-deployment/sample.env | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 5fb020bac..b6f43e9ce 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -12,7 +12,7 @@ services: CONFIG_MAXIMUM_POOL_SIZE: ${WRAPPER_CONFIG_MAXIMUM_POOL_SIZE} CONFIG_CONNECTION_TIMEOUT: ${WRAPPER_CONFIG_CONNECTION_TIMEOUT} CONFIG_ENV: ${WRAPPER_CONFIG_ENV} - CONFIG_DB_DOT_GNIS_ID: ${WRAPPER_CONFIG_DOT_GNIS_ID} + CONFIG_DOT_GNIS_ID: ${WRAPPER_CONFIG_DOT_GNIS_ID} CONFIG_SDW_TTL: ${WRAPPER_CONFIG_SDW_TTL} CONFIG_SDW_REST_URL: ${SDW_REST_URL} CONFIG_SDW_API_KEY: ${SDW_API_KEY} diff --git a/local-deployment/docker-compose.yml b/local-deployment/docker-compose.yml index 49da1467d..0f20b98db 100644 --- a/local-deployment/docker-compose.yml +++ b/local-deployment/docker-compose.yml @@ -221,6 +221,7 @@ services: CONFIG_HTTP_LOGGING_MAX_SIZE: 2000 CONFIG_RSU_ROUTES: ${RSU_ROUTES} CONFIG_POINT_INCIDENT_BUFFER_MILES: 1 + CONFIG_DOT_GNIS_ID: ${DOT_GNIS_ID} LOGGING_LEVEL_COM_TRIHYDRO: ${LOGGING_LEVEL_COM_TRIHYDRO} ports: - "7777:7777" diff --git a/local-deployment/sample.env b/local-deployment/sample.env index 3d2c7497b..8fc7518f4 100644 --- a/local-deployment/sample.env +++ b/local-deployment/sample.env @@ -6,6 +6,7 @@ POSTGRES_DB_HOSTNAME=postgres POSTGRES_DB_NAME=postgres POSTGRES_USER=username POSTGRES_PASSWORD=password +DOT_GNIS_ID=1B2843 MONGO_USER=username MONGO_PASSWORD=password RSU_ROUTES="route1, route2" From 0e1475e78ab21dc8aff1c3167309286c185bc516 Mon Sep 17 00:00:00 2001 From: Paige Monington Date: Mon, 3 Nov 2025 13:44:34 -0700 Subject: [PATCH 159/168] chore: remove unused db configurations from ode wrapper --- docker-compose.yml | 3 --- local-deployment/docker-compose.yml | 3 --- sample.env | 3 --- 3 files changed, 9 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index b6f43e9ce..e6ff704b5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,9 +6,6 @@ services: environment: SERVER_PORT: ${WRAPPER_SERVER_PORT} CONFIG_ODE_URL: ${WRAPPER_CONFIG_ODE_URL} - CONFIG_DB_URL: ${WRAPPER_CONFIG_DB_URL} - CONFIG_DB_USERNAME: ${WRAPPER_CONFIG_DB_USERNAME} - CONFIG_DB_PASSWORD: ${WRAPPER_CONFIG_DB_PASSWORD} CONFIG_MAXIMUM_POOL_SIZE: ${WRAPPER_CONFIG_MAXIMUM_POOL_SIZE} CONFIG_CONNECTION_TIMEOUT: ${WRAPPER_CONFIG_CONNECTION_TIMEOUT} CONFIG_ENV: ${WRAPPER_CONFIG_ENV} diff --git a/local-deployment/docker-compose.yml b/local-deployment/docker-compose.yml index 0f20b98db..30b02640c 100644 --- a/local-deployment/docker-compose.yml +++ b/local-deployment/docker-compose.yml @@ -202,9 +202,6 @@ services: environment: SERVER_PORT: 7777 CONFIG_ODE_URL: http://ode:8080 - CONFIG_DB_URL: jdbc:postgresql://${POSTGRES_DB_HOSTNAME}:5432/${POSTGRES_DB_NAME}?user=${POSTGRES_USER} - CONFIG_DB_USERNAME: ${POSTGRES_USER} - CONFIG_DB_PASSWORD: ${POSTGRES_PASSWORD} CONFIG_MAXIMUM_POOL_SIZE: 7 CONFIG_CONNECTION_TIMEOUT: 300000 CONFIG_ENV: local diff --git a/sample.env b/sample.env index 5de36c0ff..25e1207f9 100644 --- a/sample.env +++ b/sample.env @@ -83,9 +83,6 @@ MONGO_FROM_EMAIL=support@example.com # ODE Wrapper WRAPPER_SERVER_PORT=7777 WRAPPER_CONFIG_ODE_URL=http://ode-url:8080 -WRAPPER_CONFIG_DB_URL=jdbc:postgresql://localhost:5432/dbname?user=username -WRAPPER_CONFIG_DB_USERNAME=username -WRAPPER_CONFIG_DB_PASSWORD= WRAPPER_CONFIG_MAXIMUM_POOL_SIZE=7 WRAPPER_CONFIG_CONNECTION_TIMEOUT=300000 WRAPPER_CONFIG_ENV=dev From ee2a7f66c531a4e7086aa7e7131681467cc007b3 Mon Sep 17 00:00:00 2001 From: Paige Monington Date: Mon, 3 Nov 2025 13:46:59 -0700 Subject: [PATCH 160/168] fix: adjust sql RSU query to have proper syntax --- .../trihydro/cvdatacontroller/controller/RsuController.java | 2 +- .../cvdatacontroller/controller/RsuControllerTest.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/RsuController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/RsuController.java index 7fad3078c..a238506e1 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/RsuController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/RsuController.java @@ -198,7 +198,7 @@ public ResponseEntity> SelectRsusByRoute(@PathVariable Strin // select all RSUs from RSU table rs = statement.executeQuery( - "select rsu_id, ST_X(ST_AsText(geography)) as longitude, ST_Y(ST_AsText(geography)) as latitude, ipv4_address, primary_route, milepost from rsus where primary_route like %'%" + route + "%'"); + "select rsu_id, ST_X(ST_AsText(geography)) as longitude, ST_Y(ST_AsText(geography)) as latitude, ipv4_address, primary_route, milepost from rsus where primary_route like '%" + route + "%'"); while (rs.next()) { WydotRsu rsu = new WydotRsu(); diff --git a/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/RsuControllerTest.java b/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/RsuControllerTest.java index d2dcacb32..e220dc46e 100644 --- a/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/RsuControllerTest.java +++ b/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/RsuControllerTest.java @@ -110,7 +110,7 @@ public void SelectRsusByRoute_SUCCESS() throws SQLException { String route = "I80"; String selectStatement = "select rsu_id, ST_X(ST_AsText(geography)) as longitude, " + "ST_Y(ST_AsText(geography)) as latitude, ipv4_address, primary_route, milepost from rsus " + - "where primary_route like %'%" + route + "%'"; + "where primary_route like '%" + route + "%'"; // Act ResponseEntity> data = uut.SelectRsusByRoute(route); @@ -134,7 +134,7 @@ public void SelectRsusByRoute_FAIL() throws SQLException { String route = "I80"; String selectStatement = "select rsu_id, ST_X(ST_AsText(geography)) as longitude, " + "ST_Y(ST_AsText(geography)) as latitude, ipv4_address, primary_route, milepost from rsus " + - "where primary_route like %'%" + route + "%'"; + "where primary_route like '%" + route + "%'"; doThrow(new SQLException()).when(mockRs).getInt("RSU_ID"); // Act ResponseEntity> data = uut.SelectRsusByRoute(route); From cd4cd82756a4e4d860f9cda4320c95724cde86d1 Mon Sep 17 00:00:00 2001 From: Paige Monington Date: Mon, 3 Nov 2025 13:47:59 -0700 Subject: [PATCH 161/168] fix: adjust the itis codes to remove redundant try block --- .../odewrapper/controller/WydotTimBaseController.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java index a17dbfea7..48a69ef5e 100644 --- a/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java +++ b/ode-wrapper/src/main/java/com/trihydro/odewrapper/controller/WydotTimBaseController.java @@ -439,10 +439,9 @@ protected ControllerResult validateInputVsl(WydotTimVsl tim) { } // set itis codes - List itisCodes = new ArrayList<>(); - try { - List itisCodes = new ArrayList<>(); + try { + List itisCodes; itisCodes= setItisCodes.setItisCodesVsl(tim); if (itisCodes.isEmpty()) { resultMessages.add("No ITIS codes found"); @@ -455,8 +454,6 @@ protected ControllerResult validateInputVsl(WydotTimVsl tim) { } catch (Exception e) { resultMessages.add("Could not determine speed for speed limit tim"); } - result.setItisCodes(itisCodes); - tim.setItisCodes(itisCodes); result.setResultMessages(resultMessages); return result; From cd66f49bfbd7ecaf595a884e449a9bc3753e432b Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Mon, 3 Nov 2025 14:34:51 -0700 Subject: [PATCH 162/168] fix: update local-deployment compose file to use legacy bitnami image For context, the bitnami/kafka image no longer has any tags. --- local-deployment/docker-compose.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/local-deployment/docker-compose.yml b/local-deployment/docker-compose.yml index 49da1467d..0a469ca57 100644 --- a/local-deployment/docker-compose.yml +++ b/local-deployment/docker-compose.yml @@ -2,7 +2,7 @@ version: "2" services: # external dependencies ---------------------------------------------- kafka: - image: bitnami/kafka:latest + image: bitnamilegacy/kafka:3.8.0 hostname: kafka ports: - "9092:9092" @@ -27,7 +27,7 @@ services: max-file: "5" kafka_init: - image: bitnami/kafka:latest + image: bitnamilegacy/kafka:3.8.0 depends_on: kafka: condition: service_started From 7a559e6e78221f35699f570425b73f93eb4722b6 Mon Sep 17 00:00:00 2001 From: Paige Monington Date: Tue, 4 Nov 2025 10:25:50 -0700 Subject: [PATCH 163/168] fix: remove unused environment variables for ode-wrapper --- docker-compose-cdot-deployment.yml | 6 +----- docker-compose.yml | 2 -- local-deployment/docker-compose.yml | 2 -- sample.env | 2 -- 4 files changed, 1 insertion(+), 11 deletions(-) diff --git a/docker-compose-cdot-deployment.yml b/docker-compose-cdot-deployment.yml index 733de75ce..ce7c34515 100644 --- a/docker-compose-cdot-deployment.yml +++ b/docker-compose-cdot-deployment.yml @@ -5,11 +5,7 @@ services: environment: SERVER_PORT: ${WRAPPER_SERVER_PORT} CONFIG_ODE_URL: ${WRAPPER_CONFIG_ODE_URL} - CONFIG_DB_URL: ${WRAPPER_CONFIG_DB_URL} - CONFIG_DB_USERNAME: ${WRAPPER_CONFIG_DB_USERNAME} - CONFIG_DB_PASSWORD: ${WRAPPER_CONFIG_DB_PASSWORD} - CONFIG_MAXIMUM_POOL_SIZE: ${WRAPPER_CONFIG_MAXIMUM_POOL_SIZE} - CONFIG_CONNECTION_TIMEOUT: ${WRAPPER_CONFIG_CONNECTION_TIMEOUT} + CONFIG_DOT_GNIS_ID: ${WRAPPER_CONFIG_DOT_GNIS_ID} CONFIG_SDW_TTL: ${WRAPPER_CONFIG_SDW_TTL} CONFIG_SDW_REST_URL: ${SDW_REST_URL} CONFIG_SDW_API_KEY: ${SDW_API_KEY} diff --git a/docker-compose.yml b/docker-compose.yml index e6ff704b5..696e0538a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,8 +6,6 @@ services: environment: SERVER_PORT: ${WRAPPER_SERVER_PORT} CONFIG_ODE_URL: ${WRAPPER_CONFIG_ODE_URL} - CONFIG_MAXIMUM_POOL_SIZE: ${WRAPPER_CONFIG_MAXIMUM_POOL_SIZE} - CONFIG_CONNECTION_TIMEOUT: ${WRAPPER_CONFIG_CONNECTION_TIMEOUT} CONFIG_ENV: ${WRAPPER_CONFIG_ENV} CONFIG_DOT_GNIS_ID: ${WRAPPER_CONFIG_DOT_GNIS_ID} CONFIG_SDW_TTL: ${WRAPPER_CONFIG_SDW_TTL} diff --git a/local-deployment/docker-compose.yml b/local-deployment/docker-compose.yml index 43b9e7b1c..d1d5226c4 100644 --- a/local-deployment/docker-compose.yml +++ b/local-deployment/docker-compose.yml @@ -202,8 +202,6 @@ services: environment: SERVER_PORT: 7777 CONFIG_ODE_URL: http://ode:8080 - CONFIG_MAXIMUM_POOL_SIZE: 7 - CONFIG_CONNECTION_TIMEOUT: 300000 CONFIG_ENV: local CONFIG_SDW_TTL: oneday CONFIG_SDW_REST_URL: ${SDW_REST_URL} diff --git a/sample.env b/sample.env index 25e1207f9..ddc0eb886 100644 --- a/sample.env +++ b/sample.env @@ -83,8 +83,6 @@ MONGO_FROM_EMAIL=support@example.com # ODE Wrapper WRAPPER_SERVER_PORT=7777 WRAPPER_CONFIG_ODE_URL=http://ode-url:8080 -WRAPPER_CONFIG_MAXIMUM_POOL_SIZE=7 -WRAPPER_CONFIG_CONNECTION_TIMEOUT=300000 WRAPPER_CONFIG_ENV=dev WRAPPER_CONFIG_DOT_GNIS_ID= WRAPPER_CONFIG_SDW_TTL=oneday From 6a11519dba8784886165fae2ad167831e1e66d04 Mon Sep 17 00:00:00 2001 From: Paige Monington Date: Mon, 10 Nov 2025 10:27:09 -0700 Subject: [PATCH 164/168] fix: set furtherInfoID to octet size 2 in hex for asn1 compliance --- .../java/com/trihydro/library/helpers/CreateBaseTimUtil.java | 5 +++-- .../com/trihydro/library/helpers/TimGenerationHelper.java | 2 +- .../com/trihydro/library/helpers/CreateBaseTimUtilTest.java | 4 ++-- .../com/trihydro/library/service/WydotTimServiceTest.java | 2 +- .../library/service/mockOdeTravelerInformationMessage.json | 2 +- .../src/test/resources/rxMsg_TIM_OdeOutput.json | 2 +- .../src/test/resources/rxMsg_TIM_OdeOutput_Geometry.json | 2 +- .../test/resources/rxMsg_TIM_OdeOutput_MultipleRegions.json | 2 +- .../src/test/resources/rxMsg_TIM_SpeedLimit.json | 2 +- .../src/test/resources/sdxDecodeResponse.json | 2 +- .../src/test/resources/tim_construction.json | 2 +- .../src/test/resources/tim_construction_MultipleRegions.json | 2 +- cv-data-service-library/src/test/resources/tim_parking.json | 2 +- .../src/test/resources/tim_parking_MultipleRegions.json | 2 +- cv-data-service-library/src/test/resources/tim_vsl.json | 2 +- .../src/test/resources/tim_vsl_MultipleRegions.json | 2 +- developer-tools/geojson-from-ode-tim/sampledata.json | 2 +- .../src/test/resources/TIM_odeTimStartDateTime.json | 2 +- .../src/test/resources/TIM_odeTim_Rsus.json | 2 +- .../src/test/resources/rxMsg_TIM_OdeOutput.json | 2 +- .../src/test/resources/rxMsg_TIM_OdeOutput_NullMetadata.json | 2 +- 21 files changed, 24 insertions(+), 23 deletions(-) diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CreateBaseTimUtil.java b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CreateBaseTimUtil.java index eab962ed8..710887620 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CreateBaseTimUtil.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CreateBaseTimUtil.java @@ -77,9 +77,10 @@ public WydotTravelerInputData buildTim(WydotTim wydotTim, TimGenerationProps gen dataFrame.setItems(wydotTim.getItisCodes().toArray(new String[wydotTim.getItisCodes().size()])); // Per CTW guidance, msgId must be populated using furtherInfoID (not roadSignID) - // Since furtherInfoID is not used, set it to the default value of 0 + // Per SAE J2735 (DE_FurtherInfoID), this field is defined as an OCTET STRING (SIZE(2)). + // Since furtherInfoID is not used, set it to two zero bytes (0000) to indicate "unknown or not present" MsgId msgId = new MsgId(); - msgId.setFurtherInfoID("0"); + msgId.setFurtherInfoID("0000"); dataFrame.setMsgId(msgId); // set regions. note that we now support multiple regions in a single TIM package diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/TimGenerationHelper.java b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/TimGenerationHelper.java index 9a4c4c103..76aa515cb 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/TimGenerationHelper.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/TimGenerationHelper.java @@ -832,7 +832,7 @@ private DataFrame getDataFrame(TimUpdateModel aTim, boolean resetStartTimes, // MsgId MsgId msgId = new MsgId(); - msgId.setFurtherInfoID("0"); + msgId.setFurtherInfoID("0000"); // DataFrame DataFrame df = new DataFrame(); diff --git a/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CreateBaseTimUtilTest.java b/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CreateBaseTimUtilTest.java index d90f2e878..1c56fda1f 100644 --- a/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CreateBaseTimUtilTest.java +++ b/cv-data-service-library/src/test/java/com/trihydro/library/helpers/CreateBaseTimUtilTest.java @@ -116,7 +116,7 @@ public void buildTim_EndpointSUCCESS() { Assertions.assertNotNull(dataFrame); Assertions.assertEquals("advisory", dataFrame.getContent()); Assertions.assertEquals(32000, dataFrame.getDurationTime()); - Assertions.assertEquals("0", dataFrame.getMsgId().getFurtherInfoID()); + Assertions.assertEquals("0000", dataFrame.getMsgId().getFurtherInfoID()); Assertions.assertNull(dataFrame.getMsgId().getRoadSignID()); var region = dataFrame.getRegions()[0]; @@ -166,7 +166,7 @@ public void buildTim_singlePointSUCCESS() { Assertions.assertNotNull(dataFrame); Assertions.assertEquals("advisory", dataFrame.getContent()); Assertions.assertEquals(32000, dataFrame.getDurationTime()); - Assertions.assertEquals("0", dataFrame.getMsgId().getFurtherInfoID()); + Assertions.assertEquals("0000", dataFrame.getMsgId().getFurtherInfoID()); Assertions.assertNull(dataFrame.getMsgId().getRoadSignID()); var region = dataFrame.getRegions()[0]; diff --git a/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java b/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java index 854bd9ff7..266217580 100644 --- a/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java +++ b/cv-data-service-library/src/test/java/com/trihydro/library/service/WydotTimServiceTest.java @@ -141,7 +141,7 @@ private List getActiveTims(boolean isSat) { } private OdeTravelerInformationMessage getMockOdeTravelerInformationMessage() { - String timJson = "{\"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\":{\"furtherInfoID\":\"0\"},\"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.0030982\",\"nodeLat\":\"0.0014562\",\"delta\":\"node-LL3\"},{\"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\"}]}"; + String timJson = "{\"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\":{\"furtherInfoID\":\"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.0030982\",\"nodeLat\":\"0.0014562\",\"delta\":\"node-LL3\"},{\"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\"}]}"; Gson gson = new Gson(); return gson.fromJson(timJson, OdeTravelerInformationMessage.class); } diff --git a/cv-data-service-library/src/test/resources/com/trihydro/library/service/mockOdeTravelerInformationMessage.json b/cv-data-service-library/src/test/resources/com/trihydro/library/service/mockOdeTravelerInformationMessage.json index e350b63ef..9bdf9e89c 100644 --- a/cv-data-service-library/src/test/resources/com/trihydro/library/service/mockOdeTravelerInformationMessage.json +++ b/cv-data-service-library/src/test/resources/com/trihydro/library/service/mockOdeTravelerInformationMessage.json @@ -10,7 +10,7 @@ "doNotUse1": "0", "frameType": "advisory", "msgId": { - "furtherInfoID": "0" + "furtherInfoID": "0000" }, "priority": "0", "doNotUse2": "3", diff --git a/cv-data-service-library/src/test/resources/rxMsg_TIM_OdeOutput.json b/cv-data-service-library/src/test/resources/rxMsg_TIM_OdeOutput.json index 2f93bdc33..76cb4aa35 100644 --- a/cv-data-service-library/src/test/resources/rxMsg_TIM_OdeOutput.json +++ b/cv-data-service-library/src/test/resources/rxMsg_TIM_OdeOutput.json @@ -90,7 +90,7 @@ "roadSignage": "" }, "msgId": { - "furtherInfoID": "0" + "furtherInfoID": "0000" }, "startTime": 149760, "priority": 2, diff --git a/cv-data-service-library/src/test/resources/rxMsg_TIM_OdeOutput_Geometry.json b/cv-data-service-library/src/test/resources/rxMsg_TIM_OdeOutput_Geometry.json index c50d92da9..340c1f8ba 100644 --- a/cv-data-service-library/src/test/resources/rxMsg_TIM_OdeOutput_Geometry.json +++ b/cv-data-service-library/src/test/resources/rxMsg_TIM_OdeOutput_Geometry.json @@ -77,7 +77,7 @@ "roadSignage": "" }, "msgId": { - "furtherInfoID": "0" + "furtherInfoID": "0000" }, "startTime": 149760, "priority": 2, diff --git a/cv-data-service-library/src/test/resources/rxMsg_TIM_OdeOutput_MultipleRegions.json b/cv-data-service-library/src/test/resources/rxMsg_TIM_OdeOutput_MultipleRegions.json index b223fea56..a734db6db 100644 --- a/cv-data-service-library/src/test/resources/rxMsg_TIM_OdeOutput_MultipleRegions.json +++ b/cv-data-service-library/src/test/resources/rxMsg_TIM_OdeOutput_MultipleRegions.json @@ -134,7 +134,7 @@ "roadSignage": "" }, "msgId": { - "furtherInfoID": "0" + "furtherInfoID": "0000" }, "startTime": 149760, "priority": 2, diff --git a/cv-data-service-library/src/test/resources/rxMsg_TIM_SpeedLimit.json b/cv-data-service-library/src/test/resources/rxMsg_TIM_SpeedLimit.json index 6814be0e4..83e6038d0 100644 --- a/cv-data-service-library/src/test/resources/rxMsg_TIM_SpeedLimit.json +++ b/cv-data-service-library/src/test/resources/rxMsg_TIM_SpeedLimit.json @@ -90,7 +90,7 @@ "roadSignage": "" }, "msgId": { - "furtherInfoID": "0" + "furtherInfoID": "0000" }, "startTime": 149760, "priority": 2, diff --git a/cv-data-service-library/src/test/resources/sdxDecodeResponse.json b/cv-data-service-library/src/test/resources/sdxDecodeResponse.json index 1102aa065..a91c8fd2f 100644 --- a/cv-data-service-library/src/test/resources/sdxDecodeResponse.json +++ b/cv-data-service-library/src/test/resources/sdxDecodeResponse.json @@ -1,4 +1,4 @@ { "messageType": "MessageFrame", - "decodedMessage": "3113469004null0020194690043200050westbound_I80_39.9_53.31_SAT-4035A5DF_RC_LYMI80EGRAD00414344751-11010514253270000000011111100000-1048300445417415787-1101068786414338729-1048297813417401082-1101173822414302517-1048296846417313218-1101278808414263469-1048334156417231472-1101362065414212124-1048363596417151273-1048348231417067803-1101430219414153700-1101515051414095801-1048292665416990008-1101609734414047121-1048303785416903264-1101704290413998478-1048330081416818875-1101798529413950074-1048362115416736381-1048394037416654255-1101901550413914121-1102014424413891332-1048426742416569080-1102126907413868840-1048459137416484285-1102235582413840132-1048492892416400669-1102332568413793094-1048526150416318091-1048559229416236049-1102434259413752451-1102543983413731407-1048592545416153296-1102655116413714865-1048625771416070802-1102767179413702216-1048658799415988821-1102881705413689256-1048694127415905527-1048732305415821992-1102996201413671479-1103105581413647716-1048769216415741004-1103216030413622307-1048806392415659600-1103325763413587617-1048843990415577334-11033794134135705070058955907null" + "decodedMessage": "3113469004null0000020194690043200050westbound_I80_39.9_53.31_SAT-4035A5DF_RC_LYMI80EGRAD00414344751-11010514253270000000011111100000-1048300445417415787-1101068786414338729-1048297813417401082-1101173822414302517-1048296846417313218-1101278808414263469-1048334156417231472-1101362065414212124-1048363596417151273-1048348231417067803-1101430219414153700-1101515051414095801-1048292665416990008-1101609734414047121-1048303785416903264-1101704290413998478-1048330081416818875-1101798529413950074-1048362115416736381-1048394037416654255-1101901550413914121-1102014424413891332-1048426742416569080-1102126907413868840-1048459137416484285-1102235582413840132-1048492892416400669-1102332568413793094-1048526150416318091-1048559229416236049-1102434259413752451-1102543983413731407-1048592545416153296-1102655116413714865-1048625771416070802-1102767179413702216-1048658799415988821-1102881705413689256-1048694127415905527-1048732305415821992-1102996201413671479-1103105581413647716-1048769216415741004-1103216030413622307-1048806392415659600-1103325763413587617-1048843990415577334-11033794134135705070058955907null" } diff --git a/cv-data-service-library/src/test/resources/tim_construction.json b/cv-data-service-library/src/test/resources/tim_construction.json index 8594cc3fb..eef8ca7ef 100644 --- a/cv-data-service-library/src/test/resources/tim_construction.json +++ b/cv-data-service-library/src/test/resources/tim_construction.json @@ -39,7 +39,7 @@ "doNotUse1": 0, "frameType": "advisory", "msgId": { - "furtherInfoID": "0" + "furtherInfoID": "0000" }, "durationTime": 32000, "startYear": 2021, diff --git a/cv-data-service-library/src/test/resources/tim_construction_MultipleRegions.json b/cv-data-service-library/src/test/resources/tim_construction_MultipleRegions.json index 5661c16de..60554252b 100644 --- a/cv-data-service-library/src/test/resources/tim_construction_MultipleRegions.json +++ b/cv-data-service-library/src/test/resources/tim_construction_MultipleRegions.json @@ -39,7 +39,7 @@ "doNotUse1": 0, "frameType": "advisory", "msgId": { - "furtherInfoID": "0" + "furtherInfoID": "0000" }, "durationTime": 32000, "startYear": 2021, diff --git a/cv-data-service-library/src/test/resources/tim_parking.json b/cv-data-service-library/src/test/resources/tim_parking.json index e96e1cb20..7028dc57a 100644 --- a/cv-data-service-library/src/test/resources/tim_parking.json +++ b/cv-data-service-library/src/test/resources/tim_parking.json @@ -39,7 +39,7 @@ "doNotUse1": 0, "frameType": "advisory", "msgId": { - "furtherInfoID": "0" + "furtherInfoID": "0000" }, "durationTime": 32000, "startYear": 2021, diff --git a/cv-data-service-library/src/test/resources/tim_parking_MultipleRegions.json b/cv-data-service-library/src/test/resources/tim_parking_MultipleRegions.json index 34b291a81..be39941c2 100644 --- a/cv-data-service-library/src/test/resources/tim_parking_MultipleRegions.json +++ b/cv-data-service-library/src/test/resources/tim_parking_MultipleRegions.json @@ -142,7 +142,7 @@ "doNotUse4": 0, "startYear": 2021, "msgId": { - "furtherInfoID": "0" + "furtherInfoID": "0000" }, "priority": 5, "content": { diff --git a/cv-data-service-library/src/test/resources/tim_vsl.json b/cv-data-service-library/src/test/resources/tim_vsl.json index 881717ad8..e5ef6d68a 100644 --- a/cv-data-service-library/src/test/resources/tim_vsl.json +++ b/cv-data-service-library/src/test/resources/tim_vsl.json @@ -39,7 +39,7 @@ "doNotUse1": 0, "frameType": "advisory", "msgId": { - "furtherInfoID": "0" + "furtherInfoID": "0000" }, "durationTime": 32000, "startYear": 2021, diff --git a/cv-data-service-library/src/test/resources/tim_vsl_MultipleRegions.json b/cv-data-service-library/src/test/resources/tim_vsl_MultipleRegions.json index 9fe41d220..f741bca15 100644 --- a/cv-data-service-library/src/test/resources/tim_vsl_MultipleRegions.json +++ b/cv-data-service-library/src/test/resources/tim_vsl_MultipleRegions.json @@ -126,7 +126,7 @@ "doNotUse4": 1, "startYear": 2021, "msgId": { - "furtherInfoID": "0" + "furtherInfoID": "0000" }, "priority": 5, "content": { diff --git a/developer-tools/geojson-from-ode-tim/sampledata.json b/developer-tools/geojson-from-ode-tim/sampledata.json index fab46f9c3..b6d0acb50 100644 --- a/developer-tools/geojson-from-ode-tim/sampledata.json +++ b/developer-tools/geojson-from-ode-tim/sampledata.json @@ -24,7 +24,7 @@ "doNotUse1": 0, "frameType": "advisory", "msgId": { - "furtherInfoID": "0" + "furtherInfoID": "0000" }, "startDateTime": "2024-10-02T11:00:50.814Z", "durationTime": 32000, diff --git a/logger-kafka-consumer/src/test/resources/TIM_odeTimStartDateTime.json b/logger-kafka-consumer/src/test/resources/TIM_odeTimStartDateTime.json index b8225015d..b54518a7e 100644 --- a/logger-kafka-consumer/src/test/resources/TIM_odeTimStartDateTime.json +++ b/logger-kafka-consumer/src/test/resources/TIM_odeTimStartDateTime.json @@ -254,7 +254,7 @@ "doNotUse4": 0, "startYear": 2020, "msgId": { - "furtherInfoID": "0" + "furtherInfoID": "0000" }, "priority": 5, "content": { diff --git a/logger-kafka-consumer/src/test/resources/TIM_odeTim_Rsus.json b/logger-kafka-consumer/src/test/resources/TIM_odeTim_Rsus.json index 562f5ec7d..60a413689 100644 --- a/logger-kafka-consumer/src/test/resources/TIM_odeTim_Rsus.json +++ b/logger-kafka-consumer/src/test/resources/TIM_odeTim_Rsus.json @@ -60,7 +60,7 @@ "durationTime": 32000, "frameType": "advisory", "msgId": { - "furtherInfoID": "0" + "furtherInfoID": "0000" }, "priority": 5, "regions": [ diff --git a/logger-kafka-consumer/src/test/resources/rxMsg_TIM_OdeOutput.json b/logger-kafka-consumer/src/test/resources/rxMsg_TIM_OdeOutput.json index 2f93bdc33..76cb4aa35 100644 --- a/logger-kafka-consumer/src/test/resources/rxMsg_TIM_OdeOutput.json +++ b/logger-kafka-consumer/src/test/resources/rxMsg_TIM_OdeOutput.json @@ -90,7 +90,7 @@ "roadSignage": "" }, "msgId": { - "furtherInfoID": "0" + "furtherInfoID": "0000" }, "startTime": 149760, "priority": 2, diff --git a/logger-kafka-consumer/src/test/resources/rxMsg_TIM_OdeOutput_NullMetadata.json b/logger-kafka-consumer/src/test/resources/rxMsg_TIM_OdeOutput_NullMetadata.json index c51107342..836a4d153 100644 --- a/logger-kafka-consumer/src/test/resources/rxMsg_TIM_OdeOutput_NullMetadata.json +++ b/logger-kafka-consumer/src/test/resources/rxMsg_TIM_OdeOutput_NullMetadata.json @@ -62,7 +62,7 @@ "roadSignage": "" }, "msgId": { - "furtherInfoID": "0" + "furtherInfoID": "0000" }, "startTime": 149760, "priority": 2, From a83c1ec0c0a3b20786990f0a4b4624f7757468ff Mon Sep 17 00:00:00 2001 From: Paige Monington Date: Wed, 19 Nov 2025 09:48:49 -0700 Subject: [PATCH 165/168] fix: assign frameType based on kafka topic message --- .../loggerkafkaconsumer/app/services/DataFrameService.java | 6 ++++-- .../app/services/DataFrameServiceTest.java | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/logger-kafka-consumer/src/main/java/com/trihydro/loggerkafkaconsumer/app/services/DataFrameService.java b/logger-kafka-consumer/src/main/java/com/trihydro/loggerkafkaconsumer/app/services/DataFrameService.java index 93f6ae58e..2a6d76972 100644 --- a/logger-kafka-consumer/src/main/java/com/trihydro/loggerkafkaconsumer/app/services/DataFrameService.java +++ b/logger-kafka-consumer/src/main/java/com/trihydro/loggerkafkaconsumer/app/services/DataFrameService.java @@ -49,8 +49,10 @@ public Long AddDataFrame(DataFrame dFrame, Long timId) { } else if (col.equals("SSP_TIM_RIGHTS")) { sqlNullHandler.setShortOrNull(preparedStatement, fieldNum, dFrame.getDoNotUse1()); } else if (col.equals("FRAME_TYPE")) { - // Always assign TravelerInfoType.roadSignage - Integer ordinal = FrameType.TravelerInfoType.roadSignage.ordinal(); + Integer ordinal = null; + if (dFrame.getFrameType() != null) { + ordinal = dFrame.getFrameType().ordinal(); + } sqlNullHandler.setIntegerOrNull(preparedStatement, fieldNum, ordinal); } else if (col.equals("DURATION_TIME")) { sqlNullHandler.setIntegerOrNull(preparedStatement, fieldNum, dFrame.getDurationTime()); diff --git a/logger-kafka-consumer/src/test/java/com/trihydro/loggerkafkaconsumer/app/services/DataFrameServiceTest.java b/logger-kafka-consumer/src/test/java/com/trihydro/loggerkafkaconsumer/app/services/DataFrameServiceTest.java index 471d472d0..097b82a19 100644 --- a/logger-kafka-consumer/src/test/java/com/trihydro/loggerkafkaconsumer/app/services/DataFrameServiceTest.java +++ b/logger-kafka-consumer/src/test/java/com/trihydro/loggerkafkaconsumer/app/services/DataFrameServiceTest.java @@ -51,7 +51,7 @@ public void AddDataFrame_SUCCESS() throws SQLException, ParseException { Assertions.assertEquals(Long.valueOf(-1), data); verify(mockSqlNullHandler).setLongOrNull(mockPreparedStatement, 1, -1L);// TIM_ID verify(mockSqlNullHandler).setShortOrNull(mockPreparedStatement, 2, dFrame.getDoNotUse1());// SSP_TIM_RIGHTS & NotUsed - verify(mockSqlNullHandler).setIntegerOrNull(mockPreparedStatement, 3, 2);// FRAME_TYPE is RoadSignage + verify(mockSqlNullHandler).setIntegerOrNull(mockPreparedStatement, 3, null);// FRAME_TYPE verify(mockSqlNullHandler).setIntegerOrNull(mockPreparedStatement, 4, dFrame.getDurationTime());// DURATION_TIME verify(mockSqlNullHandler).setIntegerOrNull(mockPreparedStatement, 5, dFrame.getPriority());// PRIORITY verify(mockSqlNullHandler).setShortOrNull(mockPreparedStatement, 6, dFrame.getDoNotUse2());// SSP_LOCATION_RIGHTS & NotUsed1 @@ -70,7 +70,7 @@ public void AddDataFrame_FAIL() throws SQLException, ParseException { DataFrame dFrame = new DataFrame(); dFrame.setStartDateTime("2020-02-03T16:00Z"); doThrow(new SQLException()).when(mockSqlNullHandler).setLongOrNull(mockPreparedStatement, 1, -1L); - + // Act Long data = uut.AddDataFrame(dFrame, -1L); From f888fdd233c34ccc7f70b03ccc88b11b76703c47 Mon Sep 17 00:00:00 2001 From: Paige Monington Date: Wed, 19 Nov 2025 09:51:10 -0700 Subject: [PATCH 166/168] chore: remove unused import --- .../loggerkafkaconsumer/app/services/DataFrameService.java | 1 - 1 file changed, 1 deletion(-) diff --git a/logger-kafka-consumer/src/main/java/com/trihydro/loggerkafkaconsumer/app/services/DataFrameService.java b/logger-kafka-consumer/src/main/java/com/trihydro/loggerkafkaconsumer/app/services/DataFrameService.java index 2a6d76972..0506ac69c 100644 --- a/logger-kafka-consumer/src/main/java/com/trihydro/loggerkafkaconsumer/app/services/DataFrameService.java +++ b/logger-kafka-consumer/src/main/java/com/trihydro/loggerkafkaconsumer/app/services/DataFrameService.java @@ -18,7 +18,6 @@ import com.trihydro.library.tables.TimDbTables; import us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage.DataFrame; -import us.dot.its.jpo.ode.plugin.j2735.timstorage.FrameType; @Component @Slf4j From b20bdbf021795f169d3b39655bd9ab3c726d478b Mon Sep 17 00:00:00 2001 From: Paige Monington Date: Wed, 19 Nov 2025 10:38:38 -0700 Subject: [PATCH 167/168] fix: adjust active TIMs to return frameType from database --- .../controller/ActiveTimController.java | 25 ++++++++++++++++++- .../controller/DataFrameController.java | 7 +++--- .../controller/ActiveTimControllerTest.java | 3 --- .../library/helpers/CreateBaseTimUtil.java | 2 ++ .../library/model/TimUpdateModel.java | 8 +++--- 5 files changed, 35 insertions(+), 10 deletions(-) diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java index 26afc2d6a..886c6f035 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/ActiveTimController.java @@ -43,6 +43,7 @@ import org.springframework.web.client.HttpServerErrorException; import springfox.documentation.annotations.ApiIgnore; +import us.dot.its.jpo.ode.plugin.j2735.timstorage.FrameType.TravelerInfoType; @CrossOrigin @RestController @@ -101,6 +102,17 @@ public ResponseEntity> GetExpiringActiveTims() { while (rs.next()) { var activeTim = buildTimUpdateModelFromResultSet(rs); + int frameTypeValue = rs.getInt("FRAME_TYPE"); + if (!rs.wasNull() && frameTypeValue >= 0 && frameTypeValue < TravelerInfoType.values().length) { + activeTim.setFrameType(TravelerInfoType.values()[frameTypeValue]); + } + else { + log.warn("Could not set frame type from value {} for active tim id {}. Assuming Advisory.", frameTypeValue, + activeTim.getActiveTimId()); + // assume roadSignage + activeTim.setFrameType(TravelerInfoType.roadSignage); + } + activeTim.setDfContent(ContentEnum.advisory); activeTims.add(activeTim); } @@ -135,7 +147,18 @@ public ResponseEntity GetUpdateModelFromActiveTimId(@PathVariabl // convert to ActiveTim object while (rs.next()) { // Active_Tim properties - activeTim = buildTimUpdateModelFromResultSet(rs); + activeTim = buildTimUpdateModelFromResultSet(rs); + + int frameTypeValue = rs.getInt("FRAME_TYPE"); + if (!rs.wasNull() && frameTypeValue >= 0 && frameTypeValue < TravelerInfoType.values().length) { + activeTim.setFrameType(TravelerInfoType.values()[frameTypeValue]); + } + else { + log.warn("Could not set frame type from value {} for active tim id {}. Assuming Advisory.", frameTypeValue, activeTimId); + // assume roadSignage + activeTim.setFrameType(TravelerInfoType.roadSignage); + } + activeTim.setDfContent(ContentEnum.advisory); } } catch (Exception e) { diff --git a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/DataFrameController.java b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/DataFrameController.java index a427d860d..068b207f8 100644 --- a/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/DataFrameController.java +++ b/cv-data-controller/src/main/java/com/trihydro/cvdatacontroller/controller/DataFrameController.java @@ -29,7 +29,6 @@ import springfox.documentation.annotations.ApiIgnore; import us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage.DataFrame; -import us.dot.its.jpo.ode.plugin.j2735.timstorage.FrameType; @CrossOrigin @RestController @@ -113,8 +112,10 @@ public ResponseEntity AddDataFrame(@RequestBody DataFrame dFrame, @PathVar if (col.equals("TIM_ID")) { sqlNullHandler.setLongOrNull(preparedStatement, fieldNum, timId); } else if (col.equals("FRAME_TYPE")) { - // Always assign TravelerInfoType.roadSignage per CTW - Integer ordinal = FrameType.TravelerInfoType.roadSignage.ordinal(); + Integer ordinal = null; + if (dFrame.getFrameType() != null) { + ordinal = dFrame.getFrameType().ordinal(); + } sqlNullHandler.setIntegerOrNull(preparedStatement, fieldNum, ordinal); } else if (col.equals("DURATION_TIME")) { sqlNullHandler.setIntegerOrNull(preparedStatement, fieldNum, dFrame.getDurationTime()); diff --git a/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/ActiveTimControllerTest.java b/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/ActiveTimControllerTest.java index 3a4b08117..cb92b59d9 100644 --- a/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/ActiveTimControllerTest.java +++ b/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/ActiveTimControllerTest.java @@ -36,7 +36,6 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.client.HttpServerErrorException; -import us.dot.its.jpo.ode.plugin.j2735.timstorage.FrameType; public class ActiveTimControllerTest extends TestBase { @Spy @@ -82,7 +81,6 @@ public void GetExpiringActiveTims_SUCCESS() throws SQLException { Assertions.assertEquals(HttpStatus.OK, tums.getStatusCode()); Assertions.assertEquals(1, tums.getBody().size()); Assertions.assertEquals(Long.valueOf(999), tums.getBody().get(0).getActiveTimId()); - Assertions.assertEquals(FrameType.TravelerInfoType.roadSignage, tums.getBody().get(0).getFrameType()); verify(mockStatement).executeQuery(selectStatement); } @@ -146,7 +144,6 @@ public void GetUpdateModelFromActiveTimId_SUCCESS() throws SQLException { Assertions.assertEquals(HttpStatus.OK, tum.getStatusCode()); Assertions.assertNotNull(tum.getBody()); Assertions.assertEquals(Long.valueOf(999), tum.getBody().getActiveTimId()); - Assertions.assertEquals(FrameType.TravelerInfoType.roadSignage, tum.getBody().getFrameType()); verify(mockStatement).executeQuery(selectStatement); } diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CreateBaseTimUtil.java b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CreateBaseTimUtil.java index 9ed63b548..f8e782368 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CreateBaseTimUtil.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/CreateBaseTimUtil.java @@ -70,6 +70,8 @@ public WydotTravelerInputData buildTim(WydotTim wydotTim, TimGenerationProps gen dataFrame.setPriority(5); dataFrame.setContent(content.getStringValue()); + // Per CTW, FrameType should be set to roadSignage when state or local deployment agency is generating the message + // which is all messages coming through the TIMM so always set to roadSignage dataFrame.setFrameType(TravelerInfoType.roadSignage); dataFrame.setUrl("null"); // add itis codes to tim diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/model/TimUpdateModel.java b/cv-data-service-library/src/main/java/com/trihydro/library/model/TimUpdateModel.java index 2d669c4d1..7bfdaec4e 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/model/TimUpdateModel.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/model/TimUpdateModel.java @@ -30,6 +30,7 @@ public class TimUpdateModel extends ActiveTim { // DataFrame properties private int dataFrameId; + private TravelerInfoType frameType; private int durationTime; private short doNotUse2; private short doNotUse1; @@ -37,9 +38,6 @@ public class TimUpdateModel extends ActiveTim { private short doNotUse3; private ContentEnum dfContent; private String url; - // Per CTW, FrameType should be set to roadSignage when state or local deployment agency is generating the message - // which is all messages coming through the TIMM so always set to roadSignage - private final TravelerInfoType frameType = TravelerInfoType.roadSignage; public BigDecimal getLaneWidth() { return laneWidth; @@ -169,6 +167,10 @@ public TravelerInfoType getFrameType() { return frameType; } + public void setFrameType(TravelerInfoType frameType) { + this.frameType = frameType; + } + public short getDoNotUse1() { return doNotUse1; } From 7fc91145b81108015fc5ea5e52b7bf16a41ddd24 Mon Sep 17 00:00:00 2001 From: Paige Monington Date: Wed, 19 Nov 2025 10:52:43 -0700 Subject: [PATCH 168/168] test: add unit test for ensuring active TIM FrameType is set to value from database --- .../controller/ActiveTimControllerTest.java | 5 +++++ .../trihydro/library/helpers/JsonToJavaConverter.java | 11 +++++++++++ 2 files changed, 16 insertions(+) diff --git a/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/ActiveTimControllerTest.java b/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/ActiveTimControllerTest.java index cb92b59d9..b2b9cee55 100644 --- a/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/ActiveTimControllerTest.java +++ b/cv-data-controller/src/test/java/com/trihydro/cvdatacontroller/controller/ActiveTimControllerTest.java @@ -34,6 +34,7 @@ import org.mockito.Spy; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import us.dot.its.jpo.ode.plugin.j2735.timstorage.FrameType; import org.springframework.web.client.HttpServerErrorException; @@ -58,6 +59,7 @@ public void GetExpiringActiveTims_SUCCESS() throws SQLException { // we only set one property to verify its returned when(mockRs.getLong("ACTIVE_TIM_ID")).thenReturn(999L); when(mockRs.getInt(any())).thenReturn(0); + when(mockRs.getInt("FRAME_TYPE")).thenReturn(FrameType.TravelerInfoType.advisory.ordinal()); String selectStatement = "SELECT atim.*, tt.type as tim_type_name, tt.description as tim_type_description"; selectStatement += ", t.msg_cnt, t.url_b, t.is_satellite, t.sat_record_id, t.packet_id"; selectStatement += ", df.data_frame_id, df.frame_type, df.duration_time, df.ssp_tim_rights, df.ssp_location_rights"; @@ -81,6 +83,7 @@ public void GetExpiringActiveTims_SUCCESS() throws SQLException { Assertions.assertEquals(HttpStatus.OK, tums.getStatusCode()); Assertions.assertEquals(1, tums.getBody().size()); Assertions.assertEquals(Long.valueOf(999), tums.getBody().get(0).getActiveTimId()); + Assertions.assertEquals(FrameType.TravelerInfoType.advisory, tums.getBody().get(0).getFrameType()); verify(mockStatement).executeQuery(selectStatement); } @@ -122,6 +125,7 @@ public void GetUpdateModelFromActiveTimId_SUCCESS() throws SQLException { // we only set one property to verify its returned when(mockRs.getLong("ACTIVE_TIM_ID")).thenReturn(999L); when(mockRs.getInt(any())).thenReturn(0); + when(mockRs.getInt("FRAME_TYPE")).thenReturn(FrameType.TravelerInfoType.roadSignage.ordinal()); String selectStatement = "SELECT atim.*, tt.type AS tim_type_name, tt.description AS tim_type_description"; selectStatement += ", t.msg_cnt, t.url_b, t.is_satellite, t.sat_record_id, t.packet_id"; @@ -144,6 +148,7 @@ public void GetUpdateModelFromActiveTimId_SUCCESS() throws SQLException { Assertions.assertEquals(HttpStatus.OK, tum.getStatusCode()); Assertions.assertNotNull(tum.getBody()); Assertions.assertEquals(Long.valueOf(999), tum.getBody().getActiveTimId()); + Assertions.assertEquals(FrameType.TravelerInfoType.roadSignage, tum.getBody().getFrameType()); verify(mockStatement).executeQuery(selectStatement); } diff --git a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/JsonToJavaConverter.java b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/JsonToJavaConverter.java index 76824939f..cacc12de6 100644 --- a/cv-data-service-library/src/main/java/com/trihydro/library/helpers/JsonToJavaConverter.java +++ b/cv-data-service-library/src/main/java/com/trihydro/library/helpers/JsonToJavaConverter.java @@ -511,6 +511,17 @@ else if (sequenceArrNode.get("item").get("text") != null) itemsList.add(item); } + // TravelerInfoType.valueOf(); + JsonNode frameTypeNode = travelerDataFrame.get("frameType"); + if (frameTypeNode != null) { + if (frameTypeNode.fieldNames().hasNext()) { + TravelerInfoType frameType = TravelerInfoType.valueOf(frameTypeNode.fieldNames().next()); + if (frameType != null) { + dataFrame.setFrameType(frameType); + } + } + } + JsonNode startTimeNode = travelerDataFrame.get("startTime"); JsonNode durationNode = travelerDataFrame.get("durationTime"); JsonNode priorityNode = travelerDataFrame.get("priority");