Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions cwms-data-api/src/main/java/cwms/cda/api/Controllers.java
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ public final class Controllers {
public static final String TEMPLATE_ID_MASK = "template-id-mask";
public static final String STORE_TEMPLATE = "store-template";
public static final String REPLACE_BASE_CURVE = "replace-base-curve";
public static final String EFFECTIVE_DATE_EXACT = "use-exact-effective-date";

public static final String TIMESERIES_ID_REGEX = "timeseries-id-regex";
public static final String TIMESERIES_ID = "timeseries-id";
Expand Down
14 changes: 11 additions & 3 deletions cwms-data-api/src/main/java/cwms/cda/api/LevelsController.java
Original file line number Diff line number Diff line change
Expand Up @@ -330,8 +330,14 @@ public void getAll(@NotNull Context ctx) {
@OpenApiParam(name = OFFICE, required = true, description = "Specifies the "
+ "office of the Location Level to be returned"),
@OpenApiParam(name = EFFECTIVE_DATE, required = true, description = "Specifies "
+ "the effective date of Location Level to be returned. "
+ "the effective date of Location Level to be returned."
+ "Expected formats are `YYYY-MM-DDTHH:MM` or `YYYY-MM-DDTHH:MM:SS`"),
@OpenApiParam(name= EFFECTIVE_DATE_EXACT, required = false, description = "If true"
+ " only a level with the exact provided date will be returned. If false"
+ " The most recent level on or before this time will be returned."
+ " The default is false.",
type = Boolean.class
),
@OpenApiParam(name = TIMEZONE, description = "Specifies the time zone of "
+ "the values of the effective date field (unless otherwise "
+ "specified), as well as the time zone of any times in the response."
Expand Down Expand Up @@ -364,6 +370,8 @@ public void getOne(@NotNull Context ctx, @NotNull String levelId) {
String dateString = queryParamAsClass(ctx, new String[]{EFFECTIVE_DATE, DATE},
String.class, null, metrics, name(LevelsController.class.getName(),
GET_ONE));
boolean exactDateMatch = queryParamAsClass(ctx, new String[]{EFFECTIVE_DATE_EXACT},
Boolean.class, false, metrics, name(LevelsController.class.getName(),GET_ONE));
String timezone = ctx.queryParamAsClass(TIMEZONE, String.class)
.getOrDefault("UTC");

Expand All @@ -374,7 +382,7 @@ String.class, null, metrics, name(LevelsController.class.getName(),
LocationLevelsDao levelsDao = getLevelsDao(dsl);
//retrieveLocationLevel will throw an error if level does not exist
LocationLevel locationLevel = levelsDao.retrieveLocationLevel(levelId,
units, unmarshalledDateTime, office);
units, unmarshalledDateTime, office, exactDateMatch);
ctx.json(locationLevel);
ctx.status(HttpServletResponse.SC_OK);
}
Expand Down Expand Up @@ -431,7 +439,7 @@ public void update(@NotNull Context ctx, @NotNull String oldLevelId) {
ZoneId.systemDefault().getId());
//retrieveLocationLevel will throw an error if level does not exist
LocationLevel existingLevelLevel = levelsDao.retrieveLocationLevel(oldLevelId,
UnitSystem.EN.getValue(), unmarshalledDateTime, officeId);
UnitSystem.EN.getValue(), unmarshalledDateTime, officeId, true);
existingLevelLevel = updatedClearedFields(ctx.body(), contentType.getType(),
existingLevelLevel);
//only store (update) if level does exist
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ void deleteLocationLevel(String locationLevelName, ZonedDateTime date, String of
void renameLocationLevel(String oldLocationLevelName, String newLocationLevelName, String officeId);

LocationLevel retrieveLocationLevel(String locationLevelName, String unitSystem,
ZonedDateTime effectiveDate, String officeId);
ZonedDateTime effectiveDate, String officeId, boolean exactDateMatch);

String getLocationLevels(String format, String names, String office, String unit,
String datum, String begin,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ public void renameLocationLevel(String oldLocationLevelName, String newLocationL

@Override
public LocationLevel retrieveLocationLevel(String locationLevelName, String pUnits,
ZonedDateTime effectiveDate, String officeId) {
ZonedDateTime effectiveDate, String officeId,boolean exactDateMatch) {
Timestamp date = Timestamp.from(effectiveDate.toInstant());
String[] levelIdParts = locationLevelIdParsingPattern.split(locationLevelName);
if (levelIdParts.length <= 2) {
Expand All @@ -483,9 +483,9 @@ public LocationLevel retrieveLocationLevel(String locationLevelName, String pUni
LOCATION_LEVEL_T level = CWMS_LEVEL_PACKAGE.call_RETRIEVE_LOCATION_LEVEL__2(
configuration, locationLevelName, units, date,
"UTC", null, null,
null, "T", officeId, "VN");
null, formatBool(exactDateMatch), officeId, "VN");
if (level == null) {
throw new NotFoundException("Location level not found: " + locationLevelName);
throw new NotFoundException("Location level not found: " + officeId + "/" + locationLevelName);
}
Timestamp pEffectiveDate = level.getLEVEL_DATE();
ZonedDateTime realEffectiveDate = ZonedDateTime.ofInstant(pEffectiveDate.toInstant(), effectiveDate.getZone());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,19 +101,20 @@ void cleanup() throws Exception {
});
}

@Test
void test_location_level() throws Exception {
createLocation("level_as_single_value", true, OFFICE);
@ParameterizedTest
@ValueSource(strings = {"SPK", "SWT", "MVP"})
void test_location_level(String office) throws Exception {
createLocation("level_as_single_value", true, office);
String levelId = "level_as_single_value.Stor.Ave.1Day.Regulating";
ZonedDateTime time = ZonedDateTime.of(2023, 6, 1, 0, 0, 0, 0, ZoneId.of("America/Los_Angeles"));
LocationLevel level = new ConstantLocationLevel.Builder(levelId, time)
.withOfficeId(OFFICE)
.withOfficeId(office)
.withLevelUnitsId("ac-ft")
.withConstantValue(1.0)
.build();
levelList.add(level);
CwmsDataApiSetupCallback.getDatabaseLink().connection(c -> {
DSLContext dsl = dslContext(c, OFFICE);
DSLContext dsl = dslContext(c, office);
LocationLevelsDaoImpl dao = new LocationLevelsDaoImpl(dsl);
dao.storeLocationLevel(level);
});
Expand All @@ -123,7 +124,7 @@ void test_location_level() throws Exception {
.log().ifValidationFails(LogDetail.ALL,true)
.accept(Formats.JSONV2)
.contentType(Formats.JSONV2)
.queryParam("office", OFFICE)
.queryParam("office", office)
.queryParam(EFFECTIVE_DATE, time.toInstant().toString())
.when()
.redirects().follow(true)
Expand All @@ -143,7 +144,7 @@ void test_location_level() throws Exception {
.log().ifValidationFails(LogDetail.ALL,true)
.accept(Formats.JSONV2)
.contentType(Formats.JSONV2)
.queryParam("office", OFFICE)
.queryParam("office", office)
.queryParam(EFFECTIVE_DATE, time.toInstant().toString())
.queryParam(UNIT, "ac-ft")
.when()
Expand All @@ -156,6 +157,43 @@ void test_location_level() throws Exception {
.statusCode(is(HttpServletResponse.SC_OK))
.body("level-units-id",equalTo("ac-ft"))
.body("constant-value",equalTo(1.0F));

// test modified effective date
given()
.log().ifValidationFails(LogDetail.ALL,true)
.accept(Formats.JSONV2)
.contentType(Formats.JSONV2)
.queryParam("office", office)
.queryParam(EFFECTIVE_DATE, time.plusDays(1L).toInstant().toString())
.queryParam(UNIT, "ac-ft")
.when()
.redirects().follow(true)
.redirects().max(3)
.get("/levels/{level-id}", levelId)
.then()
.assertThat()
.log().ifValidationFails(LogDetail.ALL,true)
.statusCode(is(HttpServletResponse.SC_OK))
.body("level-units-id",equalTo("ac-ft"))
.body("constant-value",equalTo(1.0F));

// test modified effective date using exact match
given()
.log().ifValidationFails(LogDetail.ALL,true)
.accept(Formats.JSONV2)
.contentType(Formats.JSONV2)
.queryParam("office", office)
.queryParam(EFFECTIVE_DATE, time.plusDays(1L).toInstant().toString())
.queryParam(EFFECTIVE_DATE_EXACT, true)
.queryParam(UNIT, "ac-ft")
.when()
.redirects().follow(true)
.redirects().max(3)
.get("/levels/{level-id}", levelId)
.then()
.assertThat()
.log().ifValidationFails(LogDetail.ALL,true)
.statusCode(is(HttpServletResponse.SC_NOT_FOUND));
}

@Test
Expand Down Expand Up @@ -968,6 +1006,7 @@ void testStoreRetrieveVirtualLocationLevels() throws Exception {
.queryParam(Controllers.OFFICE, OFFICE)
.queryParam(UNIT, "SI")
.queryParam(EFFECTIVE_DATE, time.toInstant().toString())
.queryParam(EFFECTIVE_DATE_EXACT, true)
.when()
.redirects().follow(true)
.redirects().max(3)
Expand All @@ -984,6 +1023,7 @@ void testStoreRetrieveVirtualLocationLevels() throws Exception {
.contentType(Formats.JSONV2)
.queryParam("office", OFFICE)
.queryParam(EFFECTIVE_DATE, time.toInstant().toString())
.queryParam(EFFECTIVE_DATE_EXACT, true)
.queryParam(UNIT, "ft")
.when()
.redirects().follow(true)
Expand All @@ -1001,6 +1041,7 @@ void testStoreRetrieveVirtualLocationLevels() throws Exception {
.contentType(Formats.JSONV2)
.queryParam("office", OFFICE)
.queryParam(EFFECTIVE_DATE, time.toInstant().toString())
.queryParam(EFFECTIVE_DATE_EXACT, true)
.queryParam(UNIT, "EN")
.when()
.redirects().follow(true)
Expand All @@ -1019,6 +1060,7 @@ void testStoreRetrieveVirtualLocationLevels() throws Exception {
.contentType(Formats.JSONV2)
.queryParam("office", OFFICE)
.queryParam(EFFECTIVE_DATE, time.toInstant().toString())
.queryParam(EFFECTIVE_DATE_EXACT, true)
.queryParam(UNIT, "ft3")
.when()
.redirects().follow(true)
Expand Down Expand Up @@ -1137,6 +1179,7 @@ void testStoreRetrieveAllVirtualLocationLevels() throws Exception {
.queryParam(Controllers.OFFICE, OFFICE)
.queryParam(UNIT, "SI")
.queryParam(EFFECTIVE_DATE, time.toInstant().toString())
.queryParam(EFFECTIVE_DATE_EXACT, true)
.when()
.redirects().follow(true)
.redirects().max(3)
Expand All @@ -1154,6 +1197,7 @@ void testStoreRetrieveAllVirtualLocationLevels() throws Exception {
.queryParam(Controllers.OFFICE, OFFICE)
.queryParam(UNIT, "SI")
.queryParam(EFFECTIVE_DATE, time.toInstant().toString())
.queryParam(EFFECTIVE_DATE_EXACT, true)
.when()
.redirects().follow(true)
.redirects().max(3)
Expand All @@ -1171,6 +1215,7 @@ void testStoreRetrieveAllVirtualLocationLevels() throws Exception {
.queryParam(Controllers.OFFICE, OFFICE)
.queryParam(UNIT, "SI")
.queryParam(EFFECTIVE_DATE, time.toInstant().toString())
.queryParam(EFFECTIVE_DATE_EXACT, true)
.when()
.redirects().follow(true)
.redirects().max(3)
Expand Down Expand Up @@ -1335,6 +1380,7 @@ void testStoreRetrieveAllVirtualLocationLevelsPaged() throws Exception {
.queryParam(Controllers.OFFICE, OFFICE)
.queryParam(UNIT, "SI")
.queryParam(EFFECTIVE_DATE, time.toInstant().toString())
.queryParam(EFFECTIVE_DATE_EXACT, true)
.when()
.redirects().follow(true)
.redirects().max(3)
Expand All @@ -1352,6 +1398,7 @@ void testStoreRetrieveAllVirtualLocationLevelsPaged() throws Exception {
.queryParam(Controllers.OFFICE, OFFICE)
.queryParam(UNIT, "SI")
.queryParam(EFFECTIVE_DATE, time.toInstant().toString())
.queryParam(EFFECTIVE_DATE_EXACT, true)
.when()
.redirects().follow(true)
.redirects().max(3)
Expand All @@ -1369,6 +1416,7 @@ void testStoreRetrieveAllVirtualLocationLevelsPaged() throws Exception {
.queryParam(Controllers.OFFICE, OFFICE)
.queryParam(UNIT, "SI")
.queryParam(EFFECTIVE_DATE, time.toInstant().toString())
.queryParam(EFFECTIVE_DATE_EXACT, true)
.when()
.redirects().follow(true)
.redirects().max(3)
Expand Down Expand Up @@ -1525,6 +1573,7 @@ void testStoreDeleteVirtualLocationLevel(String deletionMethod) throws Exception
.queryParam(Controllers.OFFICE, OFFICE)
.queryParam(UNIT, "SI")
.queryParam(EFFECTIVE_DATE, time.toInstant().toString())
.queryParam(EFFECTIVE_DATE_EXACT, true)
.when()
.redirects().follow(true)
.redirects().max(3)
Expand All @@ -1542,6 +1591,7 @@ void testStoreDeleteVirtualLocationLevel(String deletionMethod) throws Exception
.contentType(Formats.JSONV2)
.queryParam("office", OFFICE)
.queryParam(EFFECTIVE_DATE, time.toInstant().toString())
.queryParam(EFFECTIVE_DATE_EXACT, true)
.queryParam(UNIT, "ft3")
.when()
.redirects().follow(true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ void testStore() throws Exception
locationsDao.storeLocation(location, false);
LocationLevelsDao levelsDao = new LocationLevelsDaoImpl(getDslContext(getConnection(), OFFICE_ID));
levelsDao.storeLocationLevel(levelToStore);
LocationLevel retrievedLevel = levelsDao.retrieveLocationLevel(levelToStore.getLocationLevelId(), UnitSystem.EN.getValue(), levelToStore.getLevelDate(), "LRL");
LocationLevel retrievedLevel = levelsDao.retrieveLocationLevel(levelToStore.getLocationLevelId(), UnitSystem.EN.getValue(), levelToStore.getLevelDate(), "LRL", true);
assertNotNull(retrievedLevel);
assertEquals(levelToStore.getLocationLevelId(), retrievedLevel.getLocationLevelId());
assertEquals(levelToStore.getLevelDate(), retrievedLevel.getLevelDate());
Expand All @@ -92,10 +92,10 @@ void testDeleteLocationLevel() throws Exception
Location location = buildTestLocation("TEST_LOC5");
locationsDao.storeLocation(location, false);
levelsDao.storeLocationLevel(levelToStore);
LocationLevel retrievedLevel = levelsDao.retrieveLocationLevel(levelToStore.getLocationLevelId(), UnitSystem.EN.getValue(), levelToStore.getLevelDate(), OFFICE_ID);
LocationLevel retrievedLevel = levelsDao.retrieveLocationLevel(levelToStore.getLocationLevelId(), UnitSystem.EN.getValue(), levelToStore.getLevelDate(), OFFICE_ID, true);
assertNotNull(retrievedLevel);
levelsDao.deleteLocationLevel(levelToStore.getLocationLevelId(), levelToStore.getLevelDate(), OFFICE_ID, true);
assertThrows(IOException.class, () -> levelsDao.retrieveLocationLevel(levelToStore.getLocationLevelId(), UnitSystem.EN.getValue(), levelToStore.getLevelDate(), OFFICE_ID));
assertThrows(IOException.class, () -> levelsDao.retrieveLocationLevel(levelToStore.getLocationLevelId(), UnitSystem.EN.getValue(), levelToStore.getLevelDate(), OFFICE_ID, true));
}

@Disabled
Expand All @@ -114,7 +114,7 @@ void testUpdate() throws Exception
String format = Formats.JSON;

SeasonalLocationLevel levelFromBody = deserializeLocationLevel(body, Formats.JSON, OFFICE_ID);
existingLocationLevel = (SeasonalLocationLevel) levelsDao.retrieveLocationLevel(levelToStore.getLocationLevelId(), UnitSystem.EN.getValue(), levelFromBody.getLevelDate(), OFFICE_ID);
existingLocationLevel = (SeasonalLocationLevel) levelsDao.retrieveLocationLevel(levelToStore.getLocationLevelId(), UnitSystem.EN.getValue(), levelFromBody.getLevelDate(), OFFICE_ID, true);
existingLocationLevel = updatedClearedFields(body, format, existingLocationLevel);
//only store (update) if level does exist
updatedLocationLevel = getUpdatedLocationLevel(existingLocationLevel, levelFromBody);
Expand All @@ -126,7 +126,7 @@ void testUpdate() throws Exception
} else {
levelsDao.storeLocationLevel(updatedLocationLevel);
}
LocationLevel retrievedLevel = levelsDao.retrieveLocationLevel(updatedLocationLevel.getLocationLevelId(), UnitSystem.EN.getValue(), updatedLocationLevel.getLevelDate(), OFFICE_ID);
LocationLevel retrievedLevel = levelsDao.retrieveLocationLevel(updatedLocationLevel.getLocationLevelId(), UnitSystem.EN.getValue(), updatedLocationLevel.getLevelDate(), OFFICE_ID, true);
assertNotNull(retrievedLevel);
}
finally {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ private void loadDefaultData(CwmsDatabaseContainer cwmsDb) throws SQLException {
user = cwmsDb.getUsername();
}
logger.atInfo().log(String.format("Running %s as %s %s", data, user, cwmsDb.getPassword()));
logger.atInfo().log("Webuser = " + webUser);
cwmsDb.executeSQL(loadResourceAsString(user_resource[1]).replace("&pduser", cwmsDb.getPdUser())
.replace("&user", cwmsDb.getUsername())
.replace("&webuser", webUser)
Expand Down
11 changes: 11 additions & 0 deletions cwms-data-api/src/test/resources/cwms/cda/data/sql/users.sql
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ begin
cwms_sec.add_user_to_group('&webuser','CWMS Users', 'SWT');
cwms_sec.add_user_to_group('&webuser','CWMS PD Users', 'SWT');
cwms_sec.add_user_to_group('&webuser','CWMS DBA Users', 'SWT');

cwms_sec.add_user_to_group('&webuser','All Users', 'MVP');

cwms_sec.add_user_to_group('&user','All Users', 'HQ');
cwms_sec.add_user_to_group('&user','CWMS Users', 'HQ');
cwms_sec.add_user_to_group('&user','CWMS PD Users', 'HQ');
Expand All @@ -49,6 +52,14 @@ begin
cwms_sec.add_user_to_group('&user','CWMS Users', 'SPK');
cwms_sec.add_user_to_group('&user','CWMS PD Users', 'SPK');
cwms_sec.add_user_to_group('&user','CWMS DBA Users', 'SPK');
cwms_sec.add_user_to_group('&user','All Users', 'SWT');
cwms_sec.add_user_to_group('&user','CWMS Users', 'SWT');
cwms_sec.add_user_to_group('&user','CWMS PD Users', 'SWT');
cwms_sec.add_user_to_group('&user','CWMS DBA Users', 'SWT');
cwms_sec.add_user_to_group('&user','All Users', 'MVP');
cwms_sec.add_user_to_group('&user','CWMS Users', 'MVP');
cwms_sec.add_user_to_group('&user','CWMS PD Users', 'MVP');
cwms_sec.add_user_to_group('&user','CWMS DBA Users', 'MVP');
execute immediate 'grant execute on cwms_upass to web_user';
/** Add a couple of districts*/
begin
Expand Down
Loading