From 0697d42acea3e931290cd374d173c769bbf991bb Mon Sep 17 00:00:00 2001 From: Adam Korynta Date: Tue, 16 Jun 2026 11:04:16 -0700 Subject: [PATCH] update level serialization to use Instant instead of ZonedDateTime this will ensure serialization to always display as UTC --- .../java/cwms/cda/api/LevelsController.java | 18 +-- .../cwms/cda/data/dao/LocationLevelsDao.java | 7 +- .../cda/data/dao/LocationLevelsDaoImpl.java | 105 +++++++++--------- .../locationlevel/ConstantLocationLevel.java | 4 +- .../data/dto/locationlevel/LocationLevel.java | 28 ++--- .../locationlevel/SeasonalLocationLevel.java | 17 ++- .../TimeSeriesLocationLevel.java | 4 +- .../locationlevel/VirtualLocationLevel.java | 4 +- .../java/cwms/cda/formatters/json/JsonV1.java | 3 + .../java/cwms/cda/formatters/json/JsonV2.java | 3 + .../adapters/FlexibleInstantDeserializer.java | 71 ++++++++++++ .../adapters/InstantJsonDeserializer.java | 25 +++++ .../java/cwms/cda/formatters/xml/XMLv1.java | 3 + .../java/cwms/cda/formatters/xml/XMLv2.java | 3 + .../cwms/cda/api/LevelControllerTest.java | 12 +- .../cwms/cda/api/LevelsControllerTestIT.java | 64 +++++------ .../java/cwms/cda/api/LockControllerIT.java | 10 +- .../cda/data/dao/LocationLevelsDaoTest.java | 9 +- .../cda/data/dao/location/kind/LockDaoIT.java | 20 ++-- .../cwms/cda/data/dto/LocationLevelTest.java | 65 +++++++---- .../java/cwms/cda/formatters/JsonV2Test.java | 2 +- 21 files changed, 304 insertions(+), 173 deletions(-) create mode 100644 cwms-data-api/src/main/java/cwms/cda/formatters/json/adapters/FlexibleInstantDeserializer.java create mode 100644 cwms-data-api/src/main/java/cwms/cda/formatters/json/adapters/InstantJsonDeserializer.java 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 f6ec6f48b8..7509689073 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 @@ -70,8 +70,8 @@ import java.io.IOException; import java.io.StringWriter; import java.nio.charset.StandardCharsets; +import java.time.Instant; import java.time.ZoneId; -import java.time.ZonedDateTime; import java.util.List; import javax.servlet.http.HttpServletResponse; import org.apache.commons.io.IOUtils; @@ -186,8 +186,8 @@ public void delete(@NotNull Context ctx, @NotNull String levelId) { .getOrDefault("UTC"); Boolean cascadeDelete = ctx.queryParamAsClass(CASCADE_DELETE, Boolean.class) .getOrDefault(false); - ZonedDateTime unmarshalledDateTime = dateString != null - ? DateUtils.parseUserDate(dateString, timezone) : null; + Instant unmarshalledDateTime = dateString != null + ? DateUtils.parseUserDate(dateString, timezone).toInstant() : null; LocationLevelsDao levelsDao = getLevelsDao(dsl); levelsDao.deleteLocationLevel(levelId, unmarshalledDateTime, office, cascadeDelete); StatusResponse re = new StatusResponse(office,"CWMS Location Level Deleted", levelId); @@ -302,12 +302,12 @@ public void getAll(@NotNull Context ctx) { int pageSize = ctx.queryParamAsClass(PAGE_SIZE, Integer.class) .getOrDefault(DEFAULT_PAGE_SIZE); - ZonedDateTime endZdt = queryParamAsZdt(ctx, END); - ZonedDateTime beginZdt = queryParamAsZdt(ctx, BEGIN); + Instant beginInstant = queryParamAsInstant(ctx, BEGIN); + Instant endInstant = queryParamAsInstant(ctx, END); LocationLevels levels; levels = levelsDao.getLocationLevels(cursor, pageSize, levelIdMask, - office, unit, datum, beginZdt, endZdt, includeAliases); + office, unit, datum, beginInstant, endInstant, includeAliases); String result = Formats.format(contentType, levels); ctx.result(result); @@ -394,7 +394,7 @@ String.class, null, metrics, name(LevelsController.class.getName(), try (final Timer.Context ignored = markAndTime(GET_ONE)) { DSLContext dsl = getDslContext(ctx); - ZonedDateTime unmarshalledDateTime = DateUtils.parseUserDate(dateString, timezone); + Instant unmarshalledDateTime = DateUtils.parseUserDate(dateString, timezone).toInstant(); LocationLevelsDao levelsDao = getLevelsDao(dsl); //retrieveLocationLevel will throw an error if level does not exist @@ -455,8 +455,8 @@ public void update(@NotNull Context ctx, @NotNull String oldLevelId) { throw new IllegalArgumentException("Cannot update location level " + "effective date if no date is specified"); } - ZonedDateTime unmarshalledDateTime = DateUtils.parseUserDate(dateString, - ZoneId.systemDefault().getId()); + Instant unmarshalledDateTime = DateUtils.parseUserDate(dateString, + ZoneId.systemDefault().getId()).toInstant(); //retrieveLocationLevel will throw an error if level does not exist LocationLevel existingLevelLevel = levelsDao.retrieveLocationLevel(oldLevelId, UnitSystem.EN.getValue(), unmarshalledDateTime, officeId, true); 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 041f8c2ac6..1848a789b3 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 @@ -31,10 +31,9 @@ import hec.data.level.ILocationLevelRef; import mil.army.usace.hec.metadata.Interval; import java.time.Instant; -import java.time.ZonedDateTime; public interface LocationLevelsDao { - void deleteLocationLevel(String locationLevelName, ZonedDateTime date, String officeId, + void deleteLocationLevel(String locationLevelName, Instant date, String officeId, Boolean cascadeDelete); void storeLocationLevel(LocationLevel level); @@ -42,7 +41,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, boolean exactDateMatch); + Instant effectiveDate, String officeId, boolean exactDateMatch); String getLocationLevels(String format, String names, String office, String unit, String datum, String begin, @@ -50,7 +49,7 @@ String getLocationLevels(String format, String names, String office, String unit LocationLevels getLocationLevels(String cursor, int pageSize, String names, String office, String unit, String datum, - ZonedDateTime beginZdt, ZonedDateTime endZdt, boolean includeAliases); + Instant beginZdt, Instant endZdt, boolean includeAliases); TimeSeries retrieveLocationLevelAsTimeSeries(ILocationLevelRef levelRef, Instant start, Instant end, Interval interval, String units); 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 96ad2d5182..19db7a0a32 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 @@ -171,8 +171,8 @@ public String getLocationLevels(String format, String names, String office, Stri @Override public LocationLevels getLocationLevels(String cursor, int pageSize, String levelIdMask, String office, @NotNull String unit, - String datum, ZonedDateTime beginZdt, - ZonedDateTime endZdt, boolean includeAliases) { + String datum, Instant beginZdt, + Instant endZdt, boolean includeAliases) { Integer total = null; int offset = 0; boolean totalSet = false; @@ -208,11 +208,11 @@ public LocationLevels getLocationLevels(String cursor, int pageSize, if (beginZdt != null) { whereCondition = - whereCondition.and(field(LOCATION_LEVEL_DATE, Timestamp.class).greaterOrEqual(Timestamp.from(beginZdt.toInstant()))); + whereCondition.and(field(LOCATION_LEVEL_DATE, Timestamp.class).greaterOrEqual(Timestamp.from(beginZdt))); } if (endZdt != null) { whereCondition = - whereCondition.and(field(LOCATION_LEVEL_DATE, Timestamp.class).lessThan(Timestamp.from(endZdt.toInstant()))); + whereCondition.and(field(LOCATION_LEVEL_DATE, Timestamp.class).lessThan(Timestamp.from(endZdt))); } Map builderMap = new LinkedHashMap<>(); @@ -335,18 +335,18 @@ public LocationLevels getLocationLevels(String cursor, int pageSize, } if (beginZdt != null) { - whereCondition = whereCondition.and((view.LEVEL_DATE.greaterOrEqual(Timestamp.from(beginZdt.toInstant()))) - .or(virtView.EFFECTIVE_DATE_UTC.greaterOrEqual(Timestamp.from(beginZdt.toInstant())))); + whereCondition = whereCondition.and((view.LEVEL_DATE.greaterOrEqual(Timestamp.from(beginZdt))) + .or(virtView.EFFECTIVE_DATE_UTC.greaterOrEqual(Timestamp.from(beginZdt)))); standardWhereCondition = standardWhereCondition.and( - (view.LEVEL_DATE.greaterOrEqual(Timestamp.from(beginZdt.toInstant()))) - .or(virtView.EFFECTIVE_DATE_UTC.greaterOrEqual(Timestamp.from(beginZdt.toInstant())))); + (view.LEVEL_DATE.greaterOrEqual(Timestamp.from(beginZdt))) + .or(virtView.EFFECTIVE_DATE_UTC.greaterOrEqual(Timestamp.from(beginZdt)))); } if (endZdt != null) { - whereCondition = whereCondition.and((view.LEVEL_DATE.lessThan(Timestamp.from(endZdt.toInstant()))) - .or(virtView.EFFECTIVE_DATE_UTC.lessThan(Timestamp.from(endZdt.toInstant())))); + whereCondition = whereCondition.and((view.LEVEL_DATE.lessThan(Timestamp.from(endZdt))) + .or(virtView.EFFECTIVE_DATE_UTC.lessThan(Timestamp.from(endZdt)))); standardWhereCondition = standardWhereCondition.and( - (view.LEVEL_DATE.lessThan(Timestamp.from(endZdt.toInstant()))) - .or(virtView.EFFECTIVE_DATE_UTC.lessThan(Timestamp.from(endZdt.toInstant())))); + (view.LEVEL_DATE.lessThan(Timestamp.from(endZdt))) + .or(virtView.EFFECTIVE_DATE_UTC.lessThan(Timestamp.from(endZdt)))); } Map builderMap = new LinkedHashMap<>(); @@ -551,7 +551,7 @@ private void storeNormalLocationLevel(LocationLevel locationLevel) { BigInteger months = null; BigInteger minutes = null; Timestamp intervalOrigin = null; - Timestamp date = Timestamp.from(locationLevel.getLevelDate().toInstant()); + Timestamp date = Timestamp.from(locationLevel.getLevelDate()); SEASONAL_VALUE_TAB_T seasonalValues = null; Number constantValue = null; String seasonalTimeSeriesId = null; @@ -563,7 +563,7 @@ private void storeNormalLocationLevel(LocationLevel locationLevel) { minutes = seasonalLocationLevel.getIntervalMinutes() == null ? null : BigInteger.valueOf(seasonalLocationLevel.getIntervalMinutes()); intervalOrigin = seasonalLocationLevel.getIntervalOrigin() == null ? null : - Timestamp.from(seasonalLocationLevel.getIntervalOrigin().toInstant()); + Timestamp.from(seasonalLocationLevel.getIntervalOrigin()); seasonalValues = getSeasonalValues(seasonalLocationLevel); } else if (locationLevel instanceof ConstantLocationLevel) { constantValue = ((ConstantLocationLevel) locationLevel).getConstantValue(); @@ -579,7 +579,6 @@ private void storeNormalLocationLevel(LocationLevel locationLevel) { final SEASONAL_VALUE_TAB_T seasonalValuesFinal = seasonalValues; final String seasonalTimeSeriesIdFinal = seasonalTimeSeriesId; final Timestamp expirationDate = Optional.ofNullable(locationLevel.getExpirationDate()) - .map(ZonedDateTime::toInstant) .map(Timestamp::from) .orElse(null); @@ -597,8 +596,8 @@ private void storeNormalLocationLevel(LocationLevel locationLevel) { } private void storeVirtualLocationLevel(VirtualLocationLevel locationLevel) { - Timestamp date = Timestamp.from(locationLevel.getLevelDate().toInstant()); - Timestamp expirationDate = Timestamp.from(locationLevel.getExpirationDate().toInstant()); + Timestamp date = Timestamp.from(locationLevel.getLevelDate()); + Timestamp expirationDate = Timestamp.from(locationLevel.getExpirationDate()); STR_TAB_TAB_T constituentTab = new STR_TAB_TAB_T(); for (VirtualLocationLevel.RatingConstituent constituent : locationLevel.getConstituents()) { constituentTab.add(new STR_TAB_T(constituent.getConstituentList())); @@ -658,12 +657,12 @@ private List buildSeasonalValues(LOCATION_LEVEL_T level) { } @Override - public void deleteLocationLevel(String locationLevelName, ZonedDateTime zonedDateTime, + public void deleteLocationLevel(String locationLevelName, Instant effectiveDate, String officeId, Boolean cascadeDelete) { try { Timestamp date; - if (zonedDateTime != null) { - date = Timestamp.from(zonedDateTime.toInstant()); + if (effectiveDate != null) { + date = Timestamp.from(effectiveDate); } else { date = null; } @@ -701,8 +700,8 @@ public void renameLocationLevel(String oldLocationLevelName, String newLocationL @Override public LocationLevel retrieveLocationLevel(String locationLevelName, String pUnits, - ZonedDateTime effectiveDate, String officeId,boolean exactDateMatch) { - Timestamp date = Timestamp.from(effectiveDate.toInstant()); + Instant effectiveDate, String officeId,boolean exactDateMatch) { + Timestamp date = Timestamp.from(effectiveDate); String[] levelIdParts = locationLevelIdParsingPattern.split(locationLevelName); if (levelIdParts.length <= 2) { throw new IllegalArgumentException("Location level name is in an invalid format, must be separated by '.'"); @@ -731,8 +730,7 @@ public LocationLevel retrieveLocationLevel(String locationLevelName, String pUni throw new NotFoundException("Location level not found: " + officeId + "/" + locationLevelName); } Timestamp pEffectiveDate = level.getLEVEL_DATE(); - ZonedDateTime realEffectiveDate = - ZonedDateTime.ofInstant(pEffectiveDate.toInstant(), effectiveDate.getZone()); + Instant realEffectiveDate = pEffectiveDate.toInstant(); List constituents = new ArrayList<>(); STR_TAB_TAB_T constituentTab = level.getCONSTITUENTS(); Double constantValue = Optional.ofNullable(level.getLEVEL_VALUE()) @@ -756,9 +754,9 @@ public LocationLevel retrieveLocationLevel(String locationLevelName, String pUni }); } - private VirtualLocationLevel buildVirtualLocationLevel(LOCATION_LEVEL_T level, String officeId, String units, ZonedDateTime effectiveDate, - STR_TAB_TAB_T constituentTab, List constituents, String locationLevelName, ZonedDateTime realEffectiveDate) { - ZonedDateTime expirationDate = ZonedDateTime.ofInstant(level.getEXPIRATION_DATE().toInstant(), effectiveDate.getZone()); + private VirtualLocationLevel buildVirtualLocationLevel(LOCATION_LEVEL_T level, String officeId, String units, Instant effectiveDate, + STR_TAB_TAB_T constituentTab, List constituents, String locationLevelName, Instant realEffectiveDate) { + Instant expirationDate = Optional.ofNullable(level.getEXPIRATION_DATE()).map(Timestamp::toInstant).orElse(null); constituentTab.forEach(constituent -> { if (constituent.size() > 3) { @@ -791,10 +789,9 @@ private VirtualLocationLevel buildVirtualLocationLevel(LOCATION_LEVEL_T level, S } private ConstantLocationLevel buildConstantLocationLevel(LOCATION_LEVEL_T level, String officeId, String units, - String locationLevelName, ZonedDateTime realEffectiveDate, Double constantValue) { - ZonedDateTime expirationDate = Optional.ofNullable(level.getEXPIRATION_DATE()) + String locationLevelName, Instant realEffectiveDate, Double constantValue) { + Instant expirationDate = Optional.ofNullable(level.getEXPIRATION_DATE()) .map(Timestamp::toInstant) - .map(i -> i.atZone(realEffectiveDate.getZone())) .orElse(null); return new ConstantLocationLevel.Builder(locationLevelName, realEffectiveDate) .withLevelUnitsId(units) @@ -809,10 +806,9 @@ private ConstantLocationLevel buildConstantLocationLevel(LOCATION_LEVEL_T level, } private SeasonalLocationLevel buildSeasonalLocationLevel(LOCATION_LEVEL_T level, String officeId, String units, - String locationLevelName, ZonedDateTime effectiveDate, ZonedDateTime realEffectiveDate, List seasonalValues) { - ZonedDateTime expirationDate = Optional.ofNullable(level.getEXPIRATION_DATE()) + String locationLevelName, Instant effectiveDate, Instant realEffectiveDate, List seasonalValues) { + Instant expirationDate = Optional.ofNullable(level.getEXPIRATION_DATE()) .map(Timestamp::toInstant) - .map(i -> i.atZone(realEffectiveDate.getZone())) .orElse(null); return new SeasonalLocationLevel.Builder(locationLevelName, realEffectiveDate) .withLevelUnitsId(units) @@ -832,10 +828,9 @@ private SeasonalLocationLevel buildSeasonalLocationLevel(LOCATION_LEVEL_T level, } private TimeSeriesLocationLevel buildTimeSeriesLocationLevel(LOCATION_LEVEL_T level, String officeId, String units, - String locationLevelName, ZonedDateTime realEffectiveDate) { - ZonedDateTime expirationDate = Optional.ofNullable(level.getEXPIRATION_DATE()) + String locationLevelName, Instant realEffectiveDate) { + Instant expirationDate = Optional.ofNullable(level.getEXPIRATION_DATE()) .map(Timestamp::toInstant) - .map(i -> i.atZone(realEffectiveDate.getZone())) .orElse(null); return new TimeSeriesLocationLevel.Builder(locationLevelName, realEffectiveDate, level.getTSID()) .withLevelUnitsId(units) @@ -873,7 +868,7 @@ private void parseLevels(Record r, Map build String virtLocLevelId = r.get(mapping.getVirtLocLevelId()); String virtOfficeId = r.get(mapping.getVirtOfficeId()); String connections = r.get(mapping.getConnections()); - ZonedDateTime expireDate = null; + Instant expireDate = null; Date levelDate = null; if (levelDateTimestamp != null) { @@ -912,7 +907,7 @@ private void parseLevels(Record r, Map build virtual = true; } if (expirationDate != null) { - expireDate = ZonedDateTime.ofInstant(expirationDate.toInstant(), ZoneId.of("UTC")); + expireDate = expirationDate.toInstant(); } JDomLocationLevelRef locationLevelRef = new JDomLocationLevelRef(officeId, locLevelId, attrId, attrStr, attrUnit); @@ -942,7 +937,8 @@ private void parseLevels(Record r, Map build Timestamp intervalOrigin = r.get(mapping.getIntervalOrigin()); if (constantLevel != null) { - ConstantLocationLevel.Builder constantBuilder = new ConstantLocationLevel.Builder(locLevelId, levelZdt); + ConstantLocationLevel.Builder constantBuilder = + new ConstantLocationLevel.Builder(locLevelId, toInstant(levelZdt)); constantBuilder.withConstantValue(constantLevel); constantBuilder = withLocationLevelRef(constantBuilder, locationLevelRef); @@ -967,7 +963,8 @@ private void parseLevels(Record r, Map build existingBuilder.withSeasonalValue(seasonalValue); builderMap.put(levelLookup, existingBuilder); } else { - SeasonalLocationLevel.Builder seasonalBuilder = new SeasonalLocationLevel.Builder(locLevelId, levelZdt); + SeasonalLocationLevel.Builder seasonalBuilder = + new SeasonalLocationLevel.Builder(locLevelId, toInstant(levelZdt)); seasonalBuilder.withSeasonalValue(seasonalValue); seasonalBuilder.withInterpolateString(interp); if (timeInterval != null) { @@ -984,13 +981,14 @@ private void parseLevels(Record r, Map build JDomSeasonalIntervalImpl offset = new JDomSeasonalIntervalImpl(); offset.setYearMonthString(calendarInterval); seasonalBuilder.withIntervalMonths(offset.getTotalMonths()); - seasonalBuilder.withIntervalOrigin(intervalOrigin, levelZdt); + seasonalBuilder.withIntervalOrigin(intervalOrigin, toInstant(levelZdt)); seasonalBuilder.withAliases(aliases); seasonalBuilder.withExpirationDate(expireDate); builderMap.put(levelLookup, seasonalBuilder); } } else if (tsId != null) { - TimeSeriesLocationLevel.Builder timeSeriesBuilder = new TimeSeriesLocationLevel.Builder(locLevelId, levelZdt, tsId); + TimeSeriesLocationLevel.Builder timeSeriesBuilder = + new TimeSeriesLocationLevel.Builder(locLevelId, toInstant(levelZdt), tsId); timeSeriesBuilder.withAttributeParameterId(attrId); timeSeriesBuilder.withAttributeUnitsId(attrUnit); timeSeriesBuilder.withLevelUnitsId(levelUnit); @@ -1006,7 +1004,7 @@ private void parseLevels(Record r, Map build if (levelDate != null) { levelZdt = ZonedDateTime.ofInstant(levelDate.toInstant(), ZoneId.of("UTC")); } - builder = new VirtualLocationLevel.Builder(locLevelId, levelZdt); + builder = new VirtualLocationLevel.Builder(locLevelId, toInstant(levelZdt)); builder = withLocationLevelRef(builder, locationLevelRef); builder.withAttributeParameterId(attrId); builder.withAttributeUnitsId(attrUnit); @@ -1041,7 +1039,7 @@ private void parseLevelsNewView(Record r, Map> T withLocationLevelRef(T builder, J return builder.withOfficeId(locationLevelRef.getOfficeId()); } + private static Instant toInstant(ZonedDateTime dateTime) { + return dateTime == null ? null : dateTime.toInstant(); + } + private SeasonalValueBean buildSeasonalValueBean(Double seasonalLevel, JDomSeasonalIntervalImpl offset) { // Avoiding JDomSeasonalValueImpl b/c it does units conversion to SI. diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/locationlevel/ConstantLocationLevel.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/locationlevel/ConstantLocationLevel.java index 50387bf11d..35914cba8d 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dto/locationlevel/ConstantLocationLevel.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/locationlevel/ConstantLocationLevel.java @@ -26,7 +26,7 @@ package cwms.cda.data.dto.locationlevel; -import java.time.ZonedDateTime; +import java.time.Instant; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @@ -78,7 +78,7 @@ public static class Builder extends LocationLevel.Builder> { String parameterTypeId; String parameterId; String levelUnitsId; - ZonedDateTime levelDate; + Instant levelDate; String levelComment; String durationId; BigDecimal attributeValue; @@ -233,13 +229,13 @@ public abstract static class Builder> { String locationId; String officeId; String interpolateString; - ZonedDateTime expirationDate; + Instant expirationDate; List aliases = new ArrayList<>(); final Map> propertyFunctionMap = new HashMap<>(); @JsonCreator protected Builder(@JsonProperty(value = "location-level-id", required = true) String name, - @JsonProperty(value = "level-date", required = true) ZonedDateTime lvlDate) { + @JsonProperty(value = "level-date", required = true) Instant lvlDate) { locationId = name; levelDate = lvlDate; } @@ -292,7 +288,7 @@ public T withParameterId(String parameterId) { return self(); } - public T withExpirationDate(ZonedDateTime expirationDate) { + public T withExpirationDate(Instant expirationDate) { this.expirationDate = expirationDate; return self(); } @@ -302,7 +298,7 @@ public T withLevelUnitsId(String levelUnitsId) { return self(); } - public T withLevelDate(ZonedDateTime levelDate) { + public T withLevelDate(Instant levelDate) { this.levelDate = levelDate; return self(); } @@ -371,7 +367,7 @@ public T withAliases(List aliases) { } public static LocationLevel getUpdatedLocationLevel(LocationLevel existingLevel, - LocationLevel updatedLevel, ZonedDateTime unmarshalledDate) { + LocationLevel updatedLevel, Instant unmarshalledDate) { String specifiedLevelId = (updatedLevel.getSpecifiedLevelId() == null ? existingLevel.getSpecifiedLevelId() : updatedLevel.getSpecifiedLevelId()); @@ -450,7 +446,7 @@ public static LocationLevel getUpdatedLocationLevel(LocationLevel existingLevel, SeasonalLocationLevel seasonalLevel = (SeasonalLocationLevel) existingLevel; SeasonalLocationLevel updatedSeasonalLevel = (SeasonalLocationLevel) updatedLevel; - ZonedDateTime intervalOrigin = (updatedSeasonalLevel.getIntervalOrigin() == null + Instant intervalOrigin = (updatedSeasonalLevel.getIntervalOrigin() == null ? seasonalLevel.getIntervalOrigin() : updatedSeasonalLevel.getIntervalOrigin()); Integer intervalMinutes = (updatedSeasonalLevel.getIntervalMinutes() == null ? seasonalLevel.getIntervalMinutes() : updatedSeasonalLevel.getIntervalMinutes()); diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/locationlevel/SeasonalLocationLevel.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/locationlevel/SeasonalLocationLevel.java index ae3a9b08f6..9005960990 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dto/locationlevel/SeasonalLocationLevel.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/locationlevel/SeasonalLocationLevel.java @@ -49,7 +49,7 @@ import hec.data.level.ISeasonalValues; import io.swagger.v3.oas.annotations.media.Schema; import java.math.BigInteger; -import java.time.ZonedDateTime; +import java.time.Instant; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -66,7 +66,7 @@ public final class SeasonalLocationLevel extends LocationLevel { @Schema(description = "The start point of provided seasonal values") @JsonFormat(shape = JsonFormat.Shape.STRING) - private final ZonedDateTime intervalOrigin; + private final Instant intervalOrigin; private final Integer intervalMonths; @@ -93,7 +93,7 @@ public List getSeasonalValues() { return seasonalValues; } - public ZonedDateTime getIntervalOrigin() { + public Instant getIntervalOrigin() { return intervalOrigin; } @@ -110,13 +110,13 @@ public Integer getIntervalMinutes() { @JsonIgnoreProperties(ignoreUnknown = true) public static final class Builder extends LocationLevel.Builder { private List seasonalValues; - private ZonedDateTime intervalOrigin; + private Instant intervalOrigin; private Integer intervalMonths; private Integer intervalMinutes; @JsonCreator public Builder(@JsonProperty(value = "location-level-id", required = true) String name, - @JsonProperty(value = "level-date", required = true) ZonedDateTime lvlDate) { + @JsonProperty(value = "level-date", required = true) Instant lvlDate) { super(name, lvlDate); } @@ -198,15 +198,14 @@ public static List buildSeasonalValues(ISeasonalValues season return retval; } - public SeasonalLocationLevel.Builder withIntervalOrigin(ZonedDateTime intervalOrigin) { + public SeasonalLocationLevel.Builder withIntervalOrigin(Instant intervalOrigin) { this.intervalOrigin = intervalOrigin; return this; } - public SeasonalLocationLevel.Builder withIntervalOrigin(Date intervalOriginDate, ZonedDateTime effectiveDate) { + public SeasonalLocationLevel.Builder withIntervalOrigin(Date intervalOriginDate, Instant effectiveDate) { if (intervalOriginDate != null && effectiveDate != null) { - return withIntervalOrigin(ZonedDateTime.ofInstant(intervalOriginDate.toInstant(), - effectiveDate.getZone())); + return withIntervalOrigin(intervalOriginDate.toInstant()); } else { this.intervalOrigin = null; return this; diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/locationlevel/TimeSeriesLocationLevel.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/locationlevel/TimeSeriesLocationLevel.java index fbcbe6fc49..9bd06a8dbe 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dto/locationlevel/TimeSeriesLocationLevel.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/locationlevel/TimeSeriesLocationLevel.java @@ -26,7 +26,7 @@ package cwms.cda.data.dto.locationlevel; -import java.time.ZonedDateTime; +import java.time.Instant; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @@ -80,7 +80,7 @@ public static final class Builder extends LocationLevel.Builder { + + @Override + public Instant deserialize(JsonParser parser, DeserializationContext context) throws IOException { + String value = parser.getValueAsString(); + + if (value == null || value.isBlank()) { + return null; + } + + value = value.trim(); + + try { + return Instant.parse(value); + } catch (DateTimeParseException ignored) { + // Try the next supported format. + } + + try { + return OffsetDateTime.parse(value).toInstant(); + } catch (DateTimeParseException ignored) { + // Try the next supported format. + } + + try { + return ZonedDateTime.parse(value).toInstant(); + } catch (DateTimeParseException ignored) { + throw context.weirdStringException( + value, + Instant.class, + "Expected an ISO-8601 instant, offset date-time, or zoned date-time" + ); + } + } +} \ No newline at end of file diff --git a/cwms-data-api/src/main/java/cwms/cda/formatters/json/adapters/InstantJsonDeserializer.java b/cwms-data-api/src/main/java/cwms/cda/formatters/json/adapters/InstantJsonDeserializer.java new file mode 100644 index 0000000000..eed62c2131 --- /dev/null +++ b/cwms-data-api/src/main/java/cwms/cda/formatters/json/adapters/InstantJsonDeserializer.java @@ -0,0 +1,25 @@ +package cwms.cda.formatters.json.adapters; + +import com.fasterxml.jackson.core.JacksonException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import cwms.cda.helpers.DateUtils; +import java.io.IOException; +import java.time.Instant; + +public class InstantJsonDeserializer extends StdDeserializer { + + public InstantJsonDeserializer() { + this(null); + } + + protected InstantJsonDeserializer(Class vc) { + super(vc); + } + + @Override + public Instant deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException { + return DateUtils.parseUserDate(p.getText(), "UTC").toInstant(); + } +} diff --git a/cwms-data-api/src/main/java/cwms/cda/formatters/xml/XMLv1.java b/cwms-data-api/src/main/java/cwms/cda/formatters/xml/XMLv1.java index 675fbb79a6..eb05ffd81e 100644 --- a/cwms-data-api/src/main/java/cwms/cda/formatters/xml/XMLv1.java +++ b/cwms-data-api/src/main/java/cwms/cda/formatters/xml/XMLv1.java @@ -13,8 +13,10 @@ import cwms.cda.formatters.Formats; import cwms.cda.formatters.FormattingException; import cwms.cda.formatters.OutputFormatter; +import cwms.cda.formatters.json.adapters.FlexibleInstantDeserializer; import cwms.cda.formatters.json.adapters.ZoneIdDeserializer; import io.javalin.http.InternalServerErrorResponse; +import java.time.Instant; import java.util.Set; import org.jetbrains.annotations.NotNull; @@ -131,6 +133,7 @@ public T parseContent(InputStream content, Class type SimpleModule module = new SimpleModule(); module.addDeserializer(ZoneId.class, new ZoneIdDeserializer()); + module.addDeserializer(Instant.class, new FlexibleInstantDeserializer()); retval.registerModule(module); return retval; } diff --git a/cwms-data-api/src/main/java/cwms/cda/formatters/xml/XMLv2.java b/cwms-data-api/src/main/java/cwms/cda/formatters/xml/XMLv2.java index 5d8716772c..6c1f414edf 100644 --- a/cwms-data-api/src/main/java/cwms/cda/formatters/xml/XMLv2.java +++ b/cwms-data-api/src/main/java/cwms/cda/formatters/xml/XMLv2.java @@ -13,8 +13,10 @@ import cwms.cda.formatters.Formats; import cwms.cda.formatters.FormattingException; import cwms.cda.formatters.OutputFormatter; +import cwms.cda.formatters.json.adapters.FlexibleInstantDeserializer; import cwms.cda.formatters.json.adapters.ZoneIdDeserializer; import io.javalin.http.InternalServerErrorResponse; +import java.time.Instant; import org.jetbrains.annotations.NotNull; import java.io.IOException; @@ -103,6 +105,7 @@ public T parseContent(InputStream content, Class type SimpleModule module = new SimpleModule(); module.addDeserializer(ZoneId.class, new ZoneIdDeserializer()); + module.addDeserializer(Instant.class, new FlexibleInstantDeserializer()); retval.registerModule(module); return retval; } diff --git a/cwms-data-api/src/test/java/cwms/cda/api/LevelControllerTest.java b/cwms-data-api/src/test/java/cwms/cda/api/LevelControllerTest.java index acdc5511fa..4c6c5e4105 100644 --- a/cwms-data-api/src/test/java/cwms/cda/api/LevelControllerTest.java +++ b/cwms-data-api/src/test/java/cwms/cda/api/LevelControllerTest.java @@ -24,7 +24,7 @@ void testDeserializeSeasonalLevelXml() throws Exception { assertEquals("LOC_TEST.Elev.Inst.0.Bottom of Inlet", level.getLocationLevelId()); assertEquals(OFFICE_ID, level.getOfficeId()); assertEquals("ft", level.getLevelUnitsId()); - assertEquals(dateTimeAdapter.unmarshal("2008-12-03T10:15:30+01:00[Z]").toInstant(), level.getLevelDate().toInstant()); + assertEquals(dateTimeAdapter.unmarshal("2008-12-03T10:15:30+01:00[Z]").toInstant(), level.getLevelDate()); assertEquals(10.0, level.getSeasonalValues().get(0).getValue()); } @@ -38,7 +38,7 @@ void testDeserializeSeasonalLevelJSON() throws Exception { assertEquals("LOC_TEST.Elev.Inst.0.Bottom of Inlet", level.getLocationLevelId()); assertEquals(OFFICE_ID, level.getOfficeId()); assertEquals("ft", level.getLevelUnitsId()); - assertEquals(dateTimeAdapter.unmarshal("2008-12-03T10:15:30+01:00[Z]"), level.getLevelDate()); + assertEquals(dateTimeAdapter.unmarshal("2008-12-03T10:15:30+01:00[Z]").toInstant(), level.getLevelDate()); assertEquals(10.0, level.getSeasonalValues().get(0).getValue()); } @@ -52,7 +52,7 @@ void testDeserializeConstantLevelXml() throws Exception { assertEquals("LOC_TEST.Elev.Inst.0.Bottom of Inlet", level.getLocationLevelId()); assertEquals(OFFICE_ID, level.getOfficeId()); assertEquals("ft", level.getLevelUnitsId()); - assertEquals(dateTimeAdapter.unmarshal("2008-12-03T10:15:30+01:00[Z]").toInstant(), level.getLevelDate().toInstant()); + assertEquals(dateTimeAdapter.unmarshal("2008-12-03T10:15:30+01:00[Z]").toInstant(), level.getLevelDate()); assertEquals(10.0, level.getConstantValue()); } @@ -66,7 +66,7 @@ void testDeserializeConstantLevelJSON() throws Exception { assertEquals("LOC_TEST.Elev.Inst.0.Bottom of Inlet", level.getLocationLevelId()); assertEquals(OFFICE_ID, level.getOfficeId()); assertEquals("ft", level.getLevelUnitsId()); - assertEquals(dateTimeAdapter.unmarshal("2008-12-03T10:15:30+01:00[Z]"), level.getLevelDate()); + assertEquals(dateTimeAdapter.unmarshal("2008-12-03T10:15:30+01:00[Z]").toInstant(), level.getLevelDate()); assertEquals(10.0, level.getConstantValue()); } @@ -82,7 +82,7 @@ void testDeserializeTimeSeriesLevelXml() throws Exception { assertEquals(OFFICE_ID, level.getOfficeId()); assertEquals("ft", level.getLevelUnitsId()); assertEquals(dateTimeAdapter.unmarshal("2008-12-03T10:15:30+01:00[Z]").toInstant(), - level.getLevelDate().toInstant()); + level.getLevelDate()); assertEquals("RYAN3.Stage.Inst.5Minutes.0.ZSTORE_TS_TEST630", level.getSeasonalTimeSeriesId()); } @@ -96,7 +96,7 @@ void testDeserializeTimeSeriesLevelJSON() throws Exception { assertEquals("LOC_TEST.Elev.Inst.0.Bottom of Inlet", level.getLocationLevelId()); assertEquals(OFFICE_ID, level.getOfficeId()); assertEquals("ft", level.getLevelUnitsId()); - assertEquals(dateTimeAdapter.unmarshal("2008-12-03T10:15:30+01:00[Z]"), level.getLevelDate()); + assertEquals(dateTimeAdapter.unmarshal("2008-12-03T10:15:30+01:00[Z]").toInstant(), level.getLevelDate()); assertEquals("RYAN3.Stage.Inst.5Minutes.0.ZSTORE_TS_TEST630", level.getSeasonalTimeSeriesId()); } } 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 15668c4ef0..9b065de5c1 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 @@ -113,7 +113,7 @@ 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) + LocationLevel level = new ConstantLocationLevel.Builder(levelId, time.toInstant()) .withOfficeId(office) .withLevelUnitsId("ac-ft") .withConstantValue(1.0) @@ -141,6 +141,7 @@ void test_location_level(String office) throws Exception { .log().ifValidationFails(LogDetail.ALL,true) .statusCode(is(HttpServletResponse.SC_OK)) .body("level-units-id", equalTo("m3")) + .body("level-date", equalTo(time.toInstant().toString())) // I think we need to create a custom matcher. // This really shouldn't use equals but due to a quirk in // RestAssured it appears to be necessary. @@ -162,6 +163,7 @@ void test_location_level(String office) throws Exception { .log().ifValidationFails(LogDetail.ALL,true) .statusCode(is(HttpServletResponse.SC_OK)) .body("level-units-id",equalTo("ac-ft")) + .body("level-date", equalTo(time.toInstant().toString())) .body("constant-value",equalTo(1.0F)); // test modified effective date @@ -208,7 +210,7 @@ void test_retrieve_effective_date() throws Exception { String levelId = "level_with_effect.Flow.Ave.1Day.Regulating"; ZonedDateTime time = ZonedDateTime.of(2023, 6, 1, 0, 0, 0, 0, ZoneId.of("America/Los_Angeles")); CwmsDataApiSetupCallback.getDatabaseLink().connection(c -> { - LocationLevel level = new ConstantLocationLevel.Builder(levelId, time) + LocationLevel level = new ConstantLocationLevel.Builder(levelId, time.toInstant()) .withOfficeId(OFFICE) .withLevelUnitsId("cms") .withConstantValue(1.0) @@ -246,7 +248,7 @@ void test_retrieve_time_window() throws Exception { String levelId = "level_get_all_loc_1.Flow.Ave.1Day.Regulating"; ZonedDateTime time = ZonedDateTime.of(2023, 6, 1, 0, 0, 0, 0, ZoneId.of("America/Los_Angeles")); CwmsDataApiSetupCallback.getDatabaseLink().connection(c -> { - LocationLevel level = new ConstantLocationLevel.Builder(levelId, time) + LocationLevel level = new ConstantLocationLevel.Builder(levelId, time.toInstant()) .withOfficeId(OFFICE) .withLevelUnitsId("cms") .withConstantValue(1.0) @@ -262,7 +264,7 @@ void test_retrieve_time_window() throws Exception { createLocation(locId2, true, OFFICE); CwmsDataApiSetupCallback.getDatabaseLink().connection(c -> { - LocationLevel level = new ConstantLocationLevel.Builder(levelId2, time) + LocationLevel level = new ConstantLocationLevel.Builder(levelId2, time.toInstant()) .withOfficeId(OFFICE) .withLevelUnitsId("ac-ft") .withConstantValue(2.0) @@ -361,7 +363,7 @@ void test_level_refs() throws Exception { createLocation(locId, true, OFFICE); CwmsDataApiSetupCallback.getDatabaseLink().connection(c -> { - LocationLevel level = new ConstantLocationLevel.Builder(levelId, time) + LocationLevel level = new ConstantLocationLevel.Builder(levelId, time.toInstant()) .withOfficeId(OFFICE) .withLevelUnitsId(unitsId) .withConstantValue(constantValue) @@ -434,13 +436,13 @@ void test_level_as_timeseries() throws Exception { int effectiveDateCount = 10; NavigableMap levels = new TreeMap<>(); for (int i = 0; i < effectiveDateCount; i++) { - LocationLevel level = new ConstantLocationLevel.Builder(levelId, time.plusDays(i)) + LocationLevel level = new ConstantLocationLevel.Builder(levelId, time.plusDays(i).toInstant()) .withOfficeId(OFFICE) .withLevelUnitsId("cfs") .withConstantValue((double) i) .build(); levelList.add(level); - levels.put(level.getLevelDate().toInstant(), level); + levels.put(level.getLevelDate(), level); CwmsDataApiSetupCallback.getDatabaseLink().connection(c -> { DSLContext dsl = dslContext(c, OFFICE); LocationLevelsDaoImpl dao = new LocationLevelsDaoImpl(dsl); @@ -541,7 +543,7 @@ void test_ts_backed_level_new_lrts_interval() throws Exception { int effectiveDateCount = 10; for (int i = 0; i < effectiveDateCount; i++) { - TimeSeriesLocationLevel level = new TimeSeriesLocationLevel.Builder(levelId, time.plusDays(i), tsId) + TimeSeriesLocationLevel level = new TimeSeriesLocationLevel.Builder(levelId, time.plusDays(i).toInstant(), tsId) .withOfficeId(OFFICE) .withLevelUnitsId("cfs") .withInterpolateString("T") @@ -619,7 +621,7 @@ void test_get_all_location_level() throws Exception { final ZonedDateTime time = ZonedDateTime.of(2023, 6, 1, 0, 0, 0, 0, ZoneId.of("America" + "/Los_Angeles")); CwmsDataApiSetupCallback.getDatabaseLink().connection(c -> { - LocationLevel level = new ConstantLocationLevel.Builder(levelId, time) + LocationLevel level = new ConstantLocationLevel.Builder(levelId, time.toInstant()) .withOfficeId(OFFICE) .withLevelUnitsId("ac-ft") .withConstantValue(1.0) @@ -635,7 +637,7 @@ void test_get_all_location_level() throws Exception { createLocation(locId2, true, OFFICE); CwmsDataApiSetupCallback.getDatabaseLink().connection(c -> { - LocationLevel level = new ConstantLocationLevel.Builder(levelId2, time) + LocationLevel level = new ConstantLocationLevel.Builder(levelId2, time.toInstant()) .withOfficeId(OFFICE) .withLevelUnitsId("ac-ft") .withConstantValue(2.0) @@ -780,7 +782,7 @@ void test_get_one_units() 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) + LocationLevel level = new ConstantLocationLevel.Builder(levelId, time.toInstant()) .withOfficeId(OFFICE) .withLevelUnitsId("ac-ft") .withConstantValue(1.0) @@ -876,7 +878,7 @@ void test_get_all_earliest_time() throws Exception { final ZonedDateTime time = ZonedDateTime.of(2023, 6, 1, 0, 0, 0, 0, ZoneId.of("America" + "/Los_Angeles")); CwmsDataApiSetupCallback.getDatabaseLink().connection(c -> { - LocationLevel level = new ConstantLocationLevel.Builder(levelId, time) + LocationLevel level = new ConstantLocationLevel.Builder(levelId, time.toInstant()) .withOfficeId(OFFICE) .withLevelUnitsId("ac-ft") .withConstantValue(1.0) @@ -892,7 +894,7 @@ void test_get_all_earliest_time() throws Exception { createLocation(locId2, true, OFFICE); CwmsDataApiSetupCallback.getDatabaseLink().connection(c -> { - LocationLevel level = new ConstantLocationLevel.Builder(levelId2, time) + LocationLevel level = new ConstantLocationLevel.Builder(levelId2, time.toInstant()) .withOfficeId(OFFICE) .withLevelUnitsId("ac-ft") .withConstantValue(2.0) @@ -1010,7 +1012,7 @@ void test_get_one_invalid_units() throws Exception { createLocation("level_units_invalid", true, OFFICE); String levelId = "level_units_invalid.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) + LocationLevel level = new ConstantLocationLevel.Builder(levelId, time.toInstant()) .withOfficeId(OFFICE) .withConstantValue(1.0) .withLevelUnitsId("ac-ft") @@ -1813,14 +1815,14 @@ void testStoreSeasonalLevel() throws Exception { .withOffsetMonths(i) .build()); } - SeasonalLocationLevel level = new SeasonalLocationLevel.Builder(levelId, levelDate) + SeasonalLocationLevel level = new SeasonalLocationLevel.Builder(levelId, levelDate.toInstant()) .withOfficeId(OFFICE) .withLevelUnitsId("ft") .withIntervalMonths(12) - .withIntervalOrigin(intervalOrigin) + .withIntervalOrigin(intervalOrigin.toInstant()) .withSeasonalValues(values) .withInterpolateString("T") - .withExpirationDate(levelDate.plusYears(50)) + .withExpirationDate(levelDate.plusYears(50).toInstant()) .build(); String levelJson = Formats.format(new ContentType(Formats.JSONV2), level); @@ -1879,14 +1881,14 @@ void testRetrieveAllSeasonalLevel() throws Exception { .withOffsetMonths(i) .build()); } - SeasonalLocationLevel level = new SeasonalLocationLevel.Builder(levelId, levelDate) + SeasonalLocationLevel level = new SeasonalLocationLevel.Builder(levelId, levelDate.toInstant()) .withOfficeId(OFFICE) .withLevelUnitsId("ft") .withIntervalMonths(12) - .withIntervalOrigin(intervalOrigin) + .withIntervalOrigin(intervalOrigin.toInstant()) .withSeasonalValues(values) .withInterpolateString("T") - .withExpirationDate(levelDate.plusYears(50)) + .withExpirationDate(levelDate.plusYears(50).toInstant()) .build(); String levelJson = Formats.format(new ContentType(Formats.JSONV2), level); @@ -1957,11 +1959,11 @@ void testStoreTimeSeriesLevel() throws Exception { String tsId = String.format("%s.Elev.Ave.1Day.1Week.Regulating", locName); createTimeseries(OFFICE, tsId); ZonedDateTime time = ZonedDateTime.ofInstant(Instant.parse("2024-01-01T00:00:00Z"), ZoneId.of("UTC")); - TimeSeriesLocationLevel level = new TimeSeriesLocationLevel.Builder(levelId, time, tsId) + TimeSeriesLocationLevel level = new TimeSeriesLocationLevel.Builder(levelId, time.toInstant(), tsId) .withOfficeId(OFFICE) .withLevelUnitsId("ft") .withInterpolateString("T") - .withExpirationDate(time.plusYears(50)) + .withExpirationDate(time.plusYears(50).toInstant()) .build(); String levelJson = Formats.format(new ContentType(Formats.JSONV2), level); @@ -2010,11 +2012,11 @@ void testStoreConstantLevel() throws Exception { createLocation(locName, true, OFFICE); String levelId = String.format("%s.Elev.Ave.1Day.Regulating", locName); ZonedDateTime time = ZonedDateTime.ofInstant(Instant.parse("2024-01-01T00:00:00Z"), ZoneId.of("UTC")); - ConstantLocationLevel level = new ConstantLocationLevel.Builder(levelId, time) + ConstantLocationLevel level = new ConstantLocationLevel.Builder(levelId, time.toInstant()) .withOfficeId(OFFICE) .withLevelUnitsId("ft") .withConstantValue(8675.309) - .withExpirationDate(time.plusYears(50)) + .withExpirationDate(time.plusYears(50).toInstant()) .build(); String levelJson = Formats.format(new ContentType(Formats.JSONV2), level); @@ -2082,12 +2084,12 @@ void test_get_constants_over_time() throws Exception { final ZonedDateTime time = ZonedDateTime.of(2023, 6, 1, 0, 0, 0, 0, ZoneId.of("America" + "/Los_Angeles")); CwmsDataApiSetupCallback.getDatabaseLink().connection(c -> { - LocationLevel level = new ConstantLocationLevel.Builder(levelId, time) + LocationLevel level = new ConstantLocationLevel.Builder(levelId, time.toInstant()) .withOfficeId(OFFICE) .withConstantValue(1.0) .withLevelUnitsId("ac-ft") .build(); - LocationLevel level2 = new ConstantLocationLevel.Builder(levelId, time.plusDays(1)) + LocationLevel level2 = new ConstantLocationLevel.Builder(levelId, time.plusDays(1).toInstant()) .withOfficeId(OFFICE) .withConstantValue(2.0) .withLevelUnitsId("ac-ft") @@ -2165,17 +2167,17 @@ void test_get_aliases() throws Exception { String controlLevelId = controlLocationName + ".Elev.Ave.1Day.USGS"; ZonedDateTime time = ZonedDateTime.of(2023, 6, 1, 0, 0, 0, 0, ZoneId.of("America/Los_Angeles")); CwmsDataApiSetupCallback.getDatabaseLink().connection(c -> { - LocationLevel level1 = new ConstantLocationLevel.Builder(levelId1, time) + LocationLevel level1 = new ConstantLocationLevel.Builder(levelId1, time.toInstant()) .withOfficeId(OFFICE) .withLevelUnitsId("ac-ft") .withConstantValue(12.0) .build(); - LocationLevel level2 = new ConstantLocationLevel.Builder(levelId2, time) + LocationLevel level2 = new ConstantLocationLevel.Builder(levelId2, time.toInstant()) .withOfficeId(OFFICE) .withLevelUnitsId("m") .withConstantValue(123.0) .build(); - LocationLevel level3 = new ConstantLocationLevel.Builder(controlLevelId, time) + LocationLevel level3 = new ConstantLocationLevel.Builder(controlLevelId, time.toInstant()) .withOfficeId(OFFICE) .withLevelUnitsId("m") .withConstantValue(25.0) @@ -2439,7 +2441,7 @@ private void createVirtualLocation(String specXml, String setXml, ZonedDateTime } catch (RatingException | IOException e) { throw new RuntimeException(e); } - LocationLevel level = new ConstantLocationLevel.Builder(levelId, time) + LocationLevel level = new ConstantLocationLevel.Builder(levelId, time.toInstant()) .withOfficeId(OFFICE) .withLevelUnitsId("ac-ft") .withConstantValue(1.0) @@ -2448,7 +2450,7 @@ private void createVirtualLocation(String specXml, String setXml, ZonedDateTime LocationLevelsDaoImpl dao = new LocationLevelsDaoImpl(dsl); dao.storeLocationLevel(level); if (levelId2 != null) { - level = new ConstantLocationLevel.Builder(levelId2, time) + level = new ConstantLocationLevel.Builder(levelId2, time.toInstant()) .withOfficeId(OFFICE) .withLevelUnitsId("ac-ft") .withConstantValue(10.0) diff --git a/cwms-data-api/src/test/java/cwms/cda/api/LockControllerIT.java b/cwms-data-api/src/test/java/cwms/cda/api/LockControllerIT.java index 0db3fe1a3f..cf0204d03f 100644 --- a/cwms-data-api/src/test/java/cwms/cda/api/LockControllerIT.java +++ b/cwms-data-api/src/test/java/cwms/cda/api/LockControllerIT.java @@ -1049,28 +1049,28 @@ private static PROJECT_OBJ_T buildProject(Location projectLocation) { private List createLocationLevelList(Lock lock) { List retVal = new ArrayList<>(); - ConstantLocationLevel lowLowerLevel = new ConstantLocationLevel.Builder(lock.getLowWaterLowerPoolLocationLevel().getLevelId(), ZonedDateTime.now()) + var lowLowerLevel = new ConstantLocationLevel.Builder(lock.getLowWaterLowerPoolLocationLevel().getLevelId(), ZonedDateTime.now().toInstant()) .withLevelUnitsId(lock.getElevationUnits()) .withOfficeId(lock.getLowWaterLowerPoolLocationLevel().getOfficeId()) .withSpecifiedLevelId(lock.getLowWaterLowerPoolLocationLevel().getSpecifiedLevelId()) .withConstantValue(lock.getLowWaterLowerPoolLocationLevel().getLevelValue()) .build(); retVal.add(lowLowerLevel); - ConstantLocationLevel lowUpperLevel = new ConstantLocationLevel.Builder(lock.getLowWaterUpperPoolLocationLevel().getLevelId(), ZonedDateTime.now()) + var lowUpperLevel = new ConstantLocationLevel.Builder(lock.getLowWaterUpperPoolLocationLevel().getLevelId(), ZonedDateTime.now().toInstant()) .withLevelUnitsId(lock.getElevationUnits()) .withOfficeId(lock.getLowWaterUpperPoolLocationLevel().getOfficeId()) .withSpecifiedLevelId(lock.getLowWaterUpperPoolLocationLevel().getSpecifiedLevelId()) .withConstantValue(lock.getLowWaterUpperPoolLocationLevel().getLevelValue()) .build(); retVal.add(lowUpperLevel); - ConstantLocationLevel highLowerLevel = new ConstantLocationLevel.Builder(lock.getHighWaterLowerPoolLocationLevel().getLevelId(), ZonedDateTime.now()) + var highLowerLevel = new ConstantLocationLevel.Builder(lock.getHighWaterLowerPoolLocationLevel().getLevelId(), ZonedDateTime.now().toInstant()) .withLevelUnitsId(lock.getElevationUnits()) .withOfficeId(lock.getHighWaterLowerPoolLocationLevel().getOfficeId()) .withSpecifiedLevelId(lock.getHighWaterLowerPoolLocationLevel().getSpecifiedLevelId()) .withConstantValue(lock.getHighWaterLowerPoolLocationLevel().getLevelValue()) .build(); retVal.add(highLowerLevel); - ConstantLocationLevel highUpperLevel = new ConstantLocationLevel.Builder(lock.getHighWaterUpperPoolLocationLevel().getLevelId(), ZonedDateTime.now()) + var highUpperLevel = new ConstantLocationLevel.Builder(lock.getHighWaterUpperPoolLocationLevel().getLevelId(), ZonedDateTime.now().toInstant()) .withLevelUnitsId(lock.getElevationUnits()) .withOfficeId(lock.getHighWaterUpperPoolLocationLevel().getOfficeId()) @@ -1078,7 +1078,7 @@ private List createLocationLevelList(Lock lock) { .withConstantValue(lock.getHighWaterUpperPoolLocationLevel().getLevelValue()) .build(); retVal.add(highUpperLevel); - ConstantLocationLevel warningBuffer = new ConstantLocationLevel.Builder(String.format("%s.Elev-Closure.Inst.0.Warning Buffer", lock.getLocation().getName()), ZonedDateTime.now()) + var warningBuffer = new ConstantLocationLevel.Builder(String.format("%s.Elev-Closure.Inst.0.Warning Buffer", lock.getLocation().getName()), ZonedDateTime.now().toInstant()) .withLevelUnitsId(lock.getElevationUnits()) .withOfficeId(lock.getLocation().getOfficeId()) .withSpecifiedLevelId("Warning Buffer") 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 f5810743f1..ba54f428e0 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 @@ -46,6 +46,7 @@ import java.io.IOException; import java.math.BigDecimal; import java.math.BigInteger; +import java.time.Instant; import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.ArrayList; @@ -244,7 +245,7 @@ private SeasonalLocationLevel getUpdatedLocationLevel(SeasonalLocationLevel exis String levelUnitsId = (updatedLevel.getLevelUnitsId() == null ? existinglocation.getLevelUnitsId() : updatedLevel.getLevelUnitsId()); - ZonedDateTime levelDate = (updatedLevel.getLevelDate() == null + Instant levelDate = (updatedLevel.getLevelDate() == null ? existinglocation.getLevelDate() : updatedLevel.getLevelDate()); String levelComment = (updatedLevel.getLevelComment() == null ? existinglocation.getLevelComment() : updatedLevel.getLevelComment()); @@ -273,7 +274,7 @@ private SeasonalLocationLevel getUpdatedLocationLevel(SeasonalLocationLevel exis attributeUnitsId = null; } - ZonedDateTime intervalOrigin = (updatedLevel.getIntervalOrigin() == null + Instant intervalOrigin = (updatedLevel.getIntervalOrigin() == null ? existinglocation.getIntervalOrigin() : updatedLevel.getIntervalOrigin()); Integer intervalMinutes = (updatedLevel.getIntervalMinutes() == null ? existinglocation.getIntervalMinutes() : updatedLevel.getIntervalMinutes()); @@ -337,10 +338,10 @@ LocationLevel buildExampleLevel(String locationName) throws Exception seasonalValues.add(0, seasonalVal); ZonedDateTimeAdapter zonedDateTimeAdapter = new ZonedDateTimeAdapter(); ZonedDateTime unmarshalledDateTime = zonedDateTimeAdapter.unmarshal(dateString); - return ((SeasonalLocationLevel.Builder) new SeasonalLocationLevel.Builder(locationName + ".Elev.Inst.0.Bottom of Inlet", unmarshalledDateTime) + return new SeasonalLocationLevel.Builder(locationName + ".Elev.Inst.0.Bottom of Inlet", unmarshalledDateTime.toInstant()) .withOfficeId(OFFICE_ID) .withLevelComment("For testing") - .withLevelUnitsId(Unit.FEET.getValue())) + .withLevelUnitsId(Unit.FEET.getValue()) .withSeasonalValues(seasonalValues) .withIntervalMonths(1) .build(); diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dao/location/kind/LockDaoIT.java b/cwms-data-api/src/test/java/cwms/cda/data/dao/location/kind/LockDaoIT.java index 9894d4b931..485771c9c3 100644 --- a/cwms-data-api/src/test/java/cwms/cda/data/dao/location/kind/LockDaoIT.java +++ b/cwms-data-api/src/test/java/cwms/cda/data/dao/location/kind/LockDaoIT.java @@ -330,38 +330,38 @@ private Lock storeLocLevelsAndBuildStorableLock(Lock lock) throws SQLException { private List createLocationLevelList(Lock lock) { List retVal = new ArrayList<>(); - ConstantLocationLevel lowLowerLevel = ((ConstantLocationLevel.Builder) new ConstantLocationLevel.Builder(lock.getLowWaterLowerPoolLocationLevel().getLevelId(), ZonedDateTime.now()) + var lowLowerLevel = new ConstantLocationLevel.Builder(lock.getLowWaterLowerPoolLocationLevel().getLevelId(), ZonedDateTime.now().toInstant()) .withLevelUnitsId(lock.getElevationUnits()) .withOfficeId(lock.getLowWaterLowerPoolLocationLevel().getOfficeId()) - .withSpecifiedLevelId(lock.getLowWaterLowerPoolLocationLevel().getSpecifiedLevelId())) + .withSpecifiedLevelId(lock.getLowWaterLowerPoolLocationLevel().getSpecifiedLevelId()) .withConstantValue(lock.getLowWaterLowerPoolLocationLevel().getLevelValue()) .build(); retVal.add(lowLowerLevel); - ConstantLocationLevel lowUpperLevel = ((ConstantLocationLevel.Builder) new ConstantLocationLevel.Builder(lock.getLowWaterUpperPoolLocationLevel().getLevelId(), ZonedDateTime.now()) + var lowUpperLevel = new ConstantLocationLevel.Builder(lock.getLowWaterUpperPoolLocationLevel().getLevelId(), ZonedDateTime.now().toInstant()) .withLevelUnitsId(lock.getElevationUnits()) .withOfficeId(lock.getLowWaterUpperPoolLocationLevel().getOfficeId()) - .withSpecifiedLevelId(lock.getLowWaterUpperPoolLocationLevel().getSpecifiedLevelId())) + .withSpecifiedLevelId(lock.getLowWaterUpperPoolLocationLevel().getSpecifiedLevelId()) .withConstantValue(lock.getLowWaterUpperPoolLocationLevel().getLevelValue()) .build(); retVal.add(lowUpperLevel); - ConstantLocationLevel highLowerLevel = ((ConstantLocationLevel.Builder) new ConstantLocationLevel.Builder(lock.getHighWaterLowerPoolLocationLevel().getLevelId(), ZonedDateTime.now()) + var highLowerLevel = new ConstantLocationLevel.Builder(lock.getHighWaterLowerPoolLocationLevel().getLevelId(), ZonedDateTime.now().toInstant()) .withLevelUnitsId(lock.getElevationUnits()) .withOfficeId(lock.getHighWaterLowerPoolLocationLevel().getOfficeId()) - .withSpecifiedLevelId(lock.getHighWaterLowerPoolLocationLevel().getSpecifiedLevelId())) + .withSpecifiedLevelId(lock.getHighWaterLowerPoolLocationLevel().getSpecifiedLevelId()) .withConstantValue(lock.getHighWaterLowerPoolLocationLevel().getLevelValue()) .build(); retVal.add(highLowerLevel); - ConstantLocationLevel highUpperLevel = ((ConstantLocationLevel.Builder) new ConstantLocationLevel.Builder(lock.getHighWaterUpperPoolLocationLevel().getLevelId(), ZonedDateTime.now()) + var highUpperLevel = new ConstantLocationLevel.Builder(lock.getHighWaterUpperPoolLocationLevel().getLevelId(), ZonedDateTime.now().toInstant()) .withLevelUnitsId(lock.getElevationUnits()) .withOfficeId(lock.getHighWaterUpperPoolLocationLevel().getOfficeId()) - .withSpecifiedLevelId(lock.getHighWaterUpperPoolLocationLevel().getSpecifiedLevelId())) + .withSpecifiedLevelId(lock.getHighWaterUpperPoolLocationLevel().getSpecifiedLevelId()) .withConstantValue(lock.getHighWaterUpperPoolLocationLevel().getLevelValue()) .build(); retVal.add(highUpperLevel); - ConstantLocationLevel warningBuffer = ((ConstantLocationLevel.Builder) new ConstantLocationLevel.Builder(String.format("%s.Elev-Closure.Inst.0.Warning Buffer", lock.getLocation().getName()), ZonedDateTime.now()) + var warningBuffer = new ConstantLocationLevel.Builder(String.format("%s.Elev-Closure.Inst.0.Warning Buffer", lock.getLocation().getName()), ZonedDateTime.now().toInstant()) .withLevelUnitsId(lock.getElevationUnits()) .withOfficeId(lock.getLocation().getOfficeId()) - .withSpecifiedLevelId("Warning Buffer")) + .withSpecifiedLevelId("Warning Buffer") .withConstantValue(lock.getHighWaterLowerPoolWarningLevel()) .build(); retVal.add(warningBuffer); diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dto/LocationLevelTest.java b/cwms-data-api/src/test/java/cwms/cda/data/dto/LocationLevelTest.java index 59ea645081..624089313b 100644 --- a/cwms-data-api/src/test/java/cwms/cda/data/dto/LocationLevelTest.java +++ b/cwms-data-api/src/test/java/cwms/cda/data/dto/LocationLevelTest.java @@ -2,6 +2,7 @@ import cwms.cda.api.errors.ExclusiveFieldsException; import cwms.cda.data.dto.catalog.LocationAlias; +import java.time.Instant; import java.time.ZonedDateTime; import com.fasterxml.jackson.core.JsonProcessingException; @@ -34,7 +35,7 @@ class LocationLevelTest { void test_serialization_formats_TimeSeries() { ZonedDateTime zdt = ZonedDateTime.parse("2021-06-21T08:00:00-07:00[PST8PDT]"); String tsId = "Test.Elev.Ave.1Day.Regulating"; - final TimeSeriesLocationLevel level = new TimeSeriesLocationLevel.Builder("Test", zdt, tsId).build(); + final TimeSeriesLocationLevel level = new TimeSeriesLocationLevel.Builder("Test", zdt.toInstant(), tsId).build(); ContentType contentType = Formats.parseHeader(Formats.JSONV2, LocationLevel.class); String jsonStr = Formats.format(contentType, level); @@ -48,7 +49,7 @@ void test_serialization_formats_TimeSeries() { @Test void test_serialization_formats_Constant() { ZonedDateTime zdt = ZonedDateTime.parse("2021-06-21T08:00:00-07:00[PST8PDT]"); - final ConstantLocationLevel level = new ConstantLocationLevel.Builder("Test", zdt).build(); + final ConstantLocationLevel level = new ConstantLocationLevel.Builder("Test", zdt.toInstant()).build(); ContentType contentType = Formats.parseHeader(Formats.JSONV2, LocationLevel.class); String jsonStr = Formats.format(contentType, level); @@ -62,7 +63,7 @@ void test_serialization_formats_Constant() { @Test void test_serialization_formats_Seasonal() { ZonedDateTime zdt = ZonedDateTime.parse("2021-06-21T08:00:00-07:00[PST8PDT]"); - final SeasonalLocationLevel level = (new SeasonalLocationLevel.Builder("Test", zdt) + final SeasonalLocationLevel level = (new SeasonalLocationLevel.Builder("Test", zdt.toInstant()) .withSeasonalValue(new SeasonalValueBean.Builder().withValue(34.9).build()) .withIntervalMinutes(23) .withOfficeId("SPK")) @@ -77,10 +78,30 @@ void test_serialization_formats_Seasonal() { assertTrue(jsonStr.contains("2021")); } + @Test + void test_serialization_formats_level_dates_as_utc() { + ZonedDateTime levelDate = ZonedDateTime.parse("2024-03-28T00:00:00-07:00[America/Los_Angeles]"); + ZonedDateTime expirationDate = ZonedDateTime.parse("2025-03-28T00:00:00-07:00[America/Los_Angeles]"); + ZonedDateTime intervalOrigin = ZonedDateTime.parse("2024-01-01T00:00:00-08:00[America/Los_Angeles]"); + final SeasonalLocationLevel level = (new SeasonalLocationLevel.Builder("Test", levelDate.toInstant()) + .withSeasonalValue(new SeasonalValueBean.Builder().withValue(34.9).build()) + .withIntervalOrigin(intervalOrigin.toInstant()) + .withExpirationDate(expirationDate.toInstant()) + .withOfficeId("SPK")) + .build(); + + ContentType contentType = Formats.parseHeader(Formats.JSONV2, LocationLevel.class); + String jsonStr = Formats.format(contentType, level); + + assertTrue(jsonStr.contains("\"level-date\":\"2024-03-28T07:00:00Z\"")); + assertTrue(jsonStr.contains("\"expiration-date\":\"2025-03-28T07:00:00Z\"")); + assertTrue(jsonStr.contains("\"interval-origin\":\"2024-01-01T08:00:00Z\"")); + } + @Test void test_serialization_formats_Virtual() { ZonedDateTime zdt = ZonedDateTime.parse("2021-06-21T08:00:00-07:00[PST8PDT]"); - final VirtualLocationLevel level = new VirtualLocationLevel.Builder("Test", zdt).build(); + final VirtualLocationLevel level = new VirtualLocationLevel.Builder("Test", zdt.toInstant()).build(); ContentType contentType = Formats.parseHeader(Formats.JSONV2, LocationLevel.class); String jsonStr = Formats.format(contentType, level); @@ -95,7 +116,7 @@ void test_serialization_formats_Virtual() { void test_serialization_om_TimeSeries() throws JsonProcessingException { ZonedDateTime zdt = ZonedDateTime.parse("2021-06-21T08:00:00-07:00[PST8PDT]"); String tsId = "Test.Elev.Ave.1Day.Regulating"; - final TimeSeriesLocationLevel level = new TimeSeriesLocationLevel.Builder("Test", zdt, tsId).build(); + final TimeSeriesLocationLevel level = new TimeSeriesLocationLevel.Builder("Test", zdt.toInstant(), tsId).build(); ObjectMapper om = JsonV2.buildObjectMapper(); String jsonStr = om.writeValueAsString(level); @@ -109,7 +130,7 @@ void test_serialization_om_TimeSeries() throws JsonProcessingException { @Test void test_serialization_om_Seasonal() throws JsonProcessingException { ZonedDateTime zdt = ZonedDateTime.parse("2021-06-21T08:00:00-07:00[PST8PDT]"); - final SeasonalLocationLevel level = (new SeasonalLocationLevel.Builder("Test", zdt) + final SeasonalLocationLevel level = (new SeasonalLocationLevel.Builder("Test", zdt.toInstant()) .withSeasonalValue(new SeasonalValueBean.Builder().withValue(21.0).build()) .withIntervalMonths(12) .withOfficeId("SPK")) @@ -127,7 +148,7 @@ void test_serialization_om_Seasonal() throws JsonProcessingException { @Test void test_serialization_om_Constant() throws JsonProcessingException { ZonedDateTime zdt = ZonedDateTime.parse("2021-06-21T08:00:00-07:00[PST8PDT]"); - final ConstantLocationLevel level = new ConstantLocationLevel.Builder("Test", zdt).build(); + final ConstantLocationLevel level = new ConstantLocationLevel.Builder("Test", zdt.toInstant()).build(); ObjectMapper om = JsonV2.buildObjectMapper(); String jsonStr = om.writeValueAsString(level); @@ -141,7 +162,7 @@ void test_serialization_om_Constant() throws JsonProcessingException { @Test void test_serialization_om_Virtual() throws JsonProcessingException { ZonedDateTime zdt = ZonedDateTime.parse("2021-06-21T08:00:00-07:00[PST8PDT]"); - final VirtualLocationLevel level = new VirtualLocationLevel.Builder("Test", zdt).build(); + final VirtualLocationLevel level = new VirtualLocationLevel.Builder("Test", zdt.toInstant()).build(); ObjectMapper om = JsonV2.buildObjectMapper(); String jsonStr = om.writeValueAsString(level); @@ -154,45 +175,45 @@ void test_serialization_om_Virtual() throws JsonProcessingException { @Test void test_mutual_exclusivity_seasonal() { - var noSeasonalIntervals = new SeasonalLocationLevel.Builder("Test", ZonedDateTime.now()).build(); + var noSeasonalIntervals = new SeasonalLocationLevel.Builder("Test", ZonedDateTime.now().toInstant()).build(); assertThrows(RequiredFieldException.class, noSeasonalIntervals::validate); - var conflictingSeasonalIntervals = new SeasonalLocationLevel.Builder("Test", ZonedDateTime.now()) + var conflictingSeasonalIntervals = new SeasonalLocationLevel.Builder("Test", ZonedDateTime.now().toInstant()) .withIntervalMinutes(25).withIntervalMonths(12).build(); assertThrows(RequiredFieldException.class, conflictingSeasonalIntervals::validate); } @Test void test_update_level() { - ConstantLocationLevel existingLevel = new ConstantLocationLevel.Builder("Test", ZonedDateTime.now()).withConstantValue(12345.65).build(); + ConstantLocationLevel existingLevel = new ConstantLocationLevel.Builder("Test", ZonedDateTime.now().toInstant()).withConstantValue(12345.65).build(); ZonedDateTime zdt = ZonedDateTime.parse("2021-06-21T08:00:00-07:00[PST8PDT]"); - ConstantLocationLevel updatedLevel = new ConstantLocationLevel.Builder("Test", ZonedDateTime.now()).withConstantValue(1899.45).build(); + ConstantLocationLevel updatedLevel = new ConstantLocationLevel.Builder("Test", ZonedDateTime.now().toInstant()).withConstantValue(1899.45).build(); - LocationLevel updated = LocationLevel.getUpdatedLocationLevel(existingLevel, updatedLevel, zdt); + LocationLevel updated = LocationLevel.getUpdatedLocationLevel(existingLevel, updatedLevel, zdt.toInstant()); assertNotNull(updated); assertInstanceOf(ConstantLocationLevel.class, updated); ConstantLocationLevel constantLevel = (ConstantLocationLevel) updated; assertEquals(1899.45, constantLevel.getConstantValue()); - assertEquals(zdt, constantLevel.getLevelDate()); + assertEquals(zdt.toInstant(), constantLevel.getLevelDate()); } @Test void test_update_level_virtual() { - VirtualLocationLevel existingLevel = new VirtualLocationLevel.Builder("Test", ZonedDateTime.now()).withConstituentConnections("L1=L2").build(); + VirtualLocationLevel existingLevel = new VirtualLocationLevel.Builder("Test", ZonedDateTime.now().toInstant()).withConstituentConnections("L1=L2").build(); ZonedDateTime zdt = ZonedDateTime.parse("2021-06-21T08:00:00-07:00[PST8PDT]"); - VirtualLocationLevel updatedLevel = new VirtualLocationLevel.Builder("Test", ZonedDateTime.now()).withConstituentConnections("L2=L3").build(); + VirtualLocationLevel updatedLevel = new VirtualLocationLevel.Builder("Test", ZonedDateTime.now().toInstant()).withConstituentConnections("L2=L3").build(); - LocationLevel updated = LocationLevel.getUpdatedLocationLevel(existingLevel, updatedLevel, zdt); + LocationLevel updated = LocationLevel.getUpdatedLocationLevel(existingLevel, updatedLevel, zdt.toInstant()); assertNotNull(updated); assertInstanceOf(VirtualLocationLevel.class, updated); VirtualLocationLevel virtualLevel = (VirtualLocationLevel) updated; assertEquals("L2=L3", virtualLevel.getConstituentConnections()); - assertEquals(zdt, virtualLevel.getLevelDate()); + assertEquals(zdt.toInstant(), virtualLevel.getLevelDate()); } @Test @@ -204,7 +225,7 @@ void test_alias_serialization_roundtrip() { aliases.add(alias1); aliases.add(alias2); - final ConstantLocationLevel level = new ConstantLocationLevel.Builder("Test", zdt) + final ConstantLocationLevel level = new ConstantLocationLevel.Builder("Test", zdt.toInstant()) .withConstantValue(25.0) .withOfficeId("SPK") .withAliases(aliases) @@ -237,7 +258,7 @@ void test_alias_serialization_roundtrip() { void test_no_alias_serialization_roundtrip() { ZonedDateTime zdt = ZonedDateTime.parse("2021-06-21T08:00:00-07:00[PST8PDT]"); - final ConstantLocationLevel level = new ConstantLocationLevel.Builder("Test", zdt) + final ConstantLocationLevel level = new ConstantLocationLevel.Builder("Test", zdt.toInstant()) .withOfficeId("SPK") .withConstantValue(25.0) .build(); @@ -262,11 +283,11 @@ void test_no_alias_serialization_roundtrip() { @Test void testMutuallyExclusiveSeasonalLevel() { var level = new SeasonalLocationLevel - .Builder("LocationLevelId", ZonedDateTime.now()) + .Builder("LocationLevelId", Instant.now()) .withIntervalMinutes(120) .withIntervalMonths(2) .withOfficeId("LRL") - .withIntervalOrigin(ZonedDateTime.now()) + .withIntervalOrigin(Instant.now()) .withSeasonalValue(new SeasonalValueBean.Builder(12.0).withOffsetMonths(2).build()) .build(); assertThrows(ExclusiveFieldsException.class, level::validate); diff --git a/cwms-data-api/src/test/java/cwms/cda/formatters/JsonV2Test.java b/cwms-data-api/src/test/java/cwms/cda/formatters/JsonV2Test.java index 54625be1ef..ec46dde362 100644 --- a/cwms-data-api/src/test/java/cwms/cda/formatters/JsonV2Test.java +++ b/cwms-data-api/src/test/java/cwms/cda/formatters/JsonV2Test.java @@ -44,7 +44,7 @@ void canSerializeLocationLevel(){ private LocationLevel buildLevel(String crazyName) { ZonedDateTime efDate = ZonedDateTime.parse("2021-06-21T08:00:00-07:00[PST8PDT]"); - return new ConstantLocationLevel.Builder(crazyName, efDate).build(); + return new ConstantLocationLevel.Builder(crazyName, efDate.toInstant()).build(); } @Test