Skip to content

Commit 7f3ebaf

Browse files
authored
Updated Water Contract Type controller to add delete functionality (#866)
Added delete functionality to Water Contract Type controller
1 parent adb424e commit 7f3ebaf

File tree

7 files changed

+233
-11
lines changed

7 files changed

+233
-11
lines changed

cwms-data-api/src/main/java/cwms/cda/ApiServlet.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@
127127
import cwms.cda.api.watersupply.WaterContractDeleteController;
128128
import cwms.cda.api.watersupply.WaterContractTypeCatalogController;
129129
import cwms.cda.api.watersupply.WaterContractTypeCreateController;
130+
import cwms.cda.api.watersupply.WaterContractTypeDeleteController;
130131
import cwms.cda.api.watersupply.WaterContractUpdateController;
131132
import cwms.cda.api.watersupply.WaterPumpDisassociateController;
132133
import cwms.cda.api.watersupply.WaterUserCatalogController;
@@ -627,6 +628,7 @@ private void addWaterContractHandlers(String path, RouteRole[] requiredRoles) {
627628
private void addWaterContractTypeHandlers(String path, RouteRole[] requiredRoles) {
628629
post(path, new WaterContractTypeCreateController(metrics), requiredRoles);
629630
get(path, new WaterContractTypeCatalogController(metrics));
631+
delete(path + "/{display-value}", new WaterContractTypeDeleteController(metrics), requiredRoles);
630632
}
631633

632634
/**

cwms-data-api/src/main/java/cwms/cda/api/watersupply/WaterContractTypeCreateController.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
import cwms.cda.data.dto.LookupType;
3737
import cwms.cda.formatters.ContentType;
3838
import cwms.cda.formatters.Formats;
39-
import io.javalin.core.util.Header;
4039
import io.javalin.http.Context;
4140
import io.javalin.http.Handler;
4241
import io.javalin.plugin.openapi.annotations.HttpMethod;
@@ -86,7 +85,7 @@ public void handle(@NotNull Context ctx) {
8685
ctx.contentType(contentType.toString());
8786
LookupType contractType = Formats.parseContent(contentType, ctx.body(), LookupType.class);
8887
WaterContractDao contractDao = getContractDao(dsl);
89-
contractDao.storeWaterContractTypes(contractType, failIfExists);
88+
contractDao.storeWaterContractType(contractType, failIfExists);
9089
ctx.status(HttpServletResponse.SC_CREATED).json("Contract type successfully stored to CWMS.");
9190
}
9291
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
*
3+
* MIT License
4+
*
5+
* Copyright (c) 2024 Hydrologic Engineering Center
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy
8+
* of this software and associated documentation files (the "Software"), to deal
9+
* in the Software without restriction, including without limitation the rights
10+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
* copies of the Software, and to permit persons to whom the Software is
12+
* furnished to do so, subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be included in all
15+
* copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23+
* DEALINGS IN THE
24+
* SOFTWARE.
25+
*/
26+
27+
package cwms.cda.api.watersupply;
28+
29+
import static cwms.cda.api.Controllers.DELETE;
30+
import static cwms.cda.api.Controllers.OFFICE;
31+
import static cwms.cda.data.dao.JooqDao.getDslContext;
32+
33+
import com.codahale.metrics.MetricRegistry;
34+
import com.codahale.metrics.Timer;
35+
import cwms.cda.data.dao.watersupply.WaterContractDao;
36+
import cwms.cda.data.dto.LookupType;
37+
import cwms.cda.formatters.ContentType;
38+
import cwms.cda.formatters.Formats;
39+
import io.javalin.http.Context;
40+
import io.javalin.http.Handler;
41+
import io.javalin.plugin.openapi.annotations.HttpMethod;
42+
import io.javalin.plugin.openapi.annotations.OpenApi;
43+
import io.javalin.plugin.openapi.annotations.OpenApiParam;
44+
import javax.servlet.http.HttpServletResponse;
45+
import org.jetbrains.annotations.NotNull;
46+
import org.jooq.DSLContext;
47+
48+
49+
public final class WaterContractTypeDeleteController extends WaterSupplyControllerBase implements Handler {
50+
51+
private static final String DISPLAY_VALUE = "display-value";
52+
53+
public WaterContractTypeDeleteController(MetricRegistry metrics) {
54+
waterMetrics(metrics);
55+
}
56+
57+
@OpenApi(
58+
pathParams = {
59+
@OpenApiParam(name = OFFICE, required = true, description = "The office associated with "
60+
+ "the contract type to delete"),
61+
@OpenApiParam(name = DISPLAY_VALUE, required = true, description = "The location associated with "
62+
+ "the contract type to delete"),
63+
},
64+
description = "Delete a water contract type",
65+
method = HttpMethod.DELETE,
66+
path = "/projects/{office}/contract-types/{display-value}",
67+
tags = {TAG}
68+
)
69+
70+
@Override
71+
public void handle(@NotNull Context ctx) {
72+
try (Timer.Context ignored = markAndTime(DELETE)) {
73+
DSLContext dsl = getDslContext(ctx);
74+
String office = ctx.pathParam(OFFICE);
75+
String displayValue = ctx.pathParam(DISPLAY_VALUE);
76+
String formatHeader = ctx.req.getContentType();
77+
ContentType contentType = Formats.parseHeader(formatHeader, LookupType.class);
78+
ctx.contentType(contentType.toString());
79+
WaterContractDao dao = new WaterContractDao(dsl);
80+
dao.deleteWaterContractType(office, displayValue);
81+
ctx.status(HttpServletResponse.SC_NO_CONTENT).json("Contract type successfully deleted from CWMS.");
82+
}
83+
}
84+
}

cwms-data-api/src/main/java/cwms/cda/data/dao/watersupply/WaterContractDao.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
import cwms.cda.api.errors.NotFoundException;
3232
import cwms.cda.data.dao.JooqDao;
33+
import cwms.cda.data.dao.LookupTypeDao;
3334
import cwms.cda.data.dao.location.kind.LocationUtil;
3435
import cwms.cda.data.dto.CwmsId;
3536
import cwms.cda.data.dto.LookupType;
@@ -176,7 +177,17 @@ public void deleteWaterContract(WaterUserContract contract, DeleteMethod deleteA
176177
});
177178
}
178179

179-
public void storeWaterContractTypes(LookupType lookupType,
180+
public void deleteWaterContractType(String office, String displayValue) {
181+
connection(dsl, c -> {
182+
setOffice(c, office);
183+
LookupTypeDao lookupTypeDao = new LookupTypeDao(DSL.using(c));
184+
String category = "AT_WS_CONTRACT_TYPE";
185+
String prefix = "WS_CONTRACT_TYPE";
186+
lookupTypeDao.deleteLookupType(category, prefix, office, displayValue);
187+
});
188+
}
189+
190+
public void storeWaterContractType(LookupType lookupType,
180191
boolean failIfExists) {
181192
connection(dsl, c -> {
182193
setOffice(c, lookupType.getOfficeId());

cwms-data-api/src/test/java/cwms/cda/api/WaterContractTypeCreateControllerTestIT.java renamed to cwms-data-api/src/test/java/cwms/cda/api/WaterContractTypeControllerTestIT.java

Lines changed: 103 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,39 +29,53 @@
2929
import static cwms.cda.data.dao.DaoTest.getDslContext;
3030
import static cwms.cda.security.KeyAccessManager.AUTH_HEADER;
3131
import static io.restassured.RestAssured.given;
32+
import static java.lang.String.format;
3233
import static org.hamcrest.Matchers.equalTo;
3334
import static org.hamcrest.Matchers.is;
3435

36+
import cwms.cda.api.errors.NotFoundException;
3537
import cwms.cda.data.dao.LookupTypeDao;
3638
import cwms.cda.data.dto.LookupType;
3739
import cwms.cda.formatters.Formats;
3840
import cwms.cda.formatters.json.JsonV1;
41+
import cwms.cda.helpers.DTOMatch;
3942
import fixtures.CwmsDataApiSetupCallback;
4043
import fixtures.TestAccounts;
4144
import io.restassured.filter.log.LogDetail;
4245
import mil.army.usace.hec.test.database.CwmsDatabaseContainer;
4346
import org.jooq.DSLContext;
47+
import org.junit.jupiter.api.AfterEach;
4448
import org.junit.jupiter.api.Tag;
4549
import org.junit.jupiter.api.Test;
4650
import javax.servlet.http.HttpServletResponse;
4751
import java.sql.SQLException;
52+
import java.util.Arrays;
53+
import java.util.List;
54+
import java.util.logging.Level;
55+
import java.util.logging.Logger;
4856

4957

5058
@Tag("integration")
51-
class WaterContractTypeCreateControllerTestIT extends DataApiTestIT {
59+
class WaterContractTypeControllerTestIT extends DataApiTestIT {
5260
private static final String OFFICE_ID = "SWT";
5361
private static final LookupType CONTRACT_TYPE;
62+
public static final Logger LOGGER =
63+
Logger.getLogger(WaterContractTypeControllerTestIT.class.getName());
5464
static {
5565
CONTRACT_TYPE = new LookupType.Builder().withActive(true).withOfficeId(OFFICE_ID)
5666
.withDisplayValue("TEST Contract Type").withTooltip("TEST LOOKUP").build();
5767
}
5868

69+
@AfterEach
70+
void cleanup() throws SQLException {
71+
cleanupType();
72+
}
73+
5974
@Test
6075
void test_create_get_WaterContractType() throws Exception {
6176
// Test Structure
6277
// 1) Create a WaterContractType
6378
// 2) Get the WaterContractType, assert it exists
64-
// 3) Cleanup
6579

6680
TestAccounts.KeyUser user = TestAccounts.KeyUser.SWT_NORMAL;
6781
String json = JsonV1.buildObjectMapper().writeValueAsString(CONTRACT_TYPE);
@@ -101,18 +115,101 @@ void test_create_get_WaterContractType() throws Exception {
101115
.body("[0].tooltip", equalTo(CONTRACT_TYPE.getTooltip()))
102116
.body("[0].active", equalTo(CONTRACT_TYPE.getActive()))
103117
;
118+
}
104119

105-
// cleanup
106-
cleanupType();
120+
@Test
121+
void test_store_delete_WaterContractType() throws Exception {
122+
// Test Structure
123+
// 1) Create a WaterContractType
124+
// 2) Get the WaterContractType, assert it exists
125+
// 3) Delete the WaterContractType
126+
// 4) Get the WaterContractType, assert it does not exist
127+
128+
TestAccounts.KeyUser user = TestAccounts.KeyUser.SWT_NORMAL;
129+
String json = JsonV1.buildObjectMapper().writeValueAsString(CONTRACT_TYPE);
130+
131+
// create water contract type
132+
given()
133+
.log().ifValidationFails(LogDetail.ALL, true)
134+
.contentType(Formats.JSONV1)
135+
.body(json)
136+
.queryParam("fail-if-exists", false)
137+
.header(AUTH_HEADER, user.toHeaderValue())
138+
.when()
139+
.redirects().follow(true)
140+
.redirects().max(3)
141+
.post("/projects/" + OFFICE_ID + "/contract-types")
142+
.then()
143+
.log().ifValidationFails(LogDetail.ALL, true)
144+
.assertThat()
145+
.statusCode(is(HttpServletResponse.SC_CREATED))
146+
;
147+
148+
// get water contract type and assert that it exists
149+
given()
150+
.log().ifValidationFails(LogDetail.ALL, true)
151+
.contentType(Formats.JSONV1)
152+
.header(AUTH_HEADER, user.toHeaderValue())
153+
.when()
154+
.redirects().follow(true)
155+
.redirects().max(3)
156+
.get("/projects/" + OFFICE_ID + "/contract-types")
157+
.then()
158+
.log().ifValidationFails(LogDetail.ALL, true)
159+
.assertThat()
160+
.statusCode(is(HttpServletResponse.SC_OK))
161+
.body("[0].office-id", equalTo(OFFICE_ID))
162+
.body("[0].display-value", equalTo(CONTRACT_TYPE.getDisplayValue()))
163+
.body("[0].tooltip", equalTo(CONTRACT_TYPE.getTooltip()))
164+
.body("[0].active", equalTo(CONTRACT_TYPE.getActive()))
165+
;
166+
167+
// delete water contract type
168+
given()
169+
.log().ifValidationFails(LogDetail.ALL, true)
170+
.contentType(Formats.JSONV1)
171+
.header(AUTH_HEADER, user.toHeaderValue())
172+
.when()
173+
.redirects().follow(true)
174+
.redirects().max(3)
175+
.delete("/projects/" + OFFICE_ID + "/contract-types/" + CONTRACT_TYPE.getDisplayValue())
176+
.then()
177+
.log().ifValidationFails(LogDetail.ALL, true)
178+
.assertThat()
179+
.statusCode(is(HttpServletResponse.SC_NO_CONTENT))
180+
;
181+
182+
// get water contract type and assert that it does not exist
183+
List<LookupType> results = Arrays.asList(given()
184+
.log().ifValidationFails(LogDetail.ALL, true)
185+
.contentType(Formats.JSONV1)
186+
.header(AUTH_HEADER, user.toHeaderValue())
187+
.when()
188+
.redirects().follow(true)
189+
.redirects().max(3)
190+
.get("/projects/" + OFFICE_ID + "/contract-types")
191+
.then()
192+
.log().ifValidationFails(LogDetail.ALL, true)
193+
.assertThat()
194+
.statusCode(is(HttpServletResponse.SC_OK))
195+
.extract().body().as(LookupType[].class))
196+
;
197+
DTOMatch.assertDoesNotContainDto(results, CONTRACT_TYPE,
198+
(i, s) -> i.getDisplayValue().equalsIgnoreCase(s.getDisplayValue()), "Contract Type not deleted");
107199
}
108200

109201
private void cleanupType() throws SQLException {
110202
CwmsDatabaseContainer<?> databaseLink = CwmsDataApiSetupCallback.getDatabaseLink();
111203
databaseLink.connection(c -> {
112204
DSLContext ctx = getDslContext(c, OFFICE_ID);
113205
LookupTypeDao lookupTypeDao = new LookupTypeDao(ctx);
114-
lookupTypeDao.deleteLookupType("AT_WS_CONTRACT_TYPE", "WS_CONTRACT_TYPE",
115-
CONTRACT_TYPE.getOfficeId(), CONTRACT_TYPE.getDisplayValue());
206+
try {
207+
208+
lookupTypeDao.deleteLookupType("AT_WS_CONTRACT_TYPE", "WS_CONTRACT_TYPE",
209+
CONTRACT_TYPE.getOfficeId(), CONTRACT_TYPE.getDisplayValue());
210+
} catch (NotFoundException e) {
211+
LOGGER.log(Level.CONFIG, format("Cleanup failed to delete lookup type: %s", e.getMessage()));
212+
}
116213
}, CwmsDataApiSetupCallback.getWebUser());
117214
}
118215
}

cwms-data-api/src/test/java/cwms/cda/api/WaterPumpDisassociateControllerTestIT.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ static void setUp() throws Exception {
155155
projectDao.store(project1, true);
156156
projectDao.store(project2, true);
157157
waterContractDao.storeWaterUser(CONTRACT.getWaterUser(), false);
158-
waterContractDao.storeWaterContractTypes(CONTRACT.getContractType(), false);
158+
waterContractDao.storeWaterContractType(CONTRACT.getContractType(), false);
159159
waterContractDao.storeWaterUser(CONTRACT_NO_PUMP.getWaterUser(), false);
160160
} catch (IOException e) {
161161
throw new RuntimeException(e);

cwms-data-api/src/test/java/cwms/cda/data/dao/watersupply/WaterContractDaoTestIT.java

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,28 @@ void cleanup() throws SQLException {
135135
}, CwmsDataApiSetupCallback.getWebUser());
136136
}
137137

138+
@Test
139+
void testStoreAndDeleteWaterContractType() throws Exception {
140+
LookupType contractType = new LookupType.Builder()
141+
.withTooltip("Test Tooltip Delete")
142+
.withActive(true)
143+
.withDisplayValue("Test Display Value Delete")
144+
.withOfficeId(OFFICE_ID).build();
145+
CwmsDatabaseContainer<?> db = CwmsDataApiSetupCallback.getDatabaseLink();
146+
db.connection(c -> {
147+
DSLContext ctx = getDslContext(c, OFFICE_ID);
148+
WaterContractDao dao = new WaterContractDao(ctx);
149+
dao.storeWaterContractType(contractType, false);
150+
List<LookupType> retrievedType = dao.getAllWaterContractTypes(OFFICE_ID);
151+
DTOMatch.assertContainsDto(retrievedType, contractType, WaterContractDaoTestIT::typeMatches,
152+
DTOMatch::assertMatch, "Contract Type not stored");
153+
dao.deleteWaterContractType(contractType.getOfficeId(), contractType.getDisplayValue());
154+
retrievedType = dao.getAllWaterContractTypes(OFFICE_ID);
155+
DTOMatch.assertDoesNotContainDto(retrievedType, contractType, WaterContractDaoTestIT::typeMatches,
156+
"Contract Type not deleted");
157+
}, CwmsDataApiSetupCallback.getWebUser());
158+
}
159+
138160
@Test
139161
void testStoreAndRetrieveWaterUserList() throws Exception {
140162
CwmsDatabaseContainer<?> db = CwmsDataApiSetupCallback.getDatabaseLink();
@@ -243,7 +265,7 @@ void testStoreAndRetrieveWaterContractType() throws Exception {
243265
.withActive(true)
244266
.withDisplayValue("Test Display Value")
245267
.withOfficeId(OFFICE_ID).build();
246-
dao.storeWaterContractTypes(contractType, false);
268+
dao.storeWaterContractType(contractType, false);
247269
List<LookupType> results = dao.getAllWaterContractTypes(OFFICE_ID);
248270
DTOMatch.assertMatch(contractType, results.get(0));
249271
}, CwmsDataApiSetupCallback.getWebUser());
@@ -356,6 +378,13 @@ void testRemovePumpFromContract() throws Exception {
356378
}, CwmsDataApiSetupCallback.getWebUser());
357379
}
358380

381+
private static boolean typeMatches(LookupType type, LookupType other) {
382+
return type.getTooltip().equals(other.getTooltip()) &&
383+
type.getDisplayValue().equals(other.getDisplayValue()) &&
384+
type.getOfficeId().equals(other.getOfficeId()) &&
385+
type.getActive() == other.getActive();
386+
}
387+
359388
private static WaterUser buildTestWaterUser(String entityName) {
360389
return new WaterUser.Builder().withEntityName(entityName).withProjectId(new CwmsId.Builder()
361390
.withName(testLocation.getName())

0 commit comments

Comments
 (0)