Skip to content

Commit 8060c9d

Browse files
authored
Merge pull request #244 from rma-bryson/feature/CWMSVUE-611_Measurements_Updates
CWMSVUE-611 - Implements measurement endpoint input and client controller with unit tests
2 parents 4099203 + f6031c7 commit 8060c9d

File tree

11 files changed

+1674
-0
lines changed

11 files changed

+1674
-0
lines changed

cwms-http-client/src/main/java/mil/army/usace/hec/cwms/http/client/EndpointInput.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,14 @@
2424

2525
package mil.army.usace.hec.cwms.http.client;
2626

27+
import java.util.Optional;
28+
2729
public abstract class EndpointInput {
2830

2931
protected abstract HttpRequestBuilder addInputParameters(HttpRequestBuilder httpRequestBuilder);
32+
33+
protected static <T> String getNullableFieldString(T field)
34+
{
35+
return Optional.ofNullable(field).map(Object::toString).orElse(null);
36+
}
3037
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* MIT License
3+
*
4+
* Copyright (c) 2024 Hydrologic Engineering Center
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
package mil.army.usace.hec.cwms.radar.client.controllers;
25+
26+
import mil.army.usace.hec.cwms.http.client.ApiConnectionInfo;
27+
import mil.army.usace.hec.cwms.http.client.HttpRequestBuilderImpl;
28+
import mil.army.usace.hec.cwms.http.client.HttpRequestResponse;
29+
import mil.army.usace.hec.cwms.http.client.request.HttpRequestExecutor;
30+
import mil.army.usace.hec.cwms.radar.client.model.Measurement;
31+
import mil.army.usace.hec.cwms.radar.client.model.RadarObjectMapper;
32+
33+
import java.io.IOException;
34+
import java.util.List;
35+
36+
import static mil.army.usace.hec.cwms.radar.client.controllers.RadarEndpointConstants.ACCEPT_HEADER_V1;
37+
import static mil.army.usace.hec.cwms.radar.client.controllers.RadarEndpointConstants.ACCEPT_QUERY_HEADER;
38+
39+
public final class MeasurementController {
40+
41+
private static final String MEASUREMENT_ENDPOINT = "measurements";
42+
43+
public List<Measurement> retrieveMeasurements(ApiConnectionInfo apiConnectionInfo, MeasurementEndpointInput.GetAll input)
44+
throws IOException {
45+
HttpRequestExecutor executor = new HttpRequestBuilderImpl(apiConnectionInfo, MEASUREMENT_ENDPOINT)
46+
.addQueryHeader(ACCEPT_QUERY_HEADER, ACCEPT_HEADER_V1)
47+
.addEndpointInput(input)
48+
.get()
49+
.withMediaType(ACCEPT_HEADER_V1);
50+
try (HttpRequestResponse response = executor.execute()) {
51+
return RadarObjectMapper.mapJsonToListOfObjects(response.getBody(), Measurement.class);
52+
}
53+
}
54+
55+
public void storeMeasurements(ApiConnectionInfo apiConnectionInfo, MeasurementEndpointInput.Post input) throws IOException {
56+
String body = RadarObjectMapper.mapObjectToJson(input.measurements());
57+
new HttpRequestBuilderImpl(apiConnectionInfo, MEASUREMENT_ENDPOINT)
58+
.addQueryHeader(ACCEPT_QUERY_HEADER, ACCEPT_HEADER_V1)
59+
.addEndpointInput(input)
60+
.post()
61+
.withBody(body)
62+
.withMediaType(ACCEPT_HEADER_V1)
63+
.execute()
64+
.close();
65+
}
66+
67+
public void deleteMeasurement(ApiConnectionInfo apiConnectionInfo, MeasurementEndpointInput.Delete input) throws IOException {
68+
String endpoint = MEASUREMENT_ENDPOINT + "/" + input.getLocationId();
69+
new HttpRequestBuilderImpl(apiConnectionInfo, endpoint)
70+
.addQueryHeader(ACCEPT_QUERY_HEADER, ACCEPT_HEADER_V1)
71+
.addEndpointInput(input)
72+
.delete()
73+
.withMediaType(ACCEPT_HEADER_V1)
74+
.execute()
75+
.close();
76+
}
77+
}
Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
package mil.army.usace.hec.cwms.radar.client.controllers;
2+
3+
/*
4+
* MIT License
5+
*
6+
* Copyright (c) 2024 Hydrologic Engineering Center
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in all
16+
* copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24+
* SOFTWARE.
25+
*/
26+
27+
import java.time.Instant;
28+
import java.util.ArrayList;
29+
import java.util.List;
30+
import mil.army.usace.hec.cwms.http.client.EndpointInput;
31+
import mil.army.usace.hec.cwms.http.client.HttpRequestBuilder;
32+
import mil.army.usace.hec.cwms.radar.client.model.Measurement;
33+
import java.util.Objects;
34+
35+
import static mil.army.usace.hec.cwms.radar.client.controllers.RadarEndpointConstants.ACCEPT_HEADER_V1;
36+
import static mil.army.usace.hec.cwms.radar.client.controllers.RadarEndpointConstants.ACCEPT_QUERY_HEADER;
37+
38+
public final class MeasurementEndpointInput {
39+
40+
private MeasurementEndpointInput() {
41+
throw new AssertionError("factory class");
42+
}
43+
44+
public static GetAll getAll() {
45+
return new GetAll();
46+
}
47+
48+
public static Post post(List<Measurement> measurements) {
49+
return new Post(measurements);
50+
}
51+
52+
public static Delete delete(String officeId, String locationId, Instant begin, Instant end) {
53+
return new Delete(officeId, locationId, begin, end);
54+
}
55+
56+
public static final class GetAll extends EndpointInput {
57+
static final String OFFICE_QUERY_PARAMETER = "office";
58+
static final String LOCATION_QUERY_PARAMETER = "location-id";
59+
static final String UNIT_SYSTEM_QUERY_PARAMETER = "unit-system";
60+
static final String MIN_NUMBER_QUERY_PARAMETER = "min-number";
61+
static final String MAX_NUMBER_QUERY_PARAMETER = "max-number";
62+
static final String BEGIN_QUERY_PARAMETER = "begin";
63+
static final String END_QUERY_PARAMETER = "end";
64+
static final String TIMEZONE_QUERY_PARAMETER = "timezone";
65+
static final String MIN_HEIGHT_QUERY_PARAMETER = "min-height";
66+
static final String MAX_HEIGHT_QUERY_PARAMETER = "max-height";
67+
static final String MIN_FLOW_QUERY_PARAMETER = "min-flow";
68+
static final String MAX_FLOW_QUERY_PARAMETER = "max-flow";
69+
static final String AGENCY_QUERY_PARAMETER = "agency";
70+
static final String QUALITY_QUERY_PARAMETER = "quality";
71+
72+
private String officeId;
73+
private String locationId;
74+
private String unitSystem;
75+
private String minNum;
76+
private String maxNum;
77+
private Instant begin;
78+
private Instant end;
79+
private String timezone;
80+
private Number minHeight;
81+
private Number maxHeight;
82+
private Number minFlow;
83+
private Number maxFlow;
84+
private String agency;
85+
private String quality;
86+
87+
private GetAll() {
88+
//all fields are optional masks
89+
}
90+
91+
public GetAll withOfficeIdMask(String officeId) {
92+
this.officeId = officeId;
93+
return this;
94+
}
95+
96+
public GetAll withLocationIdMask(String locationId) {
97+
this.locationId = locationId;
98+
return this;
99+
}
100+
101+
public GetAll withUnitSystem(String unitSystem) {
102+
this.unitSystem = unitSystem;
103+
return this;
104+
}
105+
106+
public GetAll withMinNumber(String minNum) {
107+
this.minNum = minNum;
108+
return this;
109+
}
110+
111+
public GetAll withMaxNumber(String maxNum) {
112+
this.maxNum = maxNum;
113+
return this;
114+
}
115+
116+
public GetAll withBegin(Instant minDate) {
117+
this.begin = minDate;
118+
return this;
119+
}
120+
121+
public GetAll withEnd(Instant maxDate) {
122+
this.end = maxDate;
123+
return this;
124+
}
125+
126+
public GetAll withTimezone(String timezone) {
127+
this.timezone = timezone;
128+
return this;
129+
}
130+
131+
public GetAll withMinHeight(Number minHeight) {
132+
this.minHeight = minHeight;
133+
return this;
134+
}
135+
136+
public GetAll withMaxHeight(Number maxHeight) {
137+
this.maxHeight = maxHeight;
138+
return this;
139+
}
140+
141+
public GetAll withMinFlow(Number minFlow) {
142+
this.minFlow = minFlow;
143+
return this;
144+
}
145+
146+
public GetAll withMaxFlow(Number maxFlow) {
147+
this.maxFlow = maxFlow;
148+
return this;
149+
}
150+
151+
public GetAll withAgency(String agency) {
152+
this.agency = agency;
153+
return this;
154+
}
155+
156+
public GetAll withQuality(String quality) {
157+
this.quality = quality;
158+
return this;
159+
}
160+
161+
@Override
162+
protected HttpRequestBuilder addInputParameters(HttpRequestBuilder httpRequestBuilder) {
163+
return httpRequestBuilder.addQueryParameter(OFFICE_QUERY_PARAMETER, officeId)
164+
.addQueryParameter(LOCATION_QUERY_PARAMETER, locationId)
165+
.addQueryParameter(UNIT_SYSTEM_QUERY_PARAMETER, unitSystem)
166+
.addQueryParameter(MIN_NUMBER_QUERY_PARAMETER, getNullableFieldString(minNum))
167+
.addQueryParameter(MAX_NUMBER_QUERY_PARAMETER, getNullableFieldString(maxNum))
168+
.addQueryParameter(BEGIN_QUERY_PARAMETER, getNullableFieldString(minHeight))
169+
.addQueryParameter(END_QUERY_PARAMETER, getNullableFieldString(maxHeight))
170+
.addQueryParameter(MIN_HEIGHT_QUERY_PARAMETER, getNullableFieldString(minHeight))
171+
.addQueryParameter(MAX_HEIGHT_QUERY_PARAMETER, getNullableFieldString(maxHeight))
172+
.addQueryParameter(MIN_FLOW_QUERY_PARAMETER, getNullableFieldString(minFlow))
173+
.addQueryParameter(MAX_FLOW_QUERY_PARAMETER, getNullableFieldString(maxFlow))
174+
.addQueryParameter(BEGIN_QUERY_PARAMETER, getNullableFieldString(begin))
175+
.addQueryParameter(END_QUERY_PARAMETER, getNullableFieldString(end))
176+
.addQueryParameter(TIMEZONE_QUERY_PARAMETER, timezone)
177+
.addQueryParameter(AGENCY_QUERY_PARAMETER, agency)
178+
.addQueryParameter(QUALITY_QUERY_PARAMETER, quality)
179+
.addQueryHeader(ACCEPT_QUERY_HEADER, ACCEPT_HEADER_V1);
180+
}
181+
}
182+
183+
public static final class Post extends EndpointInput {
184+
static final String FAIL_IF_EXISTS_QUERY_PARAMETER = "fail-if-exists";
185+
private final List<Measurement> measurements;
186+
private boolean failIfExists = true;
187+
188+
private Post(List<Measurement> measurement) {
189+
this.measurements = Objects.requireNonNull(measurement,"Measurement is required for the POST endpoint");
190+
}
191+
192+
public MeasurementEndpointInput.Post failIfExists(boolean failIfExists) {
193+
this.failIfExists = failIfExists;
194+
return this;
195+
}
196+
197+
List<Measurement> measurements() {
198+
return new ArrayList<>(measurements);
199+
}
200+
201+
@Override
202+
protected HttpRequestBuilder addInputParameters(HttpRequestBuilder httpRequestBuilder) {
203+
return httpRequestBuilder.addQueryParameter(FAIL_IF_EXISTS_QUERY_PARAMETER, Boolean.toString(failIfExists))
204+
.addQueryHeader(ACCEPT_QUERY_HEADER, ACCEPT_HEADER_V1);
205+
}
206+
}
207+
208+
public static final class Delete extends EndpointInput {
209+
static final String OFFICE_QUERY_PARAMETER = "office";
210+
static final String BEGIN_QUERY_PARAMETER = "begin";
211+
static final String END_QUERY_PARAMETER = "end";
212+
static final String TIMEZONE_QUERY_PARAMETER = "timezone";
213+
static final String MIN_NUMBER_QUERY_PARAMETER = "min-number";
214+
static final String MAX_NUMBER_QUERY_PARAMETER = "max-number";
215+
private final String locationId;
216+
private final String officeId;
217+
private final Instant begin;
218+
private final Instant end;
219+
private String minNumber;
220+
private String maxNumber;
221+
private String timezone;
222+
223+
private Delete(String officeId, String locationId, Instant begin, Instant end) {
224+
this.locationId = Objects.requireNonNull(locationId, "location id is required for the DELETE endpoint");
225+
this.officeId = Objects.requireNonNull(officeId, "office id is required for the DELETE endpoint");
226+
this.begin = Objects.requireNonNull(begin, "begin date is required for the DELETE endpoint");
227+
this.end = Objects.requireNonNull(end, "end date is required for the DELETE endpoint");
228+
}
229+
230+
String getLocationId() {
231+
return locationId;
232+
}
233+
234+
public Delete withMinNumber(String minNumber) {
235+
this.minNumber = minNumber;
236+
return this;
237+
}
238+
239+
public Delete withMaxNumber(String maxNumber) {
240+
this.maxNumber = maxNumber;
241+
return this;
242+
}
243+
244+
public Delete withTimezone(String timezone) {
245+
this.timezone = timezone;
246+
return this;
247+
}
248+
249+
@Override
250+
protected HttpRequestBuilder addInputParameters(HttpRequestBuilder httpRequestBuilder) {
251+
return httpRequestBuilder.addQueryParameter(OFFICE_QUERY_PARAMETER, officeId)
252+
.addQueryParameter(BEGIN_QUERY_PARAMETER, begin.toString())
253+
.addQueryParameter(END_QUERY_PARAMETER, end.toString())
254+
.addQueryParameter(TIMEZONE_QUERY_PARAMETER, timezone)
255+
.addQueryParameter(MIN_NUMBER_QUERY_PARAMETER, getNullableFieldString(minNumber))
256+
.addQueryParameter(MAX_NUMBER_QUERY_PARAMETER, getNullableFieldString(maxNumber))
257+
.addQueryHeader(ACCEPT_QUERY_HEADER, ACCEPT_HEADER_V1);
258+
}
259+
}
260+
}
261+

0 commit comments

Comments
 (0)