Skip to content

Add StatusResponse class to handle successful response messages #1167

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 41 commits into from
Jul 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
8d6f645
Add basic version of StatusResponse class
Jun 25, 2025
6a96c9d
Add serialization/deserialization unit tests for StatusResponse
Jun 25, 2025
83ca1e8
Get rid of harcoded vars in StatusResponse
Jul 1, 2025
c388048
Merge branch 'develop' into bugfix/invalid-JSON-mismatch
rohaan-rma Jul 1, 2025
277eea0
Make tests more realistic
Jul 1, 2025
5589725
Add possible StatusResponse usage in TurbineController, also fix Open…
Jul 1, 2025
ad9fc06
Make StatusResponse extend CwmsDTOBase, change response field to mess…
Jul 1, 2025
795b6fb
Add StatusResponse class to LevelsController and update basic IT (mor…
Jul 1, 2025
d193300
Add tests for TurbineController and finish tests for LevelsController
Jul 2, 2025
c65985e
Clean code: use levelId for testing identifier
Jul 2, 2025
5aebacc
Use levelId in tests for identifier
Jul 2, 2025
4cf8606
Add StatusResponse to LocationController and update tests
Jul 2, 2025
670c856
Add StatusResponse to EmbankmentController and IT
rohaan-rma Jul 3, 2025
bf83fa6
Add StatusResponse to StreamLocation
rohaan-rma Jul 3, 2025
887a5b6
Add office-id field back to StatusResponse
rohaan-rma Jul 3, 2025
81a558e
Update Controllers and tests to include office-id
rohaan-rma Jul 3, 2025
514878f
Merge branch 'develop' into bugfix/invalid-JSON-mismatch
rohaan-rma Jul 3, 2025
1064f01
Reformat tests and remove useless import
rohaan-rma Jul 3, 2025
209c1f9
Add StatusResponse to StreamController
rohaan-rma Jul 3, 2025
6afa97f
Add StatusResponse to BasinController
rohaan-rma Jul 3, 2025
e70a119
Add StatusResponse to LookupTypeController
rohaan-rma Jul 3, 2025
94fd73c
Add StatusRespoonse to WaterContractCRUDControllers
rohaan-rma Jul 7, 2025
c4e40ba
Add StatusResponse to WaterContractTypeControllers
rohaan-rma Jul 7, 2025
09f5293
Add StatusResponse to WaterUserControllers
rohaan-rma Jul 7, 2025
07d14a0
Add StatusResponse to LockController
rohaan-rma Jul 7, 2025
d6cc8f4
Add StatusResponse to PropertyController
rohaan-rma Jul 7, 2025
232c9b4
Add StatusResponse to MeasurementController
rohaan-rma Jul 7, 2025
8e21e9d
Add StatusResponse to OutletController
rohaan-rma Jul 7, 2025
db3779e
Remove unnecessary import and fix update message
rohaan-rma Jul 7, 2025
73d932f
Use String constants in tests
rohaan-rma Jul 7, 2025
56d34ab
Fix HTTP Status inconsistencies
rohaan-rma Jul 7, 2025
e54be2c
Fix bug in StreamLocationController
rohaan-rma Jul 7, 2025
7a9513b
Add StatusResponse to VirtualOutlet, AccountingCreate, Rating, Turbin…
rohaan-rma Jul 7, 2025
9f861b7
Revert "Add StatusResponse to VirtualOutlet, AccountingCreate, Rating…
rohaan-rma Jul 7, 2025
d4ff05d
Change Status codes from 204 -> 200, (NO_CONTENT to OK), to allow for…
rohaan-rma Jul 8, 2025
a4606e0
Fix a couple bugs and formatting/import issues
rohaan-rma Jul 8, 2025
7b05143
Fix status code mismatch
rohaan-rma Jul 8, 2025
5aecc94
Merge branch 'develop' into bugfix/invalid-JSON-mismatch
rohaan-rma Jul 8, 2025
f91a399
Fix format issues and update response messages
rohaan-rma Jul 9, 2025
04f779f
Merge branch 'develop' into bugfix/invalid-JSON-mismatch
rohaan-rma Jul 10, 2025
2c905ba
Fix broken Integration Tests to update to new Status codes
rohaan-rma Jul 11, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions cwms-data-api/src/main/java/cwms/cda/api/BasinController.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import cwms.cda.data.dao.JooqDao;
import cwms.cda.data.dao.basinconnectivity.BasinDao;
import cwms.cda.data.dto.CwmsId;
import cwms.cda.data.dto.StatusResponse;
import cwms.cda.data.dto.basinconnectivity.Basin;
import cwms.cda.formatters.ContentType;
import cwms.cda.formatters.Formats;
Expand Down Expand Up @@ -251,7 +252,8 @@ public void update(@NotNull Context ctx, @NotNull String name) {
.withOfficeId(officeId)
.build();
basinDao.renameBasin(oldLoc, newLoc);
ctx.status(HttpServletResponse.SC_OK).json("Updated Location");
StatusResponse re = new StatusResponse(officeId, "Updated Location", newBasinId);
ctx.status(HttpServletResponse.SC_OK).json(re);
}

@OpenApi(
Expand All @@ -276,21 +278,23 @@ public void create(@NotNull Context ctx) {
String newBasinId = basin.getBasinId().getName();
cwms.cda.data.dao.basin.BasinDao basinDao = new cwms.cda.data.dao.basin.BasinDao(dsl);
basinDao.storeBasin(basin);
ctx.status(HttpServletResponse.SC_CREATED).json(newBasinId + " Created");
StatusResponse re = new StatusResponse(basin.getBasinId().getOfficeId(),
"Basin successfully stored to CWMS.", newBasinId);
ctx.status(HttpServletResponse.SC_CREATED).json(re);
}

@OpenApi(
queryParams = {
@OpenApiParam(name = OFFICE, required = true, description = "Specifies the"
+ " owning office of the basin to be renamed."),
+ " owning office of the basin to be deleted."),
@OpenApiParam(name = METHOD, required = true, description = "Specifies the delete method used.",
type = JooqDao.DeleteMethod.class)
},
pathParams = {
@OpenApiParam(name = NAME, description = "Specifies the name of "
+ "the basin to be deleted.")
},
description = "Renames CWMS Basin",
description = "Deletes CWMS Basin",
tags = {TAG}
)
@Override
Expand All @@ -303,6 +307,7 @@ public void delete(@NotNull Context ctx, @NotNull String name) {
.withOfficeId(ctx.queryParam(OFFICE))
.build();
basinDao.deleteBasin(basinId, deleteMethod.getRule());
ctx.status(HttpServletResponse.SC_NO_CONTENT).json(basinId.getName() + " Deleted");
StatusResponse re = new StatusResponse(basinId.getOfficeId(), "Deleted CWMS Basin", basinId.getName());
ctx.status(HttpServletResponse.SC_OK).json(re);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import com.codahale.metrics.Timer;
import cwms.cda.data.dao.JooqDao;
import cwms.cda.data.dao.location.kind.EmbankmentDao;
import cwms.cda.data.dto.StatusResponse;
import cwms.cda.data.dto.location.kind.Embankment;
import cwms.cda.formatters.ContentType;
import cwms.cda.formatters.Formats;
Expand Down Expand Up @@ -167,7 +168,9 @@ public void create(Context ctx) {
DSLContext dsl = getDslContext(ctx);
EmbankmentDao dao = new EmbankmentDao(dsl);
dao.storeEmbankment(embankment, failIfExists);
ctx.status(HttpServletResponse.SC_CREATED).json("Created Embankment");
StatusResponse re = new StatusResponse(embankment.getLocation().getOfficeId(),
"Embankment successfully stored to CWMS", embankment.getLocation().getName());
ctx.status(HttpServletResponse.SC_CREATED).json(re);
}

}
Expand Down Expand Up @@ -197,7 +200,8 @@ public void update(@NotNull Context ctx, @NotNull String name) {
DSLContext dsl = getDslContext(ctx);
EmbankmentDao dao = new EmbankmentDao(dsl);
dao.renameEmbankment(office, name, newName);
ctx.status(HttpServletResponse.SC_OK).json("Renamed Embankment");
StatusResponse re = new StatusResponse(office, "Embankment successfully renamed in CWMS", newName);
ctx.status(HttpServletResponse.SC_OK).json(re);
}
}

Expand All @@ -217,7 +221,7 @@ public void update(@NotNull Context ctx, @NotNull String name) {
method = HttpMethod.DELETE,
tags = {TAG},
responses = {
@OpenApiResponse(status = STATUS_204, description = "Embankment successfully deleted from CWMS."),
@OpenApiResponse(status = STATUS_200, description = "Embankment successfully deleted from CWMS."),
@OpenApiResponse(status = STATUS_404, description = "Based on the combination of "
+ "inputs provided the embankment was not found.")
}
Expand All @@ -231,7 +235,8 @@ public void delete(@NotNull Context ctx, @NotNull String name) {
DSLContext dsl = getDslContext(ctx);
EmbankmentDao dao = new EmbankmentDao(dsl);
dao.deleteEmbankment(name, office, deleteMethod.getRule());
ctx.status(HttpServletResponse.SC_NO_CONTENT).json(name + " Deleted");
StatusResponse re = new StatusResponse(office, "Embankment successfully deleted from CWMS", name);
ctx.status(HttpServletResponse.SC_OK).json(re);
}
}
}
13 changes: 9 additions & 4 deletions cwms-data-api/src/main/java/cwms/cda/api/LevelsController.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import cwms.cda.api.enums.UnitSystem;
import cwms.cda.data.dao.LocationLevelsDao;
import cwms.cda.data.dao.LocationLevelsDaoImpl;
import cwms.cda.data.dto.StatusResponse;
import cwms.cda.data.dto.locationlevel.ConstantLocationLevel;
import cwms.cda.data.dto.locationlevel.LocationLevel;
import cwms.cda.data.dto.locationlevel.LocationLevels;
Expand Down Expand Up @@ -119,7 +120,8 @@ public void create(@NotNull Context ctx) {
DSLContext dsl = getDslContext(ctx);
LocationLevelsDao levelsDao = getLevelsDao(dsl);
levelsDao.storeLocationLevel(level);
ctx.status(HttpServletResponse.SC_CREATED).json("Created Location Level");
StatusResponse re = new StatusResponse(level.getOfficeId(),"Created Location Level", level.getLocationLevelId());
ctx.status(HttpServletResponse.SC_CREATED).json(re);
} catch (IOException e) {
throw new IllegalArgumentException("Unable to parse the request body", e);
}
Expand Down Expand Up @@ -185,7 +187,8 @@ public void delete(@NotNull Context ctx, @NotNull String levelId) {
? DateUtils.parseUserDate(dateString, timezone) : null;
LocationLevelsDao levelsDao = getLevelsDao(dsl);
levelsDao.deleteLocationLevel(levelId, unmarshalledDateTime, office, cascadeDelete);
ctx.status(HttpServletResponse.SC_OK).json(levelId + " Deleted");
StatusResponse re = new StatusResponse(office,"CWMS Location Level Deleted", levelId);
ctx.status(HttpServletResponse.SC_OK).json(re);
}
}

Expand Down Expand Up @@ -411,7 +414,8 @@ public void update(@NotNull Context ctx, @NotNull String oldLevelId) {
if (!oldLevelId.equals(newLevelId)) {
//if name changed then delete location with old name
levelsDao.renameLocationLevel(oldLevelId, newLevelId, officeId);
ctx.status(HttpServletResponse.SC_OK).json("Renamed Location Level");
StatusResponse re = new StatusResponse(officeId,"Renamed Location Level", newLevelId);
ctx.status(HttpServletResponse.SC_OK).json(re);
} else {
String dateString = queryParamAsClass(ctx,
new String[]{EFFECTIVE_DATE, DATE}, String.class, null, metrics,
Expand All @@ -432,7 +436,8 @@ public void update(@NotNull Context ctx, @NotNull String oldLevelId) {
levelFromBody, unmarshalledDateTime);

levelsDao.storeLocationLevel(updatedLocationLevel);
ctx.status(HttpServletResponse.SC_OK).json("Updated Location Level");
StatusResponse re = new StatusResponse(officeId,"Updated Location Level", newLevelId);
ctx.status(HttpServletResponse.SC_OK).json(re);
}
} catch (JsonProcessingException ex) {
throw new FormattingException("Failed to format location level update request", ex);
Expand Down
14 changes: 10 additions & 4 deletions cwms-data-api/src/main/java/cwms/cda/api/LocationController.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
import cwms.cda.data.dao.LocationsDao;
import cwms.cda.data.dao.LocationsDaoImpl;
import cwms.cda.data.dto.Location;
import cwms.cda.data.dto.StatusResponse;
import cwms.cda.formatters.ContentType;
import cwms.cda.formatters.Formats;
import cwms.cda.formatters.UnsupportedFormatException;
Expand Down Expand Up @@ -306,7 +307,8 @@ public void create(@NotNull Context ctx) {
Location locationFromBody = Formats.parseContent(contentType, ctx.body(), Location.class);
boolean failIfExists = ctx.queryParamAsClass(FAIL_IF_EXISTS, Boolean.class).getOrDefault(true);
locationsDao.storeLocation(locationFromBody, failIfExists);
ctx.status(HttpServletResponse.SC_CREATED).json("Created Location");
StatusResponse re = new StatusResponse(locationFromBody.getOfficeId(),"Created Location", locationFromBody.getName());
ctx.status(HttpServletResponse.SC_CREATED).json(re);
} catch (IOException ex) {
CdaError re = new CdaError("failed to process request");
logger.log(Level.SEVERE, re.toString(), ex);
Expand Down Expand Up @@ -351,10 +353,12 @@ public void update(@NotNull Context ctx, @NotNull String locationId) {
if (!updatedLocation.getName().equalsIgnoreCase(existingLocation.getName())) {
//if name changed then delete location with old name
locationsDao.renameLocation(locationId, updatedLocation);
ctx.status(HttpServletResponse.SC_OK).json("Updated and renamed Location");
ctx.status(HttpServletResponse.SC_OK).json(new StatusResponse(updatedLocation.getOfficeId(),
"Updated and renamed Location", updatedLocation.getName()));
} else {
locationsDao.storeLocation(updatedLocation, false);
ctx.status(HttpServletResponse.SC_OK).json("Updated Location");
ctx.status(HttpServletResponse.SC_OK).json(new StatusResponse(updatedLocation.getOfficeId(),
"Updated Location", updatedLocation.getName()));
}
} catch (NotFoundException e) {
CdaError re = new CdaError("Not found.");
Expand Down Expand Up @@ -386,6 +390,7 @@ public void update(@NotNull Context ctx, @NotNull String locationId) {
path = "/locations",
tags = {"Locations"},
responses = {
@OpenApiResponse(status = STATUS_200, description = "Location successfully deleted from CWMS."),
@OpenApiResponse(status = STATUS_404, description = "Based on the combination of "
+ "inputs provided the location was not found.")
}
Expand All @@ -400,7 +405,8 @@ public void delete(@NotNull Context ctx, @NotNull String locationId) {
LocationsDao locationsDao = getLocationsDao(dsl);
boolean cascadeDelete = ctx.queryParamAsClass(CASCADE_DELETE, Boolean.class).getOrDefault(false);
locationsDao.deleteLocation(locationId, office, cascadeDelete);
ctx.status(HttpServletResponse.SC_OK).json(locationId + " Deleted");
StatusResponse re = new StatusResponse(office,"Deleted CWMS Location", locationId);
ctx.status(HttpServletResponse.SC_OK).json(re);
} catch (DataAccessException ex) {
SQLException cause = ex.getCause(SQLException.class);
if (cause != null && cause.getErrorCode() == 20031) {
Expand Down
16 changes: 11 additions & 5 deletions cwms-data-api/src/main/java/cwms/cda/api/LookupTypeController.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import com.codahale.metrics.Timer;
import cwms.cda.data.dao.LookupTypeDao;
import cwms.cda.data.dto.LookupType;
import cwms.cda.data.dto.StatusResponse;
import cwms.cda.formatters.ContentType;
import cwms.cda.formatters.Formats;
import io.javalin.apibuilder.CrudHandler;
Expand Down Expand Up @@ -138,7 +139,9 @@ public void create(Context ctx) {
DSLContext dsl = getDslContext(ctx);
LookupTypeDao dao = new LookupTypeDao(dsl);
dao.storeLookupType(category, prefix, lookupType);
ctx.status(HttpServletResponse.SC_CREATED).json("Created Lookup Type");
StatusResponse re = new StatusResponse(lookupType.getOfficeId(), "Lookup Type successfully stored to CWMS.",
lookupType.getDisplayValue());
ctx.status(HttpServletResponse.SC_CREATED).json(re);
}
}

Expand All @@ -156,7 +159,7 @@ public void create(Context ctx) {
method = HttpMethod.PATCH,
tags = {TAG},
responses = {
@OpenApiResponse(status = STATUS_204, description = "Lookup Type successfully stored to CWMS.")
@OpenApiResponse(status = STATUS_200, description = "Updated Lookup Type")
}
)
@Override
Expand All @@ -170,7 +173,9 @@ public void update(Context ctx, String name) {
DSLContext dsl = getDslContext(ctx);
LookupTypeDao dao = new LookupTypeDao(dsl);
dao.updateLookupType(category, prefix, lookupType);
ctx.status(HttpServletResponse.SC_OK).json("Updated Lookup Type");
StatusResponse re = new StatusResponse(lookupType.getOfficeId(), "Updated Lookup Type",
lookupType.getDisplayValue());
ctx.status(HttpServletResponse.SC_OK).json(re);
}
}

Expand All @@ -184,7 +189,7 @@ public void update(Context ctx, String name) {
method = HttpMethod.DELETE,
tags = {TAG},
responses = {
@OpenApiResponse(status = STATUS_204, description = "Lookup Type successfully deleted from CWMS."),
@OpenApiResponse(status = STATUS_200, description = "Lookup Type successfully deleted from CWMS."),
@OpenApiResponse(status = STATUS_404, description = "Based on the combination of inputs provided the lookup type was not found.")
}
)
Expand All @@ -197,7 +202,8 @@ public void delete(Context ctx, @NotNull String displayValue) {
DSLContext dsl = getDslContext(ctx);
LookupTypeDao dao = new LookupTypeDao(dsl);
dao.deleteLookupType(category, prefix, officeId, displayValue);
ctx.status(HttpServletResponse.SC_NO_CONTENT).json(displayValue + " Deleted");
StatusResponse re = new StatusResponse(officeId, "Lookup Type successfully deleted from CWMS.", displayValue);
ctx.status(HttpServletResponse.SC_OK).json(re);
}
}

Expand Down
20 changes: 10 additions & 10 deletions cwms-data-api/src/main/java/cwms/cda/api/MeasurementController.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,16 @@
import static cwms.cda.api.Controllers.OFFICE;
import static cwms.cda.api.Controllers.OFFICE_MASK;
import static cwms.cda.api.Controllers.QUALITY;
import static cwms.cda.api.Controllers.STATUS_200;
import static cwms.cda.api.Controllers.STATUS_404;
import static cwms.cda.api.Controllers.TIMEZONE;
import static cwms.cda.api.Controllers.UNIT_SYSTEM;
import static cwms.cda.api.Controllers.queryParamAsDouble;
import static cwms.cda.api.Controllers.queryParamAsInstant;
import static cwms.cda.api.Controllers.requiredParam;
import cwms.cda.api.enums.UnitSystem;
import cwms.cda.data.dao.MeasurementDao;
import cwms.cda.data.dto.StatusResponse;
import cwms.cda.data.dto.measurement.Measurement;
import cwms.cda.formatters.ContentType;
import cwms.cda.formatters.Formats;
Expand Down Expand Up @@ -188,7 +191,7 @@ public void getOne(@NotNull Context ctx, @NotNull String locationId) {
method = HttpMethod.POST,
tags = {TAG},
responses = {
@OpenApiResponse(status = "204", description = "Measurement(s) successfully stored.")
@OpenApiResponse(status = "201", description = "Measurement(s) successfully stored.")
}
)
@Override
Expand All @@ -202,12 +205,8 @@ public void create(Context ctx) {
DSLContext dsl = getDslContext(ctx);
MeasurementDao dao = new MeasurementDao(dsl);
dao.storeMeasurements(measurements, failIfExists);
String statusMsg = "Created Measurement";
if(measurements.size() > 1)
{
statusMsg += "s";
}
ctx.status(HttpServletResponse.SC_CREATED).json(statusMsg);
StatusResponse re = new StatusResponse(measurements.get(0).getOfficeId(), "Measurement(s) successfully stored.");
ctx.status(HttpServletResponse.SC_CREATED).json(re);
}
}

Expand Down Expand Up @@ -245,8 +244,8 @@ public void update(@NotNull Context ctx, @NotNull String locationId) {
method = HttpMethod.DELETE,
tags = {TAG},
responses = {
@OpenApiResponse(status = "204", description = "Measurement successfully deleted."),
@OpenApiResponse(status = "404", description = "Measurement not found.")
@OpenApiResponse(status = STATUS_200, description = "Measurement successfully deleted."),
@OpenApiResponse(status = STATUS_404, description = "Measurement not found.")
}
)
@Override
Expand All @@ -260,7 +259,8 @@ public void delete(@NotNull Context ctx, @NotNull String locationId) {
DSLContext dsl = getDslContext(ctx);
MeasurementDao dao = new MeasurementDao(dsl);
dao.deleteMeasurements(officeId, locationId, minDate, maxDate,minNum, maxNum);
ctx.status(HttpServletResponse.SC_NO_CONTENT).json( "Measurements for " + locationId + " Deleted");
StatusResponse re = new StatusResponse(officeId, "Measurement successfully deleted for specified location-id.", locationId);
ctx.status(HttpServletResponse.SC_OK).json( re);
}
}

Expand Down
Loading
Loading