Skip to content

Commit 950ae3a

Browse files
authored
Merge pull request #287 from HydrologicEngineeringCenter/feature/CDA-54-add-entity-endpoint
CDA-54 Implements entity endpoint support
2 parents 9b53171 + 83a76c7 commit 950ae3a

File tree

8 files changed

+4502
-2737
lines changed

8 files changed

+4502
-2737
lines changed
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*
2+
* MIT License
3+
*
4+
* Copyright (c) 2025 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+
25+
package mil.army.usace.hec.cwms.data.api.client.controllers;
26+
27+
import static mil.army.usace.hec.cwms.data.api.client.controllers.CdaEndpointConstants.ACCEPT_HEADER_V1;
28+
import static mil.army.usace.hec.cwms.data.api.client.controllers.CdaEndpointConstants.ACCEPT_QUERY_HEADER;
29+
30+
import java.io.IOException;
31+
import java.util.List;
32+
import mil.army.usace.hec.cwms.data.api.client.model.Entity;
33+
import mil.army.usace.hec.cwms.data.api.client.model.RadarObjectMapper;
34+
import mil.army.usace.hec.cwms.http.client.ApiConnectionInfo;
35+
import mil.army.usace.hec.cwms.http.client.HttpRequestBuilderImpl;
36+
import mil.army.usace.hec.cwms.http.client.HttpRequestResponse;
37+
import mil.army.usace.hec.cwms.http.client.request.HttpRequestExecutor;
38+
39+
public final class EntityController {
40+
41+
private static final String ENTITY_ENDPOINT = "entity";
42+
43+
public Entity retrieveEntity(ApiConnectionInfo apiConnectionInfo, EntityEndpointInput.GetOne input) throws IOException {
44+
String endpoint = ENTITY_ENDPOINT + "/" + input.entityId();
45+
HttpRequestExecutor executor = new HttpRequestBuilderImpl(apiConnectionInfo, 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.mapJsonToObject(response.getBody(), Entity.class);
52+
}
53+
}
54+
55+
public List<Entity> retrieveEntities(ApiConnectionInfo apiConnectionInfo, EntityEndpointInput.GetAll input) throws IOException {
56+
HttpRequestExecutor executor = new HttpRequestBuilderImpl(apiConnectionInfo, ENTITY_ENDPOINT)
57+
.addQueryHeader(ACCEPT_QUERY_HEADER, ACCEPT_HEADER_V1)
58+
.addEndpointInput(input)
59+
.get()
60+
.withMediaType(ACCEPT_HEADER_V1);
61+
try (HttpRequestResponse response = executor.execute()) {
62+
return RadarObjectMapper.mapJsonToListOfObjects(response.getBody(), Entity.class);
63+
}
64+
}
65+
66+
public void storeEntity(ApiConnectionInfo apiConnectionInfo, EntityEndpointInput.Post input) throws IOException {
67+
String body = RadarObjectMapper.mapObjectToJson(input.entity());
68+
new HttpRequestBuilderImpl(apiConnectionInfo, ENTITY_ENDPOINT)
69+
.addQueryHeader(ACCEPT_QUERY_HEADER, ACCEPT_HEADER_V1)
70+
.addEndpointInput(input)
71+
.post()
72+
.withBody(body)
73+
.withMediaType(ACCEPT_HEADER_V1)
74+
.execute()
75+
.close();
76+
}
77+
78+
public void updateEntity(ApiConnectionInfo apiConnectionInfo, EntityEndpointInput.Patch input) throws IOException {
79+
String body = RadarObjectMapper.mapObjectToJson(input.entity());
80+
new HttpRequestBuilderImpl(apiConnectionInfo, ENTITY_ENDPOINT + "/" + input.entity().getId().getName())
81+
.addQueryHeader(ACCEPT_QUERY_HEADER, ACCEPT_HEADER_V1)
82+
.addEndpointInput(input)
83+
.patch()
84+
.withBody(body)
85+
.withMediaType(ACCEPT_HEADER_V1)
86+
.execute()
87+
.close();
88+
}
89+
90+
public void deleteEntity(ApiConnectionInfo apiConnectionInfo, EntityEndpointInput.Delete input) throws IOException {
91+
String endpoint = ENTITY_ENDPOINT + "/" + input.entityId();
92+
new HttpRequestBuilderImpl(apiConnectionInfo, endpoint)
93+
.addQueryHeader(ACCEPT_QUERY_HEADER, ACCEPT_HEADER_V1)
94+
.addEndpointInput(input)
95+
.delete()
96+
.withMediaType(ACCEPT_HEADER_V1)
97+
.execute()
98+
.close();
99+
}
100+
}
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
/*
2+
* MIT License
3+
*
4+
* Copyright (c) 2025 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+
25+
package mil.army.usace.hec.cwms.data.api.client.controllers;
26+
27+
import static mil.army.usace.hec.cwms.data.api.client.controllers.CdaEndpointConstants.ACCEPT_HEADER_V1;
28+
import static mil.army.usace.hec.cwms.data.api.client.controllers.CdaEndpointConstants.ACCEPT_QUERY_HEADER;
29+
30+
import java.util.Objects;
31+
import mil.army.usace.hec.cwms.data.api.client.model.Entity;
32+
import mil.army.usace.hec.cwms.http.client.EndpointInput;
33+
import mil.army.usace.hec.cwms.http.client.HttpRequestBuilder;
34+
35+
public final class EntityEndpointInput {
36+
37+
private EntityEndpointInput() {
38+
throw new AssertionError("factory class");
39+
}
40+
41+
public static GetAll getAll() {
42+
return new GetAll();
43+
}
44+
45+
public static GetOne getOne(String entityId, String officeId) {
46+
return new GetOne(entityId, officeId);
47+
}
48+
49+
public static Post post(Entity entity) {
50+
return new Post(entity);
51+
}
52+
53+
public static Patch patch(Entity entity) {
54+
return new Patch(entity);
55+
}
56+
57+
public static Delete delete(String entityId, String officeId, boolean cascadeDelete) {
58+
return new Delete(entityId, officeId, cascadeDelete);
59+
}
60+
61+
public static final class GetAll extends EndpointInput {
62+
static final String OFFICE_QUERY_PARAMETER = "office";
63+
static final String ENTITY_ID_QUERY_PARAMETER = "entity-id";
64+
static final String PARENT_ENTITY_ID_QUERY_PARAMETER = "parent-entity-id";
65+
static final String CATEGORY_ID_QUERY_PARAMETER = "category-id";
66+
static final String LONG_NAME_QUERY_PARAMETER = "long-name";
67+
static final String MATCH_NULL_PARENTS_QUERY_PARAMETER = "match-null-parents";
68+
69+
private String officeId;
70+
private String entityId;
71+
private String parentEntityId;
72+
private String categoryId;
73+
private String longName;
74+
private boolean matchNullParents = true;
75+
76+
private GetAll() {
77+
// factory
78+
}
79+
80+
public GetAll officeId(String officeId) {
81+
this.officeId = officeId;
82+
return this;
83+
}
84+
85+
public GetAll entityId(String entityId) {
86+
this.entityId = entityId;
87+
return this;
88+
}
89+
90+
public GetAll parentEntityId(String parentEntityId) {
91+
this.parentEntityId = parentEntityId;
92+
return this;
93+
}
94+
95+
public GetAll categoryId(String categoryId) {
96+
this.categoryId = categoryId;
97+
return this;
98+
}
99+
100+
public GetAll longName(String longName) {
101+
this.longName = longName;
102+
return this;
103+
}
104+
105+
public GetAll matchNullParents(boolean matchNullParents) {
106+
this.matchNullParents = matchNullParents;
107+
return this;
108+
}
109+
110+
@Override
111+
protected HttpRequestBuilder addInputParameters(HttpRequestBuilder httpRequestBuilder) {
112+
return httpRequestBuilder
113+
.addQueryParameter(OFFICE_QUERY_PARAMETER, officeId)
114+
.addQueryParameter(ENTITY_ID_QUERY_PARAMETER, entityId)
115+
.addQueryParameter(PARENT_ENTITY_ID_QUERY_PARAMETER, parentEntityId)
116+
.addQueryParameter(CATEGORY_ID_QUERY_PARAMETER, categoryId)
117+
.addQueryParameter(LONG_NAME_QUERY_PARAMETER, longName)
118+
.addQueryParameter(MATCH_NULL_PARENTS_QUERY_PARAMETER, Boolean.toString(matchNullParents))
119+
.addQueryHeader(ACCEPT_QUERY_HEADER, ACCEPT_HEADER_V1);
120+
}
121+
}
122+
123+
public static final class GetOne extends EndpointInput {
124+
static final String OFFICE_QUERY_PARAMETER = "office";
125+
private final String entityId;
126+
private final String officeId;
127+
128+
private GetOne(String entityId, String officeId) {
129+
this.entityId = Objects.requireNonNull(entityId, "Id required for getOne entity endpoint");
130+
this.officeId = Objects.requireNonNull(officeId, "Office id required for getOne entity endpoint");
131+
}
132+
133+
String entityId() {
134+
return entityId;
135+
}
136+
137+
@Override
138+
protected HttpRequestBuilder addInputParameters(HttpRequestBuilder httpRequestBuilder) {
139+
return httpRequestBuilder.addQueryParameter(OFFICE_QUERY_PARAMETER, officeId)
140+
.addQueryHeader(ACCEPT_QUERY_HEADER, ACCEPT_HEADER_V1);
141+
}
142+
}
143+
144+
public static final class Post extends EndpointInput {
145+
private final Entity entity;
146+
147+
private Post(Entity entity) {
148+
this.entity = Objects.requireNonNull(entity, "Cannot access the entity POST endpoint without an entity object");
149+
}
150+
151+
Entity entity() {
152+
return entity;
153+
}
154+
155+
@Override
156+
protected HttpRequestBuilder addInputParameters(HttpRequestBuilder httpRequestBuilder) {
157+
return httpRequestBuilder.addQueryHeader(ACCEPT_QUERY_HEADER, ACCEPT_HEADER_V1);
158+
}
159+
}
160+
161+
public static final class Patch extends EndpointInput {
162+
private final Entity entity;
163+
164+
private Patch(Entity entity) {
165+
this.entity = Objects.requireNonNull(entity, "Cannot access the entity PATCH endpoint without an entity object");
166+
}
167+
168+
Entity entity() {
169+
return entity;
170+
}
171+
172+
@Override
173+
protected HttpRequestBuilder addInputParameters(HttpRequestBuilder httpRequestBuilder) {
174+
return httpRequestBuilder.addQueryHeader(ACCEPT_QUERY_HEADER, ACCEPT_HEADER_V1);
175+
}
176+
}
177+
178+
public static final class Delete extends EndpointInput {
179+
static final String OFFICE_QUERY_PARAMETER = "office";
180+
static final String CASCADE_DELETE_QUERY_PARAMETER = "cascade-delete";
181+
private final String entityId;
182+
private final String officeId;
183+
private final boolean cascadeDelete;
184+
185+
private Delete(String entityId, String officeId, boolean cascadeDelete) {
186+
this.entityId = Objects.requireNonNull(entityId, "Cannot access the entity DELETE endpoint without an id");
187+
this.officeId = Objects.requireNonNull(officeId, "Cannot access the entity DELETE endpoint without an office id");
188+
this.cascadeDelete = cascadeDelete;
189+
}
190+
191+
String entityId() {
192+
return entityId;
193+
}
194+
195+
@Override
196+
protected HttpRequestBuilder addInputParameters(HttpRequestBuilder httpRequestBuilder) {
197+
return httpRequestBuilder
198+
.addQueryParameter(OFFICE_QUERY_PARAMETER, officeId)
199+
.addQueryParameter(CASCADE_DELETE_QUERY_PARAMETER, Boolean.toString(cascadeDelete))
200+
.addQueryHeader(ACCEPT_QUERY_HEADER, ACCEPT_HEADER_V1);
201+
}
202+
}
203+
}

0 commit comments

Comments
 (0)