diff --git a/.github/coveragereport/badge_methodcoverage.svg b/.github/coveragereport/badge_methodcoverage.svg index d449fc9f..3f134e5d 100644 --- a/.github/coveragereport/badge_methodcoverage.svg +++ b/.github/coveragereport/badge_methodcoverage.svg @@ -102,7 +102,7 @@ Coverage - 93.1%93.1% + 93.2%93.2% diff --git a/cwms-data-api-client/src/main/java/mil/army/usace/hec/cwms/data/api/client/controllers/LevelController.java b/cwms-data-api-client/src/main/java/mil/army/usace/hec/cwms/data/api/client/controllers/LevelController.java index 569c20f2..f4fe88a8 100644 --- a/cwms-data-api-client/src/main/java/mil/army/usace/hec/cwms/data/api/client/controllers/LevelController.java +++ b/cwms-data-api-client/src/main/java/mil/army/usace/hec/cwms/data/api/client/controllers/LevelController.java @@ -30,6 +30,7 @@ import java.io.IOException; import java.util.Set; import mil.army.usace.hec.cwms.data.api.client.model.LocationLevel; +import mil.army.usace.hec.cwms.data.api.client.model.LocationLevelRefs; import mil.army.usace.hec.cwms.data.api.client.model.LocationLevels; import mil.army.usace.hec.cwms.data.api.client.model.RadarObjectMapper; import mil.army.usace.hec.cwms.data.api.client.model.SpecifiedLevel; @@ -43,6 +44,7 @@ public final class LevelController { private static final String SPECIFIED_LEVEL_ENDPOINT = "specified-levels"; private static final String LOCATION_LEVEL_ENDPOINT = "levels"; + private static final String LOCATION_LEVEL_REFS_ENDPOINT = "level-refs"; public Set retrieveSpecifiedLevels(ApiConnectionInfo apiConnectionInfo, SpecifiedLevelEndpointInput.GetAll input) throws IOException { @@ -107,6 +109,16 @@ public LocationLevels retrieveLocationLevels(ApiConnectionInfo apiConnectionInfo } } + public LocationLevelRefs retrieveLocationLevelRefs(ApiConnectionInfo apiConnectionInfo, + LocationLevelEndpointInput.GetAllRefs input) throws IOException { + HttpRequestExecutor executor = new HttpRequestBuilderImpl(apiConnectionInfo, LOCATION_LEVEL_REFS_ENDPOINT) + .addEndpointInput(input) + .get(); + try (HttpRequestResponse response = executor.execute()) { + return RadarObjectMapper.mapJsonToObject(response.getBody(), LocationLevelRefs.class); + } + } + public void storeLevel(ApiConnectionInfo apiConnectionInfo, LocationLevelEndpointInput.Post input) throws IOException { String body = RadarObjectMapper.mapObjectToJson(input.level()); new HttpRequestBuilderImpl(apiConnectionInfo, LOCATION_LEVEL_ENDPOINT) diff --git a/cwms-data-api-client/src/main/java/mil/army/usace/hec/cwms/data/api/client/controllers/LocationLevelEndpointInput.java b/cwms-data-api-client/src/main/java/mil/army/usace/hec/cwms/data/api/client/controllers/LocationLevelEndpointInput.java index 261fc767..6f295fe4 100644 --- a/cwms-data-api-client/src/main/java/mil/army/usace/hec/cwms/data/api/client/controllers/LocationLevelEndpointInput.java +++ b/cwms-data-api-client/src/main/java/mil/army/usace/hec/cwms/data/api/client/controllers/LocationLevelEndpointInput.java @@ -65,6 +65,10 @@ public static GetAll getAll() { return new GetAll(); } + public static GetAllRefs getAllRefs() { + return new GetAllRefs(); + } + public static Post post(LocationLevel level) { return new Post(level); } @@ -211,6 +215,64 @@ public GetAll unit(String unit) { } } + public static final class GetAllRefs extends EndpointInput { + private String officeId; + private String levelIdMask = "*"; + private Instant begin; + private Instant end; + private String page; + private Integer pageSize; + + private GetAllRefs() { + //Empty private ctor + } + + @Override + protected HttpRequestBuilder addInputParameters(HttpRequestBuilder httpRequestBuilder) { + String pageSizeString = Optional.ofNullable(pageSize).map(Object::toString).orElse(null); + String beginString = Optional.ofNullable(begin).map(Object::toString).orElse(null); + String endString = Optional.ofNullable(end).map(Object::toString).orElse(null); + return httpRequestBuilder.addQueryParameter(OFFICE_QUERY_PARAMETER, officeId) + .addQueryParameter(LEVEL_ID_MASK_QUERY_PARAMETER, levelIdMask) + .addQueryParameter(OFFICE_QUERY_PARAMETER, officeId) + .addQueryParameter(BEGIN_QUERY_PARAMETER, beginString) + .addQueryParameter(END_QUERY_PARAMETER, endString) + .addQueryParameter(PAGE_QUERY_PARAMETER, page) + .addQueryParameter(PAGE_SIZE_QUERY_PARAMETER, pageSizeString) + .addQueryHeader(ACCEPT_QUERY_HEADER, ACCEPT_HEADER_V1); + } + + public GetAllRefs officeId(String officeId) { + this.officeId = officeId; + return this; + } + + public GetAllRefs levelIdMask(String levelIdMask) { + this.levelIdMask = levelIdMask; + return this; + } + + public GetAllRefs begin(Instant begin) { + this.begin = begin; + return this; + } + + public GetAllRefs end(Instant end) { + this.end = end; + return this; + } + + public GetAllRefs page(String page) { + this.page = page; + return this; + } + + public GetAllRefs pageSize(int pageSize) { + this.pageSize = pageSize; + return this; + } + } + public static final class Post extends EndpointInput { private final LocationLevel level; diff --git a/cwms-data-api-client/src/test/java/mil/army/usace/hec/cwms/data/api/client/controllers/TestLevelController.java b/cwms-data-api-client/src/test/java/mil/army/usace/hec/cwms/data/api/client/controllers/TestLevelController.java index 66c379a0..70c58f44 100644 --- a/cwms-data-api-client/src/test/java/mil/army/usace/hec/cwms/data/api/client/controllers/TestLevelController.java +++ b/cwms-data-api-client/src/test/java/mil/army/usace/hec/cwms/data/api/client/controllers/TestLevelController.java @@ -40,6 +40,8 @@ import mil.army.usace.hec.cwms.data.api.client.model.ConstantLocationLevel; import mil.army.usace.hec.cwms.data.api.client.model.LocationLevel; import mil.army.usace.hec.cwms.data.api.client.model.LocationLevelConstituent; +import mil.army.usace.hec.cwms.data.api.client.model.LocationLevelRef; +import mil.army.usace.hec.cwms.data.api.client.model.LocationLevelRefs; import mil.army.usace.hec.cwms.data.api.client.model.LocationLevels; import mil.army.usace.hec.cwms.data.api.client.model.RadarObjectMapper; import mil.army.usace.hec.cwms.data.api.client.model.SeasonalLocationLevel; @@ -129,6 +131,29 @@ void testRetrieveLocationLevels() throws IOException { assertEquals("0", level.get().getDurationId()); } + @Test + void testRetrieveLocationLevelRefs() throws IOException { + String resource = "radar/v1/json/level_refs.json"; + String collect = readJsonFile(resource); + mockHttpServer.enqueue(collect); + mockHttpServer.start(); + LocationLevelEndpointInput.GetAllRefs input = LocationLevelEndpointInput.getAllRefs() + .officeId("NWDP"); + LocationLevelRefs locationLevels = new LevelController().retrieveLocationLevelRefs(buildConnectionInfo(), input); + assertEquals(100, locationLevels.getPageSize()); + assertNotNull(locationLevels.getPage()); + assertNotNull(locationLevels.getNextPage()); + List levels = locationLevels.getLevels(); + assertFalse(levels.isEmpty()); + Optional level = levels.stream() + .filter(s -> s.getLocationLevelId().getName().equals("AGNO.Flow.Inst.0.Flood")) + .findAny(); + assertTrue(level.isPresent()); + assertEquals("NWDP", level.get().getLocationLevelId().getOfficeId()); + ZonedDateTime effectiveDate = ZonedDateTime.of(1900, 1, 1, 8, 0, 0, 0, ZoneId.of("UTC")); + assertEquals(effectiveDate.toInstant(), level.get().getEffectiveDates().get(0)); + } + @Test void testRetrieveLocationLevelSubtypes() throws IOException { String resource = "radar/v2/json/location_levels.json"; diff --git a/cwms-data-api-client/src/test/java/mil/army/usace/hec/cwms/data/api/client/controllers/TestLocationLevelEndpointInput.java b/cwms-data-api-client/src/test/java/mil/army/usace/hec/cwms/data/api/client/controllers/TestLocationLevelEndpointInput.java index 08a584c6..42db6ebe 100644 --- a/cwms-data-api-client/src/test/java/mil/army/usace/hec/cwms/data/api/client/controllers/TestLocationLevelEndpointInput.java +++ b/cwms-data-api-client/src/test/java/mil/army/usace/hec/cwms/data/api/client/controllers/TestLocationLevelEndpointInput.java @@ -81,6 +81,44 @@ void testQueryRequestNulls() { assertEquals(ACCEPT_HEADER_V2, mockHttpRequestBuilder.getQueryHeader(ACCEPT_QUERY_HEADER)); } + + @Test + void testQueryRequestRefs() { + MockHttpRequestBuilder mockHttpRequestBuilder = new MockHttpRequestBuilder(); + ZoneId zoneId = ZoneId.of("America/Los_Angeles"); + Instant begin = ZonedDateTime.of(2015, 1, 1, 0, 0, 0, 0, zoneId).toInstant(); + Instant end = begin.plusSeconds(30); + LocationLevelEndpointInput.GetAllRefs input = LocationLevelEndpointInput.getAllRefs() + .officeId("SWT") + .levelIdMask("MASK") + .page("abc") + .pageSize(10) + .begin(begin) + .end(end); + input.addInputParameters(mockHttpRequestBuilder); + assertEquals("SWT", mockHttpRequestBuilder.getQueryParameter(OFFICE_QUERY_PARAMETER)); + assertEquals("MASK", mockHttpRequestBuilder.getQueryParameter(LEVEL_ID_MASK_QUERY_PARAMETER)); + assertEquals("10", mockHttpRequestBuilder.getQueryParameter(PAGE_SIZE_QUERY_PARAMETER)); + assertEquals("abc", mockHttpRequestBuilder.getQueryParameter(PAGE_QUERY_PARAMETER)); + assertEquals("2015-01-01T08:00:00Z", mockHttpRequestBuilder.getQueryParameter(BEGIN_QUERY_PARAMETER)); + assertEquals("2015-01-01T08:00:30Z", mockHttpRequestBuilder.getQueryParameter(END_QUERY_PARAMETER)); + assertEquals(ACCEPT_HEADER_V1, mockHttpRequestBuilder.getQueryHeader(ACCEPT_QUERY_HEADER)); + } + + @Test + void testQueryRequestRefsNulls() { + MockHttpRequestBuilder mockHttpRequestBuilder = new MockHttpRequestBuilder(); + LocationLevelEndpointInput.GetAllRefs input = LocationLevelEndpointInput.getAllRefs(); + input.addInputParameters(mockHttpRequestBuilder); + assertNull(mockHttpRequestBuilder.getQueryParameter(OFFICE_QUERY_PARAMETER)); + assertEquals("*", mockHttpRequestBuilder.getQueryParameter(LEVEL_ID_MASK_QUERY_PARAMETER)); + assertNull(mockHttpRequestBuilder.getQueryParameter(PAGE_SIZE_QUERY_PARAMETER)); + assertNull(mockHttpRequestBuilder.getQueryParameter(PAGE_QUERY_PARAMETER)); + assertNull(mockHttpRequestBuilder.getQueryParameter(BEGIN_QUERY_PARAMETER)); + assertNull(mockHttpRequestBuilder.getQueryParameter(END_QUERY_PARAMETER)); + assertEquals(ACCEPT_HEADER_V1, mockHttpRequestBuilder.getQueryHeader(ACCEPT_QUERY_HEADER)); + } + @Test void testGet() { Instant now = Instant.now(); diff --git a/cwms-data-api-client/src/test/resources/radar/v1/json/level_refs.json b/cwms-data-api-client/src/test/resources/radar/v1/json/level_refs.json new file mode 100644 index 00000000..7d83c969 --- /dev/null +++ b/cwms-data-api-client/src/test/resources/radar/v1/json/level_refs.json @@ -0,0 +1,927 @@ +{ + "levels": [ + { + "location-level-id": { + "office-id": "NWDP", + "name": "AGNO.Flow.Inst.0.Action" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z", + "2020-01-01T08:00:00Z", + "2023-01-01T00:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AGNO.Flow.Inst.0.Flood" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z", + "2020-01-01T08:00:00Z", + "2023-01-01T00:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AGNO.Flow.Inst.0.NWS Action" + }, + "effective-dates": [ + "2020-01-01T08:00:00Z", + "2023-01-01T00:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AGNO.Flow.Inst.0.NWS Major Flood" + }, + "effective-dates": [ + "2020-01-01T08:00:00Z", + "2023-01-01T00:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AGNO.Flow.Inst.0.NWS Minor Flood" + }, + "effective-dates": [ + "2020-01-01T08:00:00Z", + "2023-01-01T00:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AGNO.Flow.Inst.0.NWS Moderate Flood" + }, + "effective-dates": [ + "2020-01-01T08:00:00Z", + "2023-01-01T00:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AGNO.Stage.Inst.0.Action" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AGNO.Stage.Inst.0.Flood" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AGNO.Stage.Inst.0.NWS Action" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AGNO.Stage.Inst.0.NWS Major Flood" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AGNO.Stage.Inst.0.NWS Minor Flood" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AGNO.Stage.Inst.0.NWS Moderate Flood" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AGNO.Temp-Water.Inst.0.ODFW-THRESHOLD-PUB" + }, + "effective-dates": [ + "1977-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AGNO.Temp-Water.Max.1Day.ODFW-THRESHOLD-PUB" + }, + "effective-dates": [ + "1977-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "ALBO.Flow.Inst.0.Action" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z", + "2020-01-01T08:00:00Z", + "2023-01-01T00:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "ALBO.Flow.Inst.0.COORD-BIOP-PUB" + }, + "effective-dates": [ + "2008-01-01T08:00:00Z", + "2015-01-01T08:00:00Z", + "2016-01-01T08:00:00Z", + "2021-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "ALBO.Flow.Inst.0.Flood" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z", + "2020-01-01T08:00:00Z", + "2023-01-01T00:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "ALBO.Flow.Inst.0.HD531-Minimum-PUB" + }, + "effective-dates": [ + "1948-10-01T07:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "ALBO.Flow.Inst.0.NMFS-BIOP-PUB" + }, + "effective-dates": [ + "2008-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "ALBO.Flow.Inst.0.NWS Action" + }, + "effective-dates": [ + "2020-01-01T08:00:00Z", + "2023-01-01T00:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "ALBO.Flow.Inst.0.NWS Major Flood" + }, + "effective-dates": [ + "2020-01-01T08:00:00Z", + "2023-01-01T00:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "ALBO.Flow.Inst.0.NWS Minor Flood" + }, + "effective-dates": [ + "2020-01-01T08:00:00Z", + "2023-01-01T00:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "ALBO.Flow.Inst.0.NWS Moderate Flood" + }, + "effective-dates": [ + "2020-01-01T08:00:00Z", + "2023-01-01T00:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "ALBO.Stage.Inst.0.Action" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "ALBO.Stage.Inst.0.Flood" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "ALBO.Stage.Inst.0.NWS Action" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "ALBO.Stage.Inst.0.NWS Major Flood" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "ALBO.Stage.Inst.0.NWS Minor Flood" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "ALBO.Stage.Inst.0.NWS Moderate Flood" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "ALF.Elev.Inst.0.Bottom of Flood Control" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "ALF.Elev.Inst.0.Bottom of Normal" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "ALF.Elev.Inst.0.Spillway Crest" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "ALF.Elev.Inst.0.Streambed" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "ALF.Elev.Inst.0.Top of Dam" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "ALF.Elev.Inst.0.Top of Flood Control" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "ALF.Elev.Inst.0.Top of Normal" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "ALF.Stor.Inst.0.Bottom of Flood Control" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "ALF.Stor.Inst.0.Bottom of Normal" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "ALF.Stor.Inst.0.Streambed" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "ALF.Stor.Inst.0.Top of Flood Control" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "ALF.Stor.Inst.0.Top of Normal" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AMF.Elev.Inst.0.Spillway Crest" + }, + "effective-dates": [ + "1900-01-01T07:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AMF.Elev.Inst.0.Streambed" + }, + "effective-dates": [ + "1900-01-01T07:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AMF.Elev.Inst.0.Top of Dam" + }, + "effective-dates": [ + "1900-01-01T07:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AMF.Elev.Inst.0.Top of Flood" + }, + "effective-dates": [ + "1900-01-01T07:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AMF.Elev.Inst.0.Top of Max Flood" + }, + "effective-dates": [ + "1900-01-01T07:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AMF.Stor.Inst.0.Spillway Crest" + }, + "effective-dates": [ + "1900-01-01T07:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AMF.Stor.Inst.0.Streambed" + }, + "effective-dates": [ + "1900-01-01T07:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AMF.Stor.Inst.0.Top of Dam" + }, + "effective-dates": [ + "1900-01-01T07:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AMF.Stor.Inst.0.Top of Flood" + }, + "effective-dates": [ + "1900-01-01T07:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AMF.Stor.Inst.0.Top of Max Flood" + }, + "effective-dates": [ + "1900-01-01T07:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AND.Elev.Inst.0.Bottom of Conservation" + }, + "effective-dates": [ + "1900-01-01T07:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AND.Elev.Inst.0.Bottom of Flood" + }, + "effective-dates": [ + "1900-01-01T07:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AND.Elev.Inst.0.Bottom of Power" + }, + "effective-dates": [ + "1900-01-01T07:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AND.Elev.Inst.0.Max Non-Damaging" + }, + "effective-dates": [ + "1900-01-01T07:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AND.Elev.Inst.0.Spillway Crest" + }, + "effective-dates": [ + "1900-01-01T07:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AND.Elev.Inst.0.Streambed" + }, + "effective-dates": [ + "1900-01-01T07:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AND.Elev.Inst.0.Top of Dam" + }, + "effective-dates": [ + "1900-01-01T07:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AND.Elev.Inst.0.Top of Flood" + }, + "effective-dates": [ + "1900-01-01T07:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AND.Elev.Inst.0.Top of Max Flood" + }, + "effective-dates": [ + "1900-01-01T07:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AND.Elev.Inst.0.Top of Normal" + }, + "effective-dates": [ + "1900-01-01T07:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AND.Stor.Inst.0.Bottom of Conservation" + }, + "effective-dates": [ + "1900-01-01T07:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AND.Stor.Inst.0.Bottom of Flood" + }, + "effective-dates": [ + "1900-01-01T07:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AND.Stor.Inst.0.Bottom of Power" + }, + "effective-dates": [ + "1900-01-01T07:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AND.Stor.Inst.0.Max Non-Damaging" + }, + "effective-dates": [ + "1900-01-01T07:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AND.Stor.Inst.0.Spillway Crest" + }, + "effective-dates": [ + "1900-01-01T07:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AND.Stor.Inst.0.Streambed" + }, + "effective-dates": [ + "1900-01-01T07:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AND.Stor.Inst.0.Top of Dam" + }, + "effective-dates": [ + "1900-01-01T07:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AND.Stor.Inst.0.Top of Flood" + }, + "effective-dates": [ + "1900-01-01T07:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AND.Stor.Inst.0.Top of Max Flood" + }, + "effective-dates": [ + "1900-01-01T07:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "AND.Stor.Inst.0.Top of Normal" + }, + "effective-dates": [ + "1900-01-01T07:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "APP-Copper.Elev.Inst.0.Toe of Ramp" + }, + "effective-dates": [ + "1900-01-01T16:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "APP-FrenchGulch.Elev.Inst.0.Toe of Ramp" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "APP-HartTish.Elev.Inst.0.Toe of Ramp" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "APP-WetWell1-Port2.Elev.Inst.0.0" + }, + "effective-dates": [ + "1980-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "APP-WetWell1-Port2.Height.Inst.0.0" + }, + "effective-dates": [ + "1980-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "APP-WetWell1-Port2.Width.Inst.0.0" + }, + "effective-dates": [ + "1980-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "APP-WetWell1-Port4.Elev.Inst.0.0" + }, + "effective-dates": [ + "1980-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "APP-WetWell1-Port4.Height.Inst.0.0" + }, + "effective-dates": [ + "1980-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "APP-WetWell1-Port4.Width.Inst.0.0" + }, + "effective-dates": [ + "1980-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "APP-WetWell2-Port1.Elev.Inst.0.0" + }, + "effective-dates": [ + "1980-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "APP-WetWell2-Port1.Height.Inst.0.0" + }, + "effective-dates": [ + "1980-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "APP-WetWell2-Port1.Width.Inst.0.0" + }, + "effective-dates": [ + "1980-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "APP-WetWell2-Port3.Elev.Inst.0.0" + }, + "effective-dates": [ + "1980-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "APP-WetWell2-Port3.Height.Inst.0.0" + }, + "effective-dates": [ + "1980-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "APP-WetWell2-Port3.Width.Inst.0.0" + }, + "effective-dates": [ + "1980-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "APP-WetWell2-Port5.Elev.Inst.0.0" + }, + "effective-dates": [ + "1980-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "APP-WetWell2-Port5.Height.Inst.0.0" + }, + "effective-dates": [ + "1980-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "APP-WetWell2-Port5.Width.Inst.0.0" + }, + "effective-dates": [ + "1980-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "APP.Area.Inst.0.Drainage" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "APP.Elev-Forebay-05Percentile.Const.1Day.CENWP-30year-thru2023-STATS" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "APP.Elev-Forebay-25Percentile.Const.1Day.CENWP-30year-thru2023-STATS" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "APP.Elev-Forebay-75Percentile.Const.1Day.CENWP-30year-thru2023-STATS" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "APP.Elev-Forebay-95Percentile.Const.1Day.CENWP-30year-thru2023-STATS" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "APP.Elev-Forebay.Ave.1Day.CENWP-30year-thru2023-STATS" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "APP.Elev-Forebay.Max.1Day.CENWP-30year-thru2023-STATS" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "APP.Elev-Forebay.Min.1Day.CENWP-30year-thru2023-STATS" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "APP.Elev.Inst.0.Bottom of Conservation" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "APP.Elev.Inst.0.Bottom of Flood" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z" + ] + }, + { + "location-level-id": { + "office-id": "NWDP", + "name": "APP.Elev.Inst.0.Bottom of Flood Control" + }, + "effective-dates": [ + "1900-01-01T08:00:00Z" + ] + } + ], + "next-page": "MTAwfHwzMTU5fHwxMDA=", + "page": "MHx8MzE1OXx8MTAw", + "page-size": 100, + "total": 3159 +} \ No newline at end of file diff --git a/cwms-data-api-model/cwms-data-api-swagger.yaml b/cwms-data-api-model/cwms-data-api-swagger.yaml index 11e5d82e..7a8d533b 100644 --- a/cwms-data-api-model/cwms-data-api-swagger.yaml +++ b/cwms-data-api-model/cwms-data-api-swagger.yaml @@ -2555,7 +2555,115 @@ paths: security: - ApiKey: [] - CwmsAAACacAuth: [] - "/timeseries/recent": + /level-refs: + get: + tags: + - Levels + summary: Get levelRefs + operationId: getLevelRefs + parameters: + - name: level-id-mask + in: query + description: Specifies the name(s) of the location level(s) whose data is to be + included in the response. Uses * for all. + schema: + type: string + - name: office + in: query + description: Specifies the owning office of the location level(s) whose data is + to be included in the response. If this field is not specified, + matching location level information from all offices shall be + returned. + schema: + type: string + - name: begin + in: query + description: Specifies the start of the time window for data to be included in + the response. If this field is not specified, no beginning time will + be used. + schema: + type: string + - name: end + in: query + description: Specifies the end of the time window for data to be included in the + response. If this field is not specified, no end time will be used. + schema: + type: string + - name: timezone + in: query + description: Specifies the time zone of the values of the begin and end fields + (unless otherwise specified), as well as the time zone of any times + in the response. If this field is not specified, the default time + zone of UTC shall be used. + schema: + type: string + - name: include-aliases + in: query + description: Whether to include the aliases for the location levels in the + response. The default is false. + schema: + type: boolean + - name: page + in: query + description: This identifies where in the request you are. This is an opaque + value, and can be obtained from the 'next-page' value in the + response. + schema: + type: string + - name: page-size + in: query + description: How many entries per page returned. Default 100. + schema: + type: integer + format: int32 + responses: + "200": + description: OK + content: + "": + schema: + $ref: "#/components/schemas/Unit" + application/json;version=1: + schema: + $ref: "#/components/schemas/LocationLevelRefs" + "*/*": + schema: + $ref: "#/components/schemas/LocationLevelRefs" + application/json: + schema: + $ref: "#/components/schemas/LocationLevelRefs" + "400": + description: Bad Request + content: + application/json: + schema: + $ref: "#/components/schemas/CdaError" + "401": + description: Unauthorized + content: + application/json: + schema: + $ref: "#/components/schemas/CdaError" + "403": + description: Forbidden + content: + application/json: + schema: + $ref: "#/components/schemas/CdaError" + "404": + description: Not Found + content: + application/json: + schema: + $ref: "#/components/schemas/CdaError" + "500": + description: Server Error + content: + application/json: + schema: + $ref: "#/components/schemas/CdaError" + security: [] + /timeseries/recent: get: tags: - TimeSeries @@ -18084,6 +18192,57 @@ components: format: date-time vertical-datum-info: "$ref": "#/components/schemas/vertical-datum-info" + LocationLevelRef: + required: + - location-level-id + type: object + properties: + location-level-id: + $ref: "#/components/schemas/CwmsId" + aliases: + uniqueItems: true + type: array + items: + type: string + effective-dates: + uniqueItems: true + type: array + description: The date/time at which this location level configuration takes + effect. + items: + type: string + description: The date/time at which this location level configuration takes + effect. + format: date-time + description: List of retrieved location levels ids and effective dates + LocationLevelRefs: + type: object + properties: + levels: + type: array + description: List of retrieved location levels ids and effective dates + items: + $ref: "#/components/schemas/LocationLevelRef" + next-page: + type: string + description: The cursor to the next page of data; null if there is no more data + readOnly: true + page: + type: string + description: The cursor to the current page of data + readOnly: true + page-size: + type: integer + description: The number of records fetched per-page; this may be larger than the + number of records actually retrieved + format: int32 + readOnly: true + total: + type: integer + description: The total number of records retrieved; null or not present if not + supported or unknown + format: int32 + readOnly: true UnitSystem: type: string description: Unit System desired in response. Can be SI (International Scientific) diff --git a/cwms-data-api-model/src/main/java/mil/army/usace/hec/cwms/data/api/client/model/LocationLevelRef.java b/cwms-data-api-model/src/main/java/mil/army/usace/hec/cwms/data/api/client/model/LocationLevelRef.java new file mode 100644 index 00000000..977171a7 --- /dev/null +++ b/cwms-data-api-model/src/main/java/mil/army/usace/hec/cwms/data/api/client/model/LocationLevelRef.java @@ -0,0 +1,126 @@ +package mil.army.usace.hec.cwms.data.api.client.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * List of retrieved location levels ids and effective dates + */ +@JsonIgnoreProperties(ignoreUnknown = true) +@jakarta.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.SpringCodegen", date = "2026-05-03T12:34:59.760765100-07:00[America/Los_Angeles]") +public class LocationLevelRef { + + @JsonProperty("location-level-id") + private CwmsId locationLevelId = null; + + @JsonProperty("aliases") + @Valid + private List aliases = new ArrayList<>(); + + @JsonProperty("effective-dates") + @Valid + private List effectiveDates = new ArrayList<>(); + + public LocationLevelRef locationLevelId(CwmsId locationLevelId) { + this.locationLevelId = locationLevelId; + return this; + } + + public CwmsId getLocationLevelId() { + return locationLevelId; + } + + public void setLocationLevelId(CwmsId locationLevelId) { + this.locationLevelId = locationLevelId; + } + + public LocationLevelRef aliases(List aliases) { + this.aliases = aliases; + return this; + } + + public LocationLevelRef addAliasesItem(String aliasesItem) { + if (this.aliases == null) { + this.aliases = new ArrayList<>(); + } + this.aliases.add(aliasesItem); + return this; + } + + public List getAliases() { + return aliases; + } + + public void setAliases(List aliases) { + this.aliases = aliases; + } + + public LocationLevelRef effectiveDates(List effectiveDates) { + this.effectiveDates = effectiveDates; + return this; + } + + public LocationLevelRef addEffectiveDatesItem(Instant effectiveDatesItem) { + if (this.effectiveDates == null) { + this.effectiveDates = new ArrayList<>(); + } + this.effectiveDates.add(effectiveDatesItem); + return this; + } + + public List getEffectiveDates() { + return effectiveDates; + } + + public void setEffectiveDates(List effectiveDates) { + this.effectiveDates = effectiveDates; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + LocationLevelRef locationLevelRef = (LocationLevelRef) o; + return Objects.equals(this.locationLevelId, locationLevelRef.locationLevelId) + && Objects.equals(this.aliases, locationLevelRef.aliases) + && Objects.equals(this.effectiveDates, locationLevelRef.effectiveDates) + ; + } + + @Override + public int hashCode() { + return Objects.hash(locationLevelId, aliases, effectiveDates); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class LocationLevelRef {\n"); + + sb.append(" locationLevelId: ").append(toIndentedString(locationLevelId)).append("\n"); + sb.append(" aliases: ").append(toIndentedString(aliases)).append("\n"); + sb.append(" effectiveDates: ").append(toIndentedString(effectiveDates)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} diff --git a/cwms-data-api-model/src/main/java/mil/army/usace/hec/cwms/data/api/client/model/LocationLevelRefs.java b/cwms-data-api-model/src/main/java/mil/army/usace/hec/cwms/data/api/client/model/LocationLevelRefs.java new file mode 100644 index 00000000..d53cd8a5 --- /dev/null +++ b/cwms-data-api-model/src/main/java/mil/army/usace/hec/cwms/data/api/client/model/LocationLevelRefs.java @@ -0,0 +1,152 @@ +package mil.army.usace.hec.cwms.data.api.client.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * LocationLevelRefs + */ +@JsonIgnoreProperties(ignoreUnknown = true) +@jakarta.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.SpringCodegen", date = "2026-05-03T12:34:59.760765100-07:00[America/Los_Angeles]") +public class LocationLevelRefs { + + @JsonProperty("levels") + @Valid + private List levels = new ArrayList<>(); + + @JsonProperty("next-page") + private String nextPage = null; + + @JsonProperty("page") + private String page = null; + + @JsonProperty("page-size") + private Integer pageSize = null; + + @JsonProperty("total") + private Integer total = null; + + public LocationLevelRefs levels(List levels) { + this.levels = levels; + return this; + } + + public LocationLevelRefs addLevelsItem(LocationLevelRef levelsItem) { + if (this.levels == null) { + this.levels = new ArrayList<>(); + } + this.levels.add(levelsItem); + return this; + } + + public List getLevels() { + return levels; + } + + public void setLevels(List levels) { + this.levels = levels; + } + + public LocationLevelRefs nextPage(String nextPage) { + this.nextPage = nextPage; + return this; + } + + public String getNextPage() { + return nextPage; + } + + public void setNextPage(String nextPage) { + this.nextPage = nextPage; + } + + public LocationLevelRefs page(String page) { + this.page = page; + return this; + } + + public String getPage() { + return page; + } + + public void setPage(String page) { + this.page = page; + } + + public LocationLevelRefs pageSize(Integer pageSize) { + this.pageSize = pageSize; + return this; + } + + public Integer getPageSize() { + return pageSize; + } + + public void setPageSize(Integer pageSize) { + this.pageSize = pageSize; + } + + public LocationLevelRefs total(Integer total) { + this.total = total; + return this; + } + + public Integer getTotal() { + return total; + } + + public void setTotal(Integer total) { + this.total = total; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + LocationLevelRefs locationLevelRefs = (LocationLevelRefs) o; + return Objects.equals(this.levels, locationLevelRefs.levels) + && this.nextPage == null || locationLevelRefs.nextPage == null?Objects.equals(this.nextPage, locationLevelRefs.nextPage):this.nextPage.equalsIgnoreCase(locationLevelRefs.nextPage) + && this.page == null || locationLevelRefs.page == null?Objects.equals(this.page, locationLevelRefs.page):this.page.equalsIgnoreCase(locationLevelRefs.page) + && Objects.equals(this.pageSize, locationLevelRefs.pageSize) + && Objects.equals(this.total, locationLevelRefs.total) + ; + } + + @Override + public int hashCode() { + return Objects.hash(levels, nextPage==null?0:nextPage.toLowerCase(), page==null?0:page.toLowerCase(), pageSize, total); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class LocationLevelRefs {\n"); + + sb.append(" levels: ").append(toIndentedString(levels)).append("\n"); + sb.append(" nextPage: ").append(toIndentedString(nextPage)).append("\n"); + sb.append(" page: ").append(toIndentedString(page)).append("\n"); + sb.append(" pageSize: ").append(toIndentedString(pageSize)).append("\n"); + sb.append(" total: ").append(toIndentedString(total)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +}