diff --git a/cwms-data-api/src/main/java/cwms/cda/api/LevelsController.java b/cwms-data-api/src/main/java/cwms/cda/api/LevelsController.java index 9eeaf6e5d..06ab6a8e1 100644 --- a/cwms-data-api/src/main/java/cwms/cda/api/LevelsController.java +++ b/cwms-data-api/src/main/java/cwms/cda/api/LevelsController.java @@ -137,18 +137,11 @@ public void create(@NotNull Context ctx) { String formatHeader = reqContentType != null ? reqContentType : Formats.JSONV2; ContentType contentType = Formats.parseHeader(formatHeader); LocationLevel level = Formats.parseContent(contentType, ctx.body(), LocationLevel.class); - ZonedDateTime unmarshalledDateTime = level.getLevelDate(); //getUnmarshalledDateTime - - ZoneId timezoneId = unmarshalledDateTime.getZone(); - if (timezoneId == null) { - timezoneId = ZoneId.systemDefault(); - } - level = new LocationLevel.Builder(level).withLevelDate(unmarshalledDateTime).build(); level.validate(); DSLContext dsl = getDslContext(ctx); LocationLevelsDao levelsDao = getLevelsDao(dsl); - levelsDao.storeLocationLevel(level, timezoneId); + levelsDao.storeLocationLevel(level); ctx.status(HttpServletResponse.SC_OK).json("Created Location Level"); } } @@ -446,7 +439,7 @@ public void update(@NotNull Context ctx, @NotNull String oldLevelId) { levelFromBody); updatedLocationLevel = new LocationLevel.Builder(updatedLocationLevel) .withLevelDate(unmarshalledDateTime).build(); - levelsDao.storeLocationLevel(updatedLocationLevel, unmarshalledDateTime.getZone()); + levelsDao.storeLocationLevel(updatedLocationLevel); ctx.status(HttpServletResponse.SC_OK).json("Updated Location Level"); } } catch (JsonProcessingException ex) { diff --git a/cwms-data-api/src/main/java/cwms/cda/api/ParametersController.java b/cwms-data-api/src/main/java/cwms/cda/api/ParametersController.java index 35b3d1fe7..66520ca79 100644 --- a/cwms-data-api/src/main/java/cwms/cda/api/ParametersController.java +++ b/cwms-data-api/src/main/java/cwms/cda/api/ParametersController.java @@ -24,6 +24,7 @@ import io.javalin.apibuilder.CrudHandler; import io.javalin.http.Context; import io.javalin.plugin.openapi.annotations.OpenApi; +import io.javalin.plugin.openapi.annotations.OpenApiContent; import io.javalin.plugin.openapi.annotations.OpenApiParam; import io.javalin.plugin.openapi.annotations.OpenApiResponse; @@ -78,7 +79,10 @@ public void delete(Context ctx, String id) { + " used."), }, responses = { - @OpenApiResponse(status = STATUS_200) + @OpenApiResponse(status = STATUS_200, content = { + @OpenApiContent(isArray = true, from = Parameter.class, type = Formats.JSONV2), + @OpenApiContent(isArray = true, from = Parameter.class, type = Formats.JSON) + }), }, tags = {"Parameters"} ) diff --git a/cwms-data-api/src/main/java/cwms/cda/api/TimeZoneController.java b/cwms-data-api/src/main/java/cwms/cda/api/TimeZoneController.java index c9fe83aee..4a5295508 100644 --- a/cwms-data-api/src/main/java/cwms/cda/api/TimeZoneController.java +++ b/cwms-data-api/src/main/java/cwms/cda/api/TimeZoneController.java @@ -25,6 +25,7 @@ import io.javalin.apibuilder.CrudHandler; import io.javalin.http.Context; import io.javalin.plugin.openapi.annotations.OpenApi; +import io.javalin.plugin.openapi.annotations.OpenApiContent; import io.javalin.plugin.openapi.annotations.OpenApiParam; import io.javalin.plugin.openapi.annotations.OpenApiResponse; @@ -74,7 +75,10 @@ public void delete(Context ctx, String id) { + "\n* `json` (default)") }, responses = { - @OpenApiResponse(status = STATUS_200), + @OpenApiResponse(status = STATUS_200, content = { + @OpenApiContent(from = TimeZoneIds.class, type = Formats.JSONV2), + @OpenApiContent(from = TimeZoneIds.class, type = Formats.JSON) + }), @OpenApiResponse(status = STATUS_501, description = "The format requested is not " + "implemented") }, diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dao/LocationLevelsDao.java b/cwms-data-api/src/main/java/cwms/cda/data/dao/LocationLevelsDao.java index d508d40e4..58ff3a8e4 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dao/LocationLevelsDao.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dao/LocationLevelsDao.java @@ -38,7 +38,7 @@ public interface LocationLevelsDao { void deleteLocationLevel(String locationLevelName, ZonedDateTime date, String officeId, Boolean cascadeDelete); - void storeLocationLevel(LocationLevel level, ZoneId zoneId); + void storeLocationLevel(LocationLevel level); void renameLocationLevel(String oldLocationLevelName, String newLocationLevelName, String officeId); diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dao/LocationLevelsDaoImpl.java b/cwms-data-api/src/main/java/cwms/cda/data/dao/LocationLevelsDaoImpl.java index 3053f6552..00f2ac6df 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dao/LocationLevelsDaoImpl.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dao/LocationLevelsDaoImpl.java @@ -40,14 +40,11 @@ import hec.data.Duration; import hec.data.Parameter; import hec.data.ParameterType; -import hec.data.Units; import hec.data.level.IAttributeParameterTypedValue; import hec.data.level.ILocationLevelRef; -import hec.data.level.IParameterTypedValue; import hec.data.level.ISpecifiedLevel; import hec.data.level.JDomLocationLevelRef; import hec.data.level.JDomSeasonalIntervalImpl; -import hec.data.level.JDomSeasonalValueImpl; import hec.data.location.LocationTemplate; import java.math.BigDecimal; import java.math.BigInteger; @@ -63,6 +60,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.Set; import java.util.TimeZone; import java.util.logging.Level; @@ -72,7 +70,6 @@ import mil.army.usace.hec.metadata.IntervalFactory; import mil.army.usace.hec.metadata.constants.NumericalConstants; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.jooq.Condition; import org.jooq.Configuration; import org.jooq.DSLContext; @@ -83,14 +80,14 @@ import org.jooq.conf.ParamType; import org.jooq.exception.DataAccessException; import org.jooq.impl.DSL; -import usace.cwms.db.dao.ifc.level.CwmsDbLevel; -import usace.cwms.db.dao.ifc.level.LocationLevelPojo; import usace.cwms.db.dao.util.OracleTypeMap; -import usace.cwms.db.dao.util.services.CwmsDbServiceLookup; import usace.cwms.db.jooq.codegen.packages.CWMS_ENV_PACKAGE; import usace.cwms.db.jooq.codegen.packages.CWMS_LEVEL_PACKAGE; import usace.cwms.db.jooq.codegen.packages.CWMS_LOC_PACKAGE; import usace.cwms.db.jooq.codegen.packages.CWMS_UTIL_PACKAGE; +import usace.cwms.db.jooq.codegen.packages.cwms_level.RETRIEVE_LOCATION_LEVEL3; +import usace.cwms.db.jooq.codegen.udt.records.SEASONAL_VALUE_T; +import usace.cwms.db.jooq.codegen.udt.records.SEASONAL_VALUE_TAB_T; import usace.cwms.db.jooq.codegen.udt.records.ZTSV_ARRAY; import usace.cwms.db.jooq.codegen.udt.records.ZTSV_TYPE; @@ -219,65 +216,55 @@ public int hashCode() { } @Override - public void storeLocationLevel(LocationLevel locationLevel, ZoneId zoneId) { - - try { - BigInteger months = locationLevel.getIntervalMonths() == null ? null : - BigInteger.valueOf(locationLevel.getIntervalMonths()); - BigInteger minutes = locationLevel.getIntervalMinutes() == null ? null : - BigInteger.valueOf(locationLevel.getIntervalMinutes()); - Date date = Date.from(locationLevel.getLevelDate().toLocalDateTime().atZone(zoneId).toInstant()); - Date intervalOrigin = locationLevel.getIntervalOrigin() == null ? null : - Date.from(locationLevel.getIntervalOrigin().toLocalDateTime().atZone(zoneId).toInstant()); - List seasonalValues = - getSeasonalValues(locationLevel); - connection(dsl, c -> { - setOffice(c, locationLevel.getOfficeId()); - CwmsDbLevel levelJooq = CwmsDbServiceLookup.buildCwmsDb(CwmsDbLevel.class, c); - levelJooq.storeLocationLevel(c, locationLevel.getLocationLevelId(), - locationLevel.getConstantValue(), locationLevel.getLevelUnitsId(), - locationLevel.getLevelComment(), date, - TimeZone.getTimeZone(zoneId), locationLevel.getAttributeValue(), - locationLevel.getAttributeUnitsId(), locationLevel.getAttributeDurationId(), - locationLevel.getAttributeComment(), intervalOrigin, months, - minutes, Boolean.parseBoolean(locationLevel.getInterpolateString()), - locationLevel.getSeasonalTimeSeriesId(), - seasonalValues, false, locationLevel.getOfficeId()); - }); - } catch (DataAccessException ex) { - throw new RuntimeException("Failed to store Location Level", ex); - } - } - - private static List getSeasonalValues(LocationLevel locationLevel) { - List retVal = Collections.emptyList(); - - if (locationLevel != null) { - retVal = buildSeasonalValues(locationLevel.getSeasonalValues()); - } - - return retVal; + public void storeLocationLevel(LocationLevel locationLevel) { + BigInteger months = locationLevel.getIntervalMonths() == null ? null : + BigInteger.valueOf(locationLevel.getIntervalMonths()); + BigInteger minutes = locationLevel.getIntervalMinutes() == null ? null : + BigInteger.valueOf(locationLevel.getIntervalMinutes()); + Timestamp date = Timestamp.from(locationLevel.getLevelDate().toInstant()); + Timestamp intervalOrigin = locationLevel.getIntervalOrigin() == null ? null : + Timestamp.from(locationLevel.getIntervalOrigin().toInstant()); + SEASONAL_VALUE_TAB_T seasonalValues = getSeasonalValues(locationLevel); + connection(dsl, c -> { + String officeId = locationLevel.getOfficeId(); + setOffice(c, officeId); + CWMS_LEVEL_PACKAGE.call_STORE_LOCATION_LEVEL3(DSL.using(c).configuration(), + locationLevel.getLocationLevelId(), locationLevel.getConstantValue(), locationLevel.getLevelUnitsId(), + locationLevel.getLevelComment(), + date, "UTC", locationLevel.getAttributeValue(), locationLevel.getAttributeUnitsId(), + locationLevel.getAttributeDurationId(), locationLevel.getAttributeComment(), intervalOrigin, months, + minutes, locationLevel.getInterpolateString(), locationLevel.getSeasonalTimeSeriesId(), seasonalValues, + "F", + officeId); + }); } - @Nullable - private static List buildSeasonalValues( - List levelSeasonalValues) { - List seasonalValues = null; - if (levelSeasonalValues != null) { - seasonalValues = levelSeasonalValues.stream() - .map(LocationLevelsDaoImpl::buildSeasonalValue) - .collect(toList()); + private static SEASONAL_VALUE_TAB_T getSeasonalValues(LocationLevel locationLevel) { + List seasonalValues = locationLevel.getSeasonalValues(); + + SEASONAL_VALUE_TAB_T pSeasonalValues = null; + if(seasonalValues != null && !seasonalValues.isEmpty()) { + pSeasonalValues = new SEASONAL_VALUE_TAB_T(); + for(SeasonalValueBean seasonalValue : seasonalValues) + { + SEASONAL_VALUE_T seasonalValueT = new SEASONAL_VALUE_T(); + seasonalValueT.setOFFSET_MINUTES(OracleTypeMap.toBigDecimal(seasonalValue.getOffsetMinutes())); + if(seasonalValue.getOffsetMonths() != null) { + seasonalValueT.setOFFSET_MONTHS(seasonalValue.getOffsetMonths().byteValue()); + } + seasonalValueT.setVALUE(OracleTypeMap.toBigDecimal(seasonalValue.getValue())); + pSeasonalValues.add(seasonalValueT); + } } - return seasonalValues; + return pSeasonalValues; } @NotNull - private List buildSeasonalValues(LocationLevelPojo fromPojo) { + private List buildSeasonalValues(RETRIEVE_LOCATION_LEVEL3 level) { List seasonalValues = Collections.emptyList(); - List fromValues - = fromPojo.getSeasonalValues(); - if (fromValues != null) { - seasonalValues = fromValues.stream() + SEASONAL_VALUE_TAB_T values = level.getP_SEASONAL_VALUES(); + if (values != null) { + seasonalValues = values.stream() .filter(Objects::nonNull) .map(LocationLevelsDaoImpl::buildSeasonalValue) .collect(toList()); @@ -285,51 +272,14 @@ private List buildSeasonalValues(LocationLevelPojo fromPojo) return seasonalValues; } - @NotNull - public static usace.cwms.db.dao.ifc.level.SeasonalValueBean buildSeasonalValue(SeasonalValueBean bean) { - usace.cwms.db.dao.ifc.level.SeasonalValueBean storeBean = - new usace.cwms.db.dao.ifc.level.SeasonalValueBean(); - storeBean.setValue(bean.getValue()); - Integer offsetMonths = bean.getOffsetMonths(); - if (offsetMonths != null) { - storeBean.setOffsetMonths(offsetMonths.byteValue()); - } - - BigInteger offsetMinutes = bean.getOffsetMinutes(); - if (offsetMinutes != null) { - storeBean.setOffsetMinutes(offsetMinutes); - } - return storeBean; - } - - public static SeasonalValueBean buildSeasonalValue(usace.cwms.db.dao.ifc.level.SeasonalValueBean fromBean) { - return new SeasonalValueBean.Builder(fromBean.getValue()) - .withOffsetMonths(fromBean.getOffsetMonths()) - .withOffsetMinutes(fromBean.getOffsetMinutes()) + public static SeasonalValueBean buildSeasonalValue(SEASONAL_VALUE_T fromBean) { + return new SeasonalValueBean.Builder(fromBean.getVALUE().doubleValue()) + .withOffsetMonths(fromBean.getOFFSET_MONTHS()) + .withOffsetMinutes(Optional.ofNullable(fromBean.getOFFSET_MINUTES()) + .map(BigDecimal::toBigInteger).orElse(null)) .build(); } - @NotNull - private static JDomSeasonalValueImpl buildSeasonalValue(String levelSiUnit, Double seasLevel, - JDomSeasonalIntervalImpl newSeasonalOffset, IParameterTypedValue prototypeLevel, String parameterUnits) { - // create new seasonal value with current record information - JDomSeasonalValueImpl newSeasonalValue = new JDomSeasonalValueImpl(); - - newSeasonalValue.setOffset(newSeasonalOffset); - newSeasonalValue.setPrototypeParameterType(prototypeLevel); - - // make sure that it is in the correct units. - if (Units.canConvertBetweenUnits(levelSiUnit, parameterUnits)) { - seasLevel = Units.convertUnits(seasLevel, levelSiUnit, parameterUnits); - // constant value - newSeasonalValue.setSiParameterUnitsValue(seasLevel); - //locationLevelImpl.setUnits(parameterUnits); // pretty sure we don't have to do this. - } else { - newSeasonalValue.setSiParameterUnitsValue(seasLevel); - } - return newSeasonalValue; - } - @Override public void deleteLocationLevel(String locationLevelName, ZonedDateTime zonedDateTime, String officeId, Boolean cascadeDelete) { @@ -375,58 +325,45 @@ public void renameLocationLevel(String oldLocationLevelName, String newLocationL } @Override - public LocationLevel retrieveLocationLevel(String locationLevelName, String units, + public LocationLevel retrieveLocationLevel(String locationLevelName, String pUnits, ZonedDateTime effectiveDate, String officeId) { - TimeZone timezone = TimeZone.getTimeZone(effectiveDate.getZone()); - Date date = Date.from(effectiveDate.toLocalDateTime().atZone(ZoneId.systemDefault()).toInstant()); - + Timestamp date = Timestamp.from(effectiveDate.toInstant()); return connectionResult(dsl, c -> { - CwmsDbLevel levelJooq = CwmsDbServiceLookup.buildCwmsDb(CwmsDbLevel.class, c); - LocationLevelPojo levelPojo = levelJooq.retrieveLocationLevel(c, - locationLevelName, units, date, timezone, null, null, - units, false, officeId); - if (units == null && levelPojo.getLevelUnitsId() == null) { - final String parameter = locationLevelName.split("\\.")[1]; - Configuration configuration = getDslContext(c, officeId).configuration(); + String units = pUnits; + Configuration configuration = getDslContext(c, officeId).configuration(); + RETRIEVE_LOCATION_LEVEL3 level = CWMS_LEVEL_PACKAGE.call_RETRIEVE_LOCATION_LEVEL3( + configuration, locationLevelName, units, date, + "UTC", null, null, units, + "F", officeId); + List seasonalValues = buildSeasonalValues(level); + if (units == null) { + String parameter = locationLevelName.split("\\.")[1]; logger.info("Getting default units for " + parameter); - final String defaultUnits = CWMS_UTIL_PACKAGE.call_GET_DEFAULT_UNITS( - configuration, parameter, UnitSystem.SI.getValue()); + String defaultUnits = CWMS_UTIL_PACKAGE.call_GET_DEFAULT_UNITS( + configuration, parameter, UnitSystem.SI.getValue()); logger.info("Default units are " + defaultUnits); - levelPojo.setLevelUnitsId(defaultUnits); + units = defaultUnits; } - return getLevelFromPojo(levelPojo, effectiveDate); - }); - } - - private LocationLevel getLevelFromPojo(LocationLevelPojo copyFromPojo, - ZonedDateTime effectiveDate) { - List seasonalValues = buildSeasonalValues(copyFromPojo); - return new LocationLevel.Builder(copyFromPojo.getLocationId(), effectiveDate) - .withAttributeComment(copyFromPojo.getAttributeComment()) - .withAttributeDurationId(copyFromPojo.getAttributeDurationId()) - .withAttributeParameterId(copyFromPojo.getAttributeParameterId()) - .withLocationLevelId(copyFromPojo.getLocationId()) - .withAttributeValue(copyFromPojo.getAttributeValue()) - .withAttributeParameterTypeId(copyFromPojo.getAttributeParameterTypeId()) - .withAttributeUnitsId(copyFromPojo.getAttributeUnitsId()) - .withDurationId(copyFromPojo.getDurationId()) - .withInterpolateString(copyFromPojo.getInterpolateString()) - .withIntervalMinutes(copyFromPojo.getIntervalMinutes()) - .withIntervalMonths(copyFromPojo.getIntervalMonths()) - .withIntervalOrigin(copyFromPojo.getIntervalOrigin(), effectiveDate) - .withLevelComment(copyFromPojo.getLevelComment()) - .withLevelUnitsId(copyFromPojo.getLevelUnitsId()) - .withOfficeId(copyFromPojo.getOfficeId()) - .withParameterId(copyFromPojo.getParameterId()) - .withParameterTypeId(copyFromPojo.getParameterTypeId()) - .withSeasonalTimeSeriesId(copyFromPojo.getSeasonalTimeSeriesId()) + return new LocationLevel.Builder(locationLevelName, effectiveDate) + .withLevelUnitsId(units) + .withAttributeUnitsId(units) + .withInterpolateString(level.getP_INTERPOLATE()) + .withIntervalMinutes(Optional.ofNullable(level.getP_INTERVAL_MINUTES()) + .map(BigInteger::intValue).orElse(null)) + .withIntervalMonths(Optional.ofNullable(level.getP_INTERVAL_MONTHS()) + .map(BigInteger::intValue).orElse(null)) + .withIntervalOrigin(level.getP_INTERVAL_ORIGIN(), effectiveDate) + .withLevelComment(level.getP_LEVEL_COMMENT()) + .withOfficeId(officeId) + .withAttributeParameterId(level.get(RETRIEVE_LOCATION_LEVEL3.P_ATTRIBUTE_ID)) + .withSeasonalTimeSeriesId(level.get(RETRIEVE_LOCATION_LEVEL3.P_TSID)) .withSeasonalValues(seasonalValues) - .withConstantValue(copyFromPojo.getSiParameterUnitsConstantValue()) - .withSpecifiedLevelId(copyFromPojo.getSpecifiedLevelId()) + .withConstantValue(Optional.ofNullable(level.getP_LEVEL_VALUE()) + .map(BigDecimal::doubleValue).orElse(null)) .build(); + }); } - // These are all the fields that we need to pull out of jOOQ record for addSeasonalValue private Collection> getAddSeasonalValueFields() { Set> retval = new LinkedHashSet<>(); diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dao/TimeSeriesGroupDao.java b/cwms-data-api/src/main/java/cwms/cda/data/dao/TimeSeriesGroupDao.java index 7497fc82e..7e89968d7 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dao/TimeSeriesGroupDao.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dao/TimeSeriesGroupDao.java @@ -239,7 +239,7 @@ private Condition buildWhereCondition(String groupOfficeId, String categoryId, S public void delete(String categoryId, String groupId, String office) { - dsl.connection(c -> + connection(dsl, c -> CWMS_TS_PACKAGE.call_DELETE_TS_GROUP( getDslContext(c,office).configuration(), categoryId, groupId, office ) @@ -247,7 +247,7 @@ public void delete(String categoryId, String groupId, String office) { } public void create(TimeSeriesGroup group, boolean failIfExists) { - dsl.connection(c-> { + connection(dsl, c-> { Configuration configuration = getDslContext(c,group.getOfficeId()).configuration(); String categoryId = group.getTimeSeriesCategory().getId(); CWMS_TS_PACKAGE.call_STORE_TS_GROUP(configuration, categoryId, @@ -273,7 +273,7 @@ private void assignTs(Configuration configuration,TimeSeriesGroup group) { } public void assignTs(TimeSeriesGroup group) { - dsl.connection(c->assignTs(getDslContext(c,group.getOfficeId()).configuration(),group)); + connection(dsl, c->assignTs(getDslContext(c,group.getOfficeId()).configuration(),group)); } private static TS_ALIAS_T convertToTsAliasType(AssignedTimeSeries assignedTimeSeries) { @@ -283,7 +283,7 @@ private static TS_ALIAS_T convertToTsAliasType(AssignedTimeSeries assignedTimeSe } public void renameTimeSeriesGroup(String oldGroupId, TimeSeriesGroup group) { - dsl.connection(c-> + connection(dsl, c-> CWMS_TS_PACKAGE.call_RENAME_TS_GROUP( getDslContext(c,group.getOfficeId()).configuration(), group.getTimeSeriesCategory().getId(), oldGroupId, group.getId(), @@ -292,7 +292,7 @@ public void renameTimeSeriesGroup(String oldGroupId, TimeSeriesGroup group) { } public void unassignAllTs(TimeSeriesGroup group) { - dsl.connection(c -> + connection(dsl, c -> CWMS_TS_PACKAGE.call_UNASSIGN_TS_GROUP( getDslContext(c,group.getOfficeId()).configuration(), group.getTimeSeriesCategory().getId(), group.getId(), diff --git a/cwms-data-api/src/test/java/cwms/cda/api/LevelsControllerTestIT.java b/cwms-data-api/src/test/java/cwms/cda/api/LevelsControllerTestIT.java index 90ff7e9c9..e0a37eddc 100644 --- a/cwms-data-api/src/test/java/cwms/cda/api/LevelsControllerTestIT.java +++ b/cwms-data-api/src/test/java/cwms/cda/api/LevelsControllerTestIT.java @@ -73,7 +73,7 @@ void test_location_level() throws Exception { CwmsDataApiSetupCallback.getDatabaseLink().connection(c -> { DSLContext dsl = dslContext(c, OFFICE); LocationLevelsDaoImpl dao = new LocationLevelsDaoImpl(dsl); - dao.storeLocationLevel(level, level.getLevelDate().getZone()); + dao.storeLocationLevel(level); }); //Read level without unit @@ -136,7 +136,7 @@ void test_level_as_timeseries() throws Exception { CwmsDataApiSetupCallback.getDatabaseLink().connection(c -> { DSLContext dsl = dslContext(c, OFFICE); LocationLevelsDaoImpl dao = new LocationLevelsDaoImpl(dsl); - dao.storeLocationLevel(level, level.getLevelDate().getZone()); + dao.storeLocationLevel(level); }); } @@ -196,7 +196,7 @@ void test_get_all_location_level() throws Exception { .build(); DSLContext dsl = dslContext(c, OFFICE); LocationLevelsDaoImpl dao = new LocationLevelsDaoImpl(dsl); - dao.storeLocationLevel(level, level.getLevelDate().getZone()); + dao.storeLocationLevel(level); }); String locId2 = "level_get_all_loc2"; @@ -211,7 +211,7 @@ void test_get_all_location_level() throws Exception { .build(); DSLContext dsl = dslContext(c, OFFICE); LocationLevelsDaoImpl dao = new LocationLevelsDaoImpl(dsl); - dao.storeLocationLevel(level, level.getLevelDate().getZone()); + dao.storeLocationLevel(level); }); String startStr = "2023-06-01T00:00:00Z"; diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dao/LocationLevelsDaoTest.java b/cwms-data-api/src/test/java/cwms/cda/data/dao/LocationLevelsDaoTest.java index ad33048a3..d06b1cadd 100644 --- a/cwms-data-api/src/test/java/cwms/cda/data/dao/LocationLevelsDaoTest.java +++ b/cwms-data-api/src/test/java/cwms/cda/data/dao/LocationLevelsDaoTest.java @@ -69,7 +69,7 @@ void testStore() throws Exception location = buildTestLocation("TEST_LOC"); locationsDao.storeLocation(location); LocationLevelsDao levelsDao = new LocationLevelsDaoImpl(getDslContext(getConnection(), OFFICE_ID)); - levelsDao.storeLocationLevel(levelToStore, ZoneId.of("UTC")); + levelsDao.storeLocationLevel(levelToStore); LocationLevel retrievedLevel = levelsDao.retrieveLocationLevel(levelToStore.getLocationLevelId(), UnitSystem.EN.getValue(), levelToStore.getLevelDate(), "LRL"); assertNotNull(retrievedLevel); assertEquals(levelToStore.getLocationLevelId(), retrievedLevel.getLocationLevelId()); @@ -91,7 +91,7 @@ void testDeleteLocationLevel() throws Exception LocationsDao locationsDao = new LocationsDaoImpl(getDslContext(getConnection(), OFFICE_ID)); Location location = buildTestLocation("TEST_LOC5"); locationsDao.storeLocation(location); - levelsDao.storeLocationLevel(levelToStore, ZoneId.of("UTC")); + levelsDao.storeLocationLevel(levelToStore); LocationLevel retrievedLevel = levelsDao.retrieveLocationLevel(levelToStore.getLocationLevelId(), UnitSystem.EN.getValue(), levelToStore.getLevelDate(), OFFICE_ID); assertNotNull(retrievedLevel); levelsDao.deleteLocationLevel(levelToStore.getLocationLevelId(), levelToStore.getLevelDate(), OFFICE_ID, true); @@ -109,7 +109,7 @@ void testUpdate() throws Exception Location location = buildTestLocation("TEST_LOC6"); try { locationsDao.storeLocation(location); - levelsDao.storeLocationLevel(levelToStore, ZoneId.of("UTC")); + levelsDao.storeLocationLevel(levelToStore); String body = getRenamedExampleJSON(); String format = Formats.JSON; @@ -123,7 +123,7 @@ void testUpdate() throws Exception { levelsDao.renameLocationLevel(levelToStore.getLocationLevelId(), updatedLocationLevel.getLocationLevelId(), OFFICE_ID); } else { - levelsDao.storeLocationLevel(updatedLocationLevel, updatedLocationLevel.getLevelDate().getZone()); + levelsDao.storeLocationLevel(updatedLocationLevel); } LocationLevel retrievedLevel = levelsDao.retrieveLocationLevel(updatedLocationLevel.getLocationLevelId(), UnitSystem.EN.getValue(), updatedLocationLevel.getLevelDate(), OFFICE_ID); assertNotNull(retrievedLevel); @@ -136,61 +136,6 @@ void testUpdate() throws Exception } } - - @Test - void testIfcToDto(){ - usace.cwms.db.dao.ifc.level.SeasonalValueBean ifcBean = - new usace.cwms.db.dao.ifc.level.SeasonalValueBean(); - double value = 23.0; - ifcBean.setValue(value); - - // just value - SeasonalValueBean dtoBean = LocationLevelsDaoImpl.buildSeasonalValue(ifcBean); - assertEquals(value, dtoBean.getValue()); - assertNull(dtoBean.getOffsetMonths()); - assertNull(dtoBean.getOffsetMinutes()); - - // just minutes - ifcBean.setOffsetMinutes(BigInteger.valueOf(22)); - dtoBean = LocationLevelsDaoImpl.buildSeasonalValue(ifcBean); - assertNull(dtoBean.getOffsetMonths()); - assertEquals(22, dtoBean.getOffsetMinutes().intValue()); - - - // just months - ifcBean.setOffsetMinutes(null); - ifcBean.setOffsetMonths(Integer.valueOf(7).byteValue()); - dtoBean = LocationLevelsDaoImpl.buildSeasonalValue(ifcBean); - assertNull(dtoBean.getOffsetMinutes()); - assertEquals(7, dtoBean.getOffsetMonths()); - } - - @Test - void testDtoToIfc() { - // Now go the other way - SeasonalValueBean.Builder builder = new SeasonalValueBean.Builder(23.0); - - // just value - usace.cwms.db.dao.ifc.level.SeasonalValueBean ifcBean = LocationLevelsDaoImpl.buildSeasonalValue(builder.build()); - assertEquals(23.0, ifcBean.getValue()); - assertNull(ifcBean.getOffsetMonths()); - assertNull(ifcBean.getOffsetMinutes()); - - // just minutes - builder.withOffsetMinutes(BigInteger.valueOf(22)); - ifcBean = LocationLevelsDaoImpl.buildSeasonalValue(builder.build()); - assertEquals(23.0, ifcBean.getValue()); - assertNull(ifcBean.getOffsetMonths()); - assertEquals(22, ifcBean.getOffsetMinutes().intValue()); - - // just months - builder.withOffsetMinutes(null).withOffsetMonths(Integer.valueOf(7).byteValue()); - ifcBean = LocationLevelsDaoImpl.buildSeasonalValue(builder.build()); - assertEquals(23.0, ifcBean.getValue()); - assertNull(ifcBean.getOffsetMinutes()); - assertEquals(7, ifcBean.getOffsetMonths().intValue()); - } - private LocationLevel deserializeLocationLevel(String body, String format, String office) throws IOException { ObjectMapper om = getObjectMapperForFormat(format); diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dao/location/kind/OutletDaoRatingIT.java b/cwms-data-api/src/test/java/cwms/cda/data/dao/location/kind/OutletDaoRatingIT.java new file mode 100644 index 000000000..e0edd83ac --- /dev/null +++ b/cwms-data-api/src/test/java/cwms/cda/data/dao/location/kind/OutletDaoRatingIT.java @@ -0,0 +1,154 @@ +/* + * + * MIT License + * + * Copyright (c) 2024 Hydrologic Engineering Center + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE + * SOFTWARE. + */ + +package cwms.cda.data.dao.location.kind; + +import cwms.cda.data.dao.DeleteRule; +import cwms.cda.data.dao.LocationGroupDao; +import cwms.cda.data.dto.CwmsId; +import cwms.cda.data.dto.Location; +import cwms.cda.data.dto.LocationGroup; +import cwms.cda.data.dto.location.kind.Outlet; +import fixtures.CwmsDataApiSetupCallback; +import mil.army.usace.hec.test.database.CwmsDatabaseContainer; +import org.jooq.DSLContext; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import java.sql.SQLException; +import java.util.List; + +import static cwms.cda.data.dao.DaoTest.getDslContext; +import static org.junit.jupiter.api.Assertions.*; + +@Tag("integration") +class OutletDaoRatingIT extends ProjectStructureIT { + private static final String lowFlowCurveId = "opening-low flow,elev;flow"; + private static final String spillwayCurveId = "elev;flow curve"; + private static final String OUTLET_KIND = "OUTLET"; + private static final CwmsId PROJECT_LOW_FLOW_RATING_GROUP = new CwmsId.Builder() + .withName("Rating-" + PROJECT_1_ID.getName() + "-LowFlow").withOfficeId(PROJECT_1_ID.getOfficeId()).build(); + private static final CwmsId PROJECT_SPILLWAY_RATING_GROUP = new CwmsId.Builder() + .withName("Rating-" + PROJECT_1_ID.getName() + "-Spillway") + .withOfficeId(PROJECT_1_ID.getOfficeId()).build(); + private static final Location PROJECT_LOW_FLOW_LOC + = buildProjectStructureLocation(PROJECT_1_ID.getName() + "-LF1", OUTLET_KIND); + private static final Location PROJECT_SPILLWAY_LOC + = buildProjectStructureLocation(PROJECT_1_ID.getName() + "-LF2", OUTLET_KIND); + private static final Outlet PROJECT_LOW_FLOW_OUTLET = buildTestOutlet(PROJECT_LOW_FLOW_LOC, + PROJECT_LOC, PROJECT_LOW_FLOW_RATING_GROUP); + private static final Outlet PROJECT_SPILLWAY_OUTLET = buildTestOutlet(PROJECT_SPILLWAY_LOC, + PROJECT_LOC, PROJECT_SPILLWAY_RATING_GROUP); + + @BeforeAll + static void setup() throws Exception { + setupProject(); + } + + @AfterAll + static void cleanup() throws Exception { + tearDownProject(); + } + + @Test + void test_uncontrolled_outlet() throws SQLException { + CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); + databaseLink.connection(c -> { + DSLContext context = getDslContext(c, OFFICE_ID); + OutletDao outletDao = new OutletDao(context); + outletDao.storeOutlet(PROJECT_SPILLWAY_OUTLET, false); + LocationGroupDao locationGroupDao = new LocationGroupDao(context); + List groups = locationGroupDao.getLocationGroups(); + assertNotNull(groups); + LocationGroup group = retrieveFromGroup(groups, PROJECT_SPILLWAY_RATING_GROUP); + assertNotNull(group); + LocationGroup modifiedGroup = new LocationGroup(group.getLocationCategory(), group.getOfficeId(), + group.getId(), group.getDescription(), spillwayCurveId, group.getSharedRefLocationId(), + group.getLocGroupAttribute()); + LocationGroup newGroup = new LocationGroup(modifiedGroup, group.getAssignedLocations()); + locationGroupDao.unassignAllLocs(group); + locationGroupDao.assignLocs(newGroup); + Outlet retrievedOutlet = outletDao.retrieveOutlet(PROJECT_SPILLWAY_LOC.getOfficeId(), + PROJECT_SPILLWAY_LOC.getName()); + assertNotNull(retrievedOutlet); + assertEquals(retrievedOutlet.getRatingGroupId().getName(), PROJECT_SPILLWAY_RATING_GROUP.getName()); + assertEquals(retrievedOutlet.getRatingGroupId().getOfficeId(), PROJECT_SPILLWAY_RATING_GROUP.getOfficeId()); + outletDao.deleteOutlet(PROJECT_SPILLWAY_LOC.getOfficeId(), PROJECT_SPILLWAY_LOC.getName(), DeleteRule.DELETE_ALL); + locationGroupDao.delete(newGroup.getLocationCategory().getId(), newGroup.getId(), + true, newGroup.getOfficeId()); + }, CwmsDataApiSetupCallback.getWebUser()); + } + + @Test + void test_controlled_outlet() throws SQLException { + CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); + databaseLink.connection(c -> { + DSLContext context = getDslContext(c, OFFICE_ID); + OutletDao outletDao = new OutletDao(context); + outletDao.storeOutlet(PROJECT_LOW_FLOW_OUTLET, false); + LocationGroupDao locationGroupDao = new LocationGroupDao(context); + List groups = locationGroupDao.getLocationGroups(); + assertNotNull(groups); + LocationGroup group = retrieveFromGroup(groups, PROJECT_LOW_FLOW_RATING_GROUP); + assertNotNull(group); + LocationGroup modifiedGroup = new LocationGroup(group.getLocationCategory(), group.getOfficeId(), + group.getId(), group.getDescription(), lowFlowCurveId, group.getSharedRefLocationId(), + group.getLocGroupAttribute()); + LocationGroup newGroup = new LocationGroup(modifiedGroup, group.getAssignedLocations()); + locationGroupDao.unassignAllLocs(group); + locationGroupDao.assignLocs(newGroup); + Outlet retrievedOutlet = outletDao.retrieveOutlet(PROJECT_LOW_FLOW_LOC.getOfficeId(), + PROJECT_LOW_FLOW_LOC.getName()); + assertNotNull(retrievedOutlet); + assertEquals(retrievedOutlet.getRatingGroupId().getName(), PROJECT_LOW_FLOW_RATING_GROUP.getName()); + assertEquals(retrievedOutlet.getRatingGroupId().getOfficeId(), PROJECT_LOW_FLOW_RATING_GROUP.getOfficeId()); + outletDao.deleteOutlet(PROJECT_LOW_FLOW_LOC.getOfficeId(), PROJECT_LOW_FLOW_LOC.getName(), DeleteRule.DELETE_ALL); + locationGroupDao.delete(newGroup.getLocationCategory().getId(), newGroup.getId(), + true, newGroup.getOfficeId()); + }, CwmsDataApiSetupCallback.getWebUser()); + } + + private static LocationGroup retrieveFromGroup(List groups, CwmsId targetGroup) { + for (LocationGroup group : groups) { + if (group.getId().equals(targetGroup.getName()) + && group.getOfficeId().equals(targetGroup.getOfficeId())) { + return group; + } + } + return null; + } + + private static Outlet buildTestOutlet(Location outletLoc, Location projectLoc, CwmsId ratingId) { + return new Outlet.Builder() + .withLocation(outletLoc) + .withProjectId(new CwmsId.Builder().withName(projectLoc.getName()) + .withOfficeId(projectLoc.getOfficeId()).build()) + .withRatingGroupId(ratingId) + .build(); + } +}