From 1b8b925ab1960cd0f0a177e05d327ba9009d1d45 Mon Sep 17 00:00:00 2001 From: Andreas Christmann Date: Fri, 14 Jun 2024 08:36:33 -0700 Subject: [PATCH 01/26] ts profile json --- .../timeseriesprofile/timeseriesprofile.json | 8 ++++ .../timeseriesprofileinstance.json | 41 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofile.json create mode 100644 cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileinstance.json diff --git a/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofile.json b/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofile.json new file mode 100644 index 000000000..5222856a6 --- /dev/null +++ b/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofile.json @@ -0,0 +1,8 @@ +{ + "description": "Description", + "parameter-list": ["Temperature","Depth"], + "location-id": "Location", + "office-id": "Office", + "ref-ts-id": "TimeSeries", + "key-parameter": "Depth" +} \ No newline at end of file diff --git a/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileinstance.json b/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileinstance.json new file mode 100644 index 000000000..b6555c4fe --- /dev/null +++ b/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileinstance.json @@ -0,0 +1,41 @@ +{ + "time-series-profile": + { + "location-id": "DET", + "key-parameter": "Depth", + "parameter-list": [ "Temp-Water", "Pres", "%-DO", "Conc-DO", "Cond", "pH", "TurbN", "Depth","Volt-Battery"], + "description": "Demonstration Profile for Couger Lake", + "office-id": "SWT", + "ref-ts-id": "DET.Elev-Forebay.Inst.0.0.Mixed-Rev" + }, + + "value-list" : [ + { + "time-zone": "US/Pacific", + "times" : ["09/09/2019,13:16:01", "09/09/2019,13:17:20"], + "value": + { + "parameter": "Temp-Water", + "unit": "F", + "values": ["1", "2"] + } + }, + { + "value": + { + "parameter": "Pres", + "unit": "mm-hg", + "values": ["1", "2"] + } + }, + { + "value": + { + "parameter": "Depth", + "unit": "ft", + "values": ["1", "2"] + } + } + ] + +} \ No newline at end of file From 32c0927816de7fbd776bef607e03ed8a54e7fbd3 Mon Sep 17 00:00:00 2001 From: Andreas Christmann Date: Tue, 18 Jun 2024 10:32:51 -0700 Subject: [PATCH 02/26] ts profile json --- .../timeseriesprofileinstance.json | 53 ++++++++++--------- .../timeseriesprofileparser.json | 23 ++++++++ 2 files changed, 51 insertions(+), 25 deletions(-) create mode 100644 cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileparser.json diff --git a/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileinstance.json b/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileinstance.json index b6555c4fe..e432b678b 100644 --- a/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileinstance.json +++ b/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileinstance.json @@ -3,39 +3,42 @@ { "location-id": "DET", "key-parameter": "Depth", - "parameter-list": [ "Temp-Water", "Pres", "%-DO", "Conc-DO", "Cond", "pH", "TurbN", "Depth","Volt-Battery"], + "parameter-list": [ "Temp-Water", "Depth"], "description": "Demonstration Profile for Couger Lake", "office-id": "SWT", "ref-ts-id": "DET.Elev-Forebay.Inst.0.0.Mixed-Rev" }, - "value-list" : [ + "timeseries-list" : [ { - "time-zone": "US/Pacific", - "times" : ["09/09/2019,13:16:01", "09/09/2019,13:17:20"], - "value": - { - "parameter": "Temp-Water", - "unit": "F", - "values": ["1", "2"] - } + "parameter": "Temp-Water", + "unit": "F", + "time-value-pairs": + [ + { + "time": "09/09/2019,13:16:01Z", + "value": "1.0" + }, + { + "time": "09/09/2019,13:17:20Z", + "value": "2.0" + } + ] }, { - "value": - { - "parameter": "Pres", - "unit": "mm-hg", - "values": ["1", "2"] - } - }, - { - "value": - { - "parameter": "Depth", - "unit": "ft", - "values": ["1", "2"] - } + "parameter": "Depth", + "unit": "ft", + "time-value-pairs": + [ + { + "time": "09/09/2019,13:16:01-07:00", + "value": "1.0" + }, + { + "time": "09/09/2019,13:17:20-07:00", + "value": "2.0" + } + ] } ] - } \ No newline at end of file diff --git a/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileparser.json b/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileparser.json new file mode 100644 index 000000000..7ca2c30e3 --- /dev/null +++ b/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileparser.json @@ -0,0 +1,23 @@ +{ + "office-id": "SWT", + "location-id": "TIMESERIESPROFILE_LOC", + "key-parameter": "Depth", + "record-delimiter": "\n", + "field-delimiter": ",", + "time-format": "MM/DD/YYYY,HH24:MI:SS", + "time-zone": "UTC", + "time-field": 1, + "time-in-two-fields": "F", + "parameter-info": [ + { + "parameter":"Depth", + "unit":"m", + "index":3 + }, + { + "parameter":"Temp-Water", + "unit":"F", + "index":5 + } + ] +} From 7b61ef3507f0d4c5cb838d609f1e308d22a1f72d Mon Sep 17 00:00:00 2001 From: Andreas Christmann Date: Tue, 18 Jun 2024 10:48:46 -0700 Subject: [PATCH 03/26] ts profile json --- .../cwms/cda/data/dto/timeseriesprofile/timeseriesprofile.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofile.json b/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofile.json index 5222856a6..4bbf3e071 100644 --- a/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofile.json +++ b/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofile.json @@ -4,5 +4,5 @@ "location-id": "Location", "office-id": "Office", "ref-ts-id": "TimeSeries", - "key-parameter": "Depth" + "key-parameter": "Depth", } \ No newline at end of file From ab581100d59cae4b25a9053ad9dd54701d83bf9d Mon Sep 17 00:00:00 2001 From: Andreas Christmann Date: Tue, 18 Jun 2024 10:50:55 -0700 Subject: [PATCH 04/26] ts profile json --- .../cwms/cda/data/dto/timeseriesprofile/timeseriesprofile.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofile.json b/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofile.json index 4bbf3e071..5222856a6 100644 --- a/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofile.json +++ b/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofile.json @@ -4,5 +4,5 @@ "location-id": "Location", "office-id": "Office", "ref-ts-id": "TimeSeries", - "key-parameter": "Depth", + "key-parameter": "Depth" } \ No newline at end of file From 15fdef179192ad449a13f83b4ca8e2328c168d96 Mon Sep 17 00:00:00 2001 From: Andreas Christmann Date: Wed, 19 Jun 2024 14:19:39 -0700 Subject: [PATCH 05/26] sample time series profile data --- .../timeSeriesProfileData.txt | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeSeriesProfileData.txt diff --git a/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeSeriesProfileData.txt b/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeSeriesProfileData.txt new file mode 100644 index 000000000..8f514133c --- /dev/null +++ b/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeSeriesProfileData.txt @@ -0,0 +1,27 @@ +'sep=, Date,Time,Site,Unit ID,User ID,�F-18H105402,mmHg-18H111574,DO %-18H110258,DO mg/L-18H110258,SPC-uS/cm-18H105402,pH-18H111544,NTU-18H108850,BGA-PCRFU-18H110486,BGA-PCug/L-18H110486,Chl RFU-18H110486,Chl ug/L-18H110486,DEP ft-18H105572,Batt V-18H111574,Lat-18H111574,Lon-18H111574, +09/09/2019,12:48:57,DET,,Holly Bellringer,67.108,719.6,98.3,9.03,43.9,8.54,0.19,0.21,-0.65,0.17,-0.01,3.152,5.35,44.71898,-122.24620, +09/09/2019,12:49:19,DET,,Holly Bellringer,67.563,719.6,97.2,8.88,43.4,8.43,0.12,0.21,-0.65,0.19,0.05,4.028,5.34,44.71898,-122.24620, +09/09/2019,12:52:54,DET,,Holly Bellringer,67.820,719.5,96.8,8.82,43.3,8.04,0.23,0.14,-0.71,0.20,0.10,6.264,5.32,44.71899,-122.24610, +09/09/2019,12:53:17,DET,,Holly Bellringer,67.767,719.6,96.6,8.81,43.3,8.02,0.12,0.15,-0.70,0.24,0.24,8.525,5.31,44.71900,-122.24610, +09/09/2019,12:54:42,DET,,Holly Bellringer,67.718,719.6,96.5,8.80,43.3,7.97,0.11,0.13,-0.72,0.25,0.29,10.789,5.31,44.71898,-122.24620, +09/09/2019,12:55:50,DET,,Holly Bellringer,67.700,719.6,96.4,8.79,43.3,7.95,0.08,0.17,-0.68,0.23,0.19,12.045,5.27,44.71898,-122.24620, +09/09/2019,12:56:27,DET,,Holly Bellringer,67.682,719.5,96.3,8.79,43.2,7.92,0.08,0.16,-0.70,0.24,0.24,14.188,5.28,44.71897,-122.24620, +09/09/2019,12:56:54,DET,,Holly Bellringer,67.669,719.5,96.2,8.78,43.2,7.92,0.17,0.10,-0.75,0.27,0.39,16.218,5.26,44.71897,-122.24620, +09/09/2019,12:57:48,DET,,Holly Bellringer,67.651,719.5,96.1,8.77,43.2,7.86,0.13,0.10,-0.75,0.22,0.16,18.303,5.26,44.71901,-122.24620, +09/09/2019,12:58:57,DET,,Holly Bellringer,67.613,719.6,95.8,8.75,43.2,7.86,0.05,0.15,-0.70,0.24,0.26,23.081,5.24,44.71901,-122.24620, +09/09/2019,12:59:31,DET,,Holly Bellringer,67.572,719.6,95.3,8.71,43.2,7.83,0.12,0.12,-0.74,0.30,0.48,28.262,5.26,44.71900,-122.24620, +09/09/2019,13:00:37,DET,,Holly Bellringer,67.557,719.6,95.1,8.69,43.2,7.82,0.07,0.11,-0.74,0.27,0.39,33.043,5.28,44.71904,-122.24610, +09/09/2019,13:01:08,DET,,Holly Bellringer,67.495,719.6,94.6,8.65,43.2,7.78,0.17,0.15,-0.71,0.26,0.35,38.527,5.27,44.71902,-122.24620, +09/09/2019,13:02:17,DET,,Holly Bellringer,67.003,719.7,91.4,8.40,43.4,7.74,0.14,0.26,-0.59,0.57,1.55,43.937,5.28,44.71902,-122.24620, +09/09/2019,13:02:51,DET,,Holly Bellringer,64.150,719.6,77.9,7.40,44.2,7.63,0.12,0.15,-0.70,0.33,0.62,48.191,5.27,44.71902,-122.24620, +09/09/2019,13:03:50,DET,,Holly Bellringer,62.782,719.6,71.1,6.86,44.2,7.49,0.13,0.26,-0.59,0.40,0.88,53.288,5.28,44.71902,-122.24620, +09/09/2019,13:04:50,DET,,Holly Bellringer,61.698,719.7,65.8,6.43,43.5,7.37,0.19,0.22,-0.63,0.37,0.76,58.457,5.28,44.71902,-122.24620, +09/09/2019,13:07:48,DET,,Holly Bellringer,54.818,719.8,61.8,6.56,39.4,7.12,0.67,0.18,-0.67,0.12,-0.23,88.792,5.29,44.71902,-122.24620, +09/09/2019,13:08:57,DET,,Holly Bellringer,52.003,719.8,68.4,7.53,37.9,7.07,0.08,0.28,-0.58,0.13,-0.19,103.598,5.28,44.71904,-122.24620, +09/09/2019,13:09:46,DET,,Holly Bellringer,49.363,719.8,73.9,8.42,37.4,7.05,0.17,0.23,-0.63,0.13,-0.19,118.692,5.30,44.71901,-122.24620, +09/09/2019,13:11:20,DET,,Holly Bellringer,47.156,719.8,76.6,8.98,37.2,7.03,0.28,0.28,-0.58,0.10,-0.29,133.659,5.32,44.71902,-122.24620, +09/09/2019,13:12:45,DET,,Holly Bellringer,45.468,719.8,75.9,9.11,37.0,7.00,0.43,0.30,-0.55,0.11,-0.26,148.541,5.31,44.71902,-122.24620, +09/09/2019,13:13:33,DET,,Holly Bellringer,44.743,719.8,75.4,9.13,37.0,6.99,0.52,0.35,-0.50,0.10,-0.30,163.665,5.31,44.71900,-122.24620, +09/09/2019,13:14:49,DET,,Holly Bellringer,44.135,719.8,75.5,9.22,36.9,6.98,0.67,0.30,-0.55,0.13,-0.20,178.560,5.31,44.71901,-122.24620, +09/09/2019,13:16:01,DET,,Holly Bellringer,43.701,719.8,75.7,9.30,36.9,6.97,0.88,0.31,-0.54,0.08,-0.38,193.010,5.32,44.71903,-122.24620, +09/09/2019,13:17:20,DET,,Holly Bellringer,43.390,719.8,75.6,9.33,36.9,6.96,1.00,0.32,-0.53,0.10,-0.31,208.607,5.31,44.71902,-122.24620,'; From 88d507964a129654756286f32a0aa42573cdcc49 Mon Sep 17 00:00:00 2001 From: Andreas Christmann Date: Wed, 19 Jun 2024 14:22:27 -0700 Subject: [PATCH 06/26] time series profile dto's --- .../dto/timeseriesprofile/ParameterInfo.java | 96 +++++++++ .../timeseriesprofile/TimeSeriesProfile.java | 165 +++++++++++++++ .../TimeSeriesProfileInstance.java | 29 +++ .../TimeSeriesProfileParser.java | 194 ++++++++++++++++++ 4 files changed, 484 insertions(+) create mode 100644 cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfo.java create mode 100644 cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfile.java create mode 100644 cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstance.java create mode 100644 cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParser.java diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfo.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfo.java new file mode 100644 index 000000000..02640b45d --- /dev/null +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfo.java @@ -0,0 +1,96 @@ +package cwms.cda.data.dto.timeseriesprofile; + +import java.util.Objects; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.PropertyNamingStrategies; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; +import cwms.cda.api.errors.FieldException; +import cwms.cda.data.dto.CwmsDTOBase; +import cwms.cda.formatters.Formats; +import cwms.cda.formatters.annotations.FormattableWith; +import cwms.cda.formatters.json.JsonV2; + +@FormattableWith(contentType = Formats.JSONV2, formatter = JsonV2.class) +@JsonDeserialize(builder = ParameterInfo.Builder.class) +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) +public class ParameterInfo implements CwmsDTOBase +{ + private final String parameter; + private final String unit; + private final int index; + protected ParameterInfo(ParameterInfo.Builder builder) + { + parameter= builder.parameter; + unit = builder.unit; + index = builder.index; + } + public String getParameter() + { + return parameter; + } + public String getUnit() + { + return unit; + } + + public int getIndex(){ return index; } + + + @Override + public void validate() throws FieldException + { + + } + @Override + public int hashCode() { + int result = Objects.hashCode(getParameter()); + result = 31 * result + Objects.hashCode(getUnit()); + result = 31 * result + Objects.hashCode(getIndex()); + return result; + }@Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + ParameterInfo that = (ParameterInfo) o; + return Objects.equals(getParameter(), that.getParameter()) + && Objects.equals(getUnit(), that.getUnit()) + && Objects.equals(getIndex(), that.getIndex()); + } + @JsonPOJOBuilder + @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) + public static final class Builder + { + private String parameter; + private String unit; + private int index; + + + public ParameterInfo.Builder withParameter(String parameter) { + this.parameter = parameter; + return this; + } + public ParameterInfo.Builder withUnit(String unit) { + this.unit = unit; + return this; + } + public ParameterInfo.Builder withIndex(int index) + { + this.index = index; + return this; + } + + public ParameterInfo build() { + return new ParameterInfo(this); + } + + } +} \ No newline at end of file diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfile.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfile.java new file mode 100644 index 000000000..16805ff59 --- /dev/null +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfile.java @@ -0,0 +1,165 @@ +package cwms.cda.data.dto.timeseriesprofile; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.PropertyNamingStrategies; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; +import cwms.cda.api.errors.FieldException; +import cwms.cda.data.dto.CwmsDTO; +import cwms.cda.formatters.Formats; +import cwms.cda.formatters.annotations.FormattableWith; +import cwms.cda.formatters.json.JsonV2; +import io.swagger.v3.oas.annotations.media.Schema; + +@FormattableWith(contentType = Formats.JSONV2, formatter = JsonV2.class) +@JsonDeserialize(builder = TimeSeriesProfile.Builder.class) +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) +public final class TimeSeriesProfile extends CwmsDTO +{ + @Schema(description = "Location ID") + private final String locationId; + @Schema(description = "Description") + private final String description; + @Schema(description = "Parameter List") + private final List parameterList; + @Schema(description = "Key Parameter") + private final String keyParameter; + @Schema(description = "Reference TS") + private final String refTsId; + + private TimeSeriesProfile(Builder builder) + { + super(builder.officeId); + this.locationId = builder.locationId; + this.description = builder.description; + this.keyParameter = builder.keyParameter; + this.parameterList = builder.parameterList; + this.refTsId = builder.refTsId; + } + + public String getLocationId() + { + return locationId; + } + + public String getDescription() + { + return description; + } + + public String getKeyParameter() + { + return keyParameter; + } + + public List getParameterList() + { + return parameterList!=null ? new ArrayList<>(parameterList) : null; + } + + public String getRefTsId() + { + return refTsId; + } + + @Override + public void validate() throws FieldException + { + if (this.parameterList == null) { + throw new FieldException("Parameter list field can't be null"); + } + if (this.keyParameter == null) { + throw new FieldException("Key Parameter field can't be null"); + } + if (this.officeId == null) { + throw new FieldException("Office Id field can't be null"); + } + if (this.locationId == null) { + throw new FieldException("Location Id field can't be null"); + } + if (!parameterList.contains(keyParameter)) + { + throw new FieldException("Key Parameter must be part of Parameter list"); + } + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + TimeSeriesProfile that = (TimeSeriesProfile) o; + return Objects.equals(getLocationId(), that.getLocationId()) + && Objects.equals(getOfficeId(), that.getOfficeId()) + && Objects.equals(getDescription(), that.getDescription()) + && Objects.equals(getKeyParameter(), that.getKeyParameter()) + && Objects.equals(getRefTsId(), that.getRefTsId()) + && Objects.equals(getParameterList(), that.getParameterList()) + ; + } + @Override + public int hashCode() { + int result = Objects.hashCode(getDescription()); + result = 31 * result + Objects.hashCode(getKeyParameter()); + result = 31 * result + Objects.hashCode(getLocationId()); + result = 31 * result + Objects.hashCode(getParameterList()); + result = 31 * result + Objects.hashCode(getOfficeId()); + result = 31 * result + Objects.hashCode(getRefTsId()); + return result; + } + @JsonPOJOBuilder + @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) + public static final class Builder { + private String officeId; + private List parameterList; + private String keyParameter; + private String description; + private String locationId; + private String refTsId; + + public TimeSeriesProfile.Builder withLocationId(String locationId) { + this.locationId = locationId; + return this; + } + + public TimeSeriesProfile.Builder withDescription(String description) { + this.description = description; + return this; + } + public TimeSeriesProfile.Builder withKeyParameter(String keyParameter) { + this.keyParameter = keyParameter; + return this; + } + + public TimeSeriesProfile.Builder withParameterList(List parameterList) + { + this.parameterList = parameterList!=null ? new ArrayList<>(parameterList) : null; + return this; + } + + public TimeSeriesProfile.Builder withOfficeId(String officeId) { + this.officeId = officeId; + return this; + } + + public TimeSeriesProfile.Builder withRefTsId(String refTsId) { + this.refTsId = refTsId; + return this; + } + + + public TimeSeriesProfile build() { + return new TimeSeriesProfile(this); + } + } +} diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstance.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstance.java new file mode 100644 index 000000000..67a26b1aa --- /dev/null +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstance.java @@ -0,0 +1,29 @@ +package cwms.cda.data.dto.timeseriesprofile; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.PropertyNamingStrategies; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import cwms.cda.api.errors.FieldException; +import cwms.cda.data.dto.CwmsDTO; +import cwms.cda.formatters.Formats; +import cwms.cda.formatters.annotations.FormattableWith; +import cwms.cda.formatters.json.JsonV2; + +@FormattableWith(contentType = Formats.JSONV2, formatter = JsonV2.class) +@JsonDeserialize(builder = TimeSeriesProfile.Builder.class) +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) +public final class TimeSeriesProfileInstance extends CwmsDTO +{ + protected TimeSeriesProfileInstance(String office) + { + super(office); + } + + @Override + public void validate() throws FieldException + { + + } +} diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParser.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParser.java new file mode 100644 index 000000000..19532bb72 --- /dev/null +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParser.java @@ -0,0 +1,194 @@ +package cwms.cda.data.dto.timeseriesprofile; + +import java.math.BigInteger; +import java.util.List; +import java.util.Objects; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.PropertyNamingStrategies; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; +import cwms.cda.api.errors.FieldException; +import cwms.cda.data.dto.CwmsDTO; +import cwms.cda.formatters.Formats; +import cwms.cda.formatters.annotations.FormattableWith; +import cwms.cda.formatters.json.JsonV2; + +@FormattableWith(contentType = Formats.JSONV2, formatter = JsonV2.class) +@JsonDeserialize(builder = TimeSeriesProfileParser.Builder.class) +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) +public class TimeSeriesProfileParser extends CwmsDTO +{ + private final String locationId; + private final String keyParameter; + private final char recordDelimiter; + private final char fieldDelimiter; + private final String timeFormat; + private final String timeZone; + private final int timeField; + private final List parameterInfo; + private final boolean timeInTwoFields; + protected TimeSeriesProfileParser(Builder builder) + { + super(builder.officeId); + locationId = builder.locationId; + keyParameter = builder.keyParameter; + recordDelimiter = builder.recordDelimiter; + fieldDelimiter = builder.fieldDelimiter; + timeFormat = builder.timeFormat; + timeZone = builder.timeZone; + timeField = builder.timeField; + parameterInfo = builder.parameterInfo; + timeInTwoFields = builder.timeInTwoFields; + } + + @Override + public void validate() throws FieldException + { + + } + + + public String getLocationId() + { + return locationId; + } + + public String getKeyParameter() + { + return keyParameter; + } + public String getRecordDelimiter(){ return String.valueOf(recordDelimiter); } + public String getFieldDelimiter(){ return String.valueOf(fieldDelimiter); } + public List getParameterInfo () + { + return parameterInfo; + } + + public String getTimeFormat() + { + return timeFormat; + } + + public String getTimeZone() + { + return timeZone; + } + + public BigInteger getTimeField() + { + return BigInteger.valueOf(timeField); + } + + public String getTimeInTwoFields() + { + return timeInTwoFields?"T":"F"; + } + + @Override + public int hashCode() { + int result = Objects.hashCode(getLocationId()); + result = 31 * result + Objects.hashCode(getFieldDelimiter()); + result = 31 * result + Objects.hashCode(getOfficeId()); + result = 31 * result + Objects.hashCode(getKeyParameter()); + result = 31 * result + Objects.hashCode(getTimeField()); + result = 31 * result + Objects.hashCode(getTimeFormat()); + result = 31 * result + Objects.hashCode(getParameterInfo()); + result = 31 * result + Objects.hashCode(getRecordDelimiter()); + result = 31 * result + Objects.hashCode(getTimeZone()); + result = 31 * result + Objects.hashCode(getTimeInTwoFields()); + return result; + } + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + TimeSeriesProfileParser that = (TimeSeriesProfileParser) o; + return Objects.equals(getLocationId(), that.getLocationId()) + && Objects.equals(getFieldDelimiter(), that.getFieldDelimiter()) + && Objects.equals(getOfficeId(), that.getOfficeId()) + && Objects.equals(getKeyParameter(), that.getKeyParameter()) + && Objects.equals(getTimeField(), that.getTimeField()) + && Objects.equals(getTimeFormat(), that.getTimeFormat()) + && Objects.equals(getParameterInfo(), that.getParameterInfo()) + && Objects.equals(getRecordDelimiter(), that.getRecordDelimiter()) + && Objects.equals(getTimeZone(), that.getTimeZone()) + && Objects.equals(getTimeInTwoFields(), that.getTimeInTwoFields()); + } + + @JsonPOJOBuilder + @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) + public static final class Builder { + private String officeId; + private List parameterInfo; + private String keyParameter; + private char recordDelimiter; + private char fieldDelimiter; + private String timeFormat; + private String timeZone; + private int timeField; + private boolean timeInTwoFields; + private String locationId; + + public TimeSeriesProfileParser.Builder withLocationId(String locationId) { + this.locationId = locationId; + return this; + } + + public TimeSeriesProfileParser.Builder withKeyParameter(String keyParameter) { + this.keyParameter = keyParameter; + return this; + } + public TimeSeriesProfileParser.Builder withRecordDelimiter(char delimiter) { + this.recordDelimiter = delimiter; + return this; + } + public TimeSeriesProfileParser.Builder withFieldDelimiter(char delimiter) { + this.fieldDelimiter = delimiter; + return this; + } + public TimeSeriesProfileParser.Builder withTimeFormat(String timeFormat) + { + this.timeFormat = timeFormat; + return this; + } + public TimeSeriesProfileParser.Builder withTimeZone(String timeZone) + { + this.timeZone = timeZone; + return this; + } + public TimeSeriesProfileParser.Builder withTimeField(int field) + { + this.timeField = field; + return this; + } + public TimeSeriesProfileParser.Builder withTimeInTwoFields(boolean timeInTwoFields) + { + this.timeInTwoFields = timeInTwoFields; + return this; + } + public TimeSeriesProfileParser.Builder withParameterInfoList(List parameterInfoList) + { + this.parameterInfo =parameterInfoList; + return this; + } + + public TimeSeriesProfileParser.Builder withOfficeId(String officeId) { + this.officeId = officeId; + return this; + } + + + public TimeSeriesProfileParser build() { + return new TimeSeriesProfileParser(this); + } + } + +} From 994c9084bdb54138701f4e21ba4fa90f0b7c581b Mon Sep 17 00:00:00 2001 From: Andreas Christmann Date: Wed, 19 Jun 2024 15:11:13 -0700 Subject: [PATCH 07/26] time series profile dao's --- .../TimeSeriesProfileDao.java | 48 +++++++++++++++++++ .../TimeSeriesProfileInstanceDao.java | 21 ++++++++ 2 files changed, 69 insertions(+) create mode 100644 cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileDao.java create mode 100644 cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDao.java diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileDao.java b/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileDao.java new file mode 100644 index 000000000..a44a6d565 --- /dev/null +++ b/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileDao.java @@ -0,0 +1,48 @@ +package cwms.cda.data.dao.timeseriesprofile; + +import java.util.List; + +import cwms.cda.data.dao.JooqDao; +import cwms.cda.data.dto.timeseriesprofile.TimeSeriesProfile; +import org.jooq.DSLContext; +import org.jooq.impl.DSL; + +import usace.cwms.db.jooq.codegen.packages.CWMS_TS_PROFILE_PACKAGE; + +public class TimeSeriesProfileDao extends JooqDao +{ + public TimeSeriesProfileDao(DSLContext dsl) + { + super(dsl); + } + public void storeTimeSeriesProfile(TimeSeriesProfile timeSeriesProfile, boolean failIfExists) { + + connection(dsl, conn -> { + List parameterList = timeSeriesProfile.getParameterList(); + String parameterString = parameterList.get(0); + for(int i=1; i Date: Wed, 19 Jun 2024 15:15:54 -0700 Subject: [PATCH 08/26] time series profile dto's unit test --- .../timeseriesprofile/ParameterInfoTest.java | 5 ++ .../TimeSeriesProfileInstanceTest.java | 5 ++ .../TimeSeriesProfileParserTest.java | 61 +++++++++++++++ .../TimeSeriesProfileTest.java | 74 +++++++++++++++++++ 4 files changed, 145 insertions(+) create mode 100644 cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfoTest.java create mode 100644 cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstanceTest.java create mode 100644 cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserTest.java create mode 100644 cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileTest.java diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfoTest.java b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfoTest.java new file mode 100644 index 000000000..7de1adaca --- /dev/null +++ b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfoTest.java @@ -0,0 +1,5 @@ +package cwms.cda.data.dto.timeseriesprofile; + +public class ParameterInfoTest +{ +} diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstanceTest.java b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstanceTest.java new file mode 100644 index 000000000..bb05555cd --- /dev/null +++ b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstanceTest.java @@ -0,0 +1,5 @@ +package cwms.cda.data.dto.timeseriesprofile; + +public class TimeSeriesProfileInstanceTest +{ +} diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserTest.java b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserTest.java new file mode 100644 index 000000000..a59003f7f --- /dev/null +++ b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserTest.java @@ -0,0 +1,61 @@ +package cwms.cda.data.dto.timeseriesprofile; + +import java.util.ArrayList; +import java.util.List; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import cwms.cda.formatters.ContentType; +import cwms.cda.formatters.Formats; +import cwms.cda.formatters.json.JsonV2; +import fixtures.CwmsDataApiSetupCallback; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class TimeSeriesProfileParserTest +{ + @Test + void testTimeSeriesProfileSerializationRoundTrip() throws JsonProcessingException + { + TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser(); + ContentType contentType = Formats.parseHeader(Formats.JSONV2); + + ObjectMapper om = JsonV2.buildObjectMapper(); + String serializedLocation = om.writeValueAsString(timeSeriesProfileParser); + + String serialized = Formats.format(contentType, timeSeriesProfileParser); + TimeSeriesProfileParser deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2), serialized, TimeSeriesProfileParser.class); + assertEquals(timeSeriesProfileParser, deserialized, "Roundtrip serialization failed"); + assertEquals( timeSeriesProfileParser.hashCode(), deserialized.hashCode(), + "Roundtrip serialization failed"); + } + private static TimeSeriesProfileParser buildTestTimeSeriesProfileParser() { + List parameterInfo= new ArrayList<>(); + parameterInfo.add (new ParameterInfo.Builder() + .withParameter("Depth") + .withIndex(3) + .withUnit("m") + .build()); + parameterInfo.add (new ParameterInfo.Builder() + .withParameter("Temp-Water") + .withIndex(5) + .withUnit("F") + .build()); + return + + new TimeSeriesProfileParser.Builder() + .withOfficeId("SWT") + .withLocationId("TIMESERIESPROFILE_LOC") + .withKeyParameter("Depth") + .withRecordDelimiter((char) 10) + .withFieldDelimiter(',') + .withTimeFormat("MM/DD/YYYY,HH24:MI:SS") + .withTimeZone("UTC") + .withTimeField(1) + .withTimeInTwoFields(false) + .withParameterInfoList(parameterInfo) + .build(); + } + +} diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileTest.java b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileTest.java new file mode 100644 index 000000000..c5520bf73 --- /dev/null +++ b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileTest.java @@ -0,0 +1,74 @@ +package cwms.cda.data.dto.timeseriesprofile; + +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; + +import cwms.cda.formatters.ContentType; +import cwms.cda.formatters.Formats; +import org.apache.commons.io.IOUtils; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +final class TimeSeriesProfileTest +{ + @Test + void testTimeSeriesProfileSerializationRoundTrip() { + TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile(); + ContentType contentType = Formats.parseHeader(Formats.JSONV2); + String serialized = Formats.format(contentType, timeSeriesProfile); + TimeSeriesProfile deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2), serialized, TimeSeriesProfile.class); + assertEquals(timeSeriesProfile, deserialized, "Roundtrip serialization failed"); + assertEquals(timeSeriesProfile.hashCode(), deserialized.hashCode(), "Roundtrip serialization failed"); + } + + @Test + void testTimeSeriesProfileSerializationRoundTripFromFile() throws Exception { + TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile(); + InputStream resource = this.getClass().getResourceAsStream("/cwms/cda/data/dto/timeseriesprofile/timeseriesprofile.json"); + assertNotNull(resource); + String serialized = IOUtils.toString(resource, StandardCharsets.UTF_8); + TimeSeriesProfile deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2), serialized, TimeSeriesProfile.class); + assertEquals(timeSeriesProfile, deserialized, "Roundtrip serialization failed"); + } + +// @Test +// void testValidate() { +// Location location = buildTestLocation(); +// String projectId = "project"; +// assertAll(() -> { +// Embankment embankment = new Embankment.Builder().build(); +// assertThrows(FieldException.class, embankment::validate, +// "Expected validate() to throw FieldException because Location field can't be null, but it didn't"); +// }, () -> { +// Embankment embankment = new Embankment.Builder().withLocation(location).build(); +// assertThrows(FieldException.class, embankment::validate, +// "Expected validate() to throw FieldException because Project Id field can't be null, but it didn't"); +// }, () -> { +// Embankment embankment = new Embankment.Builder().withLocation(location).withProjectId(projectId).build(); +// assertThrows(FieldException.class, embankment::validate, +// "Expected validate() to throw FieldException because Project Office Id field can't be null, but it didn't"); +// }, () -> { +// Embankment embankment = new Embankment.Builder().withLocation(location).withProjectId(projectId).withProjectOfficeId("SPK").build(); +// assertThrows(FieldException.class, embankment::validate, +// "Expected validate() to throw FieldException because Structure type field can't be null, but it didn't"); +// } +// ); +// } + + private TimeSeriesProfile buildTestTimeSeriesProfile() { + return new TimeSeriesProfile.Builder() + .withOfficeId("Office") + .withKeyParameter("Depth") + .withRefTsId("TimeSeries") + .withLocationId("Location") + .withDescription("Description") + .withParameterList(Arrays.asList(new String[]{"Temperature", "Depth"})) + .build(); + } + +} From 8fbcb4e7b92fdf36207711a242880e0ee78f7a75 Mon Sep 17 00:00:00 2001 From: Andreas Christmann Date: Wed, 19 Jun 2024 15:17:02 -0700 Subject: [PATCH 09/26] time series profile dao integration test --- .../TimeSeriesProfileParserDaoIT.java | 183 ++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDaoIT.java diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDaoIT.java b/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDaoIT.java new file mode 100644 index 000000000..a499ae723 --- /dev/null +++ b/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDaoIT.java @@ -0,0 +1,183 @@ +package cwms.cda.data.dao.timeseriesprofile; + +import java.io.IOException; +import java.sql.SQLException; +import java.time.ZoneId; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import cwms.cda.api.DataApiTestIT; +import cwms.cda.api.enums.Nation; +import cwms.cda.data.dao.LocationsDaoImpl; +import cwms.cda.data.dto.Location; +import cwms.cda.data.dto.timeseriesprofile.ParameterInfo; +import cwms.cda.data.dto.timeseriesprofile.TimeSeriesProfile; +import cwms.cda.data.dto.timeseriesprofile.TimeSeriesProfileParser; +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 static cwms.cda.data.dao.DaoTest.getDslContext; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertThrowsExactly; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@Tag("integration") +final class TimeSeriesProfileParserDaoIT extends DataApiTestIT +{ + private static final Location TIMESERIESPORFILE_LOC = buildTestLocation(); + + @BeforeAll + public static void setup() throws Exception + { + CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); + databaseLink.connection(c -> { + DSLContext context = getDslContext(c, databaseLink.getOfficeId()); + LocationsDaoImpl locationsDao = new LocationsDaoImpl(context); + try + { + locationsDao.storeLocation(TIMESERIESPORFILE_LOC); + } + catch(IOException e) + { + throw new RuntimeException(e); + } + }); + } + + @AfterAll + public static void tearDown() throws Exception { + + CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); + databaseLink.connection(c -> { + DSLContext context = getDslContext(c, databaseLink.getOfficeId()); + LocationsDaoImpl locationsDao = new LocationsDaoImpl(context); + locationsDao.deleteLocation(TIMESERIESPORFILE_LOC.getName(), databaseLink.getOfficeId()); + }); + } + + @Test + void testStoreAndRetrieve() throws Exception { + CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); + databaseLink.connection(c -> { + DSLContext context = getDslContext(c, databaseLink.getOfficeId()); + + TimeSeriesProfileDao timeSeriesProfileDao = new TimeSeriesProfileDao(context); + + TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile(); + timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfile, false); + + TimeSeriesProfileParserDao timeSeriesProfileParserDao = new TimeSeriesProfileParserDao(context); + TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser(); + timeSeriesProfileParserDao.storeTimeSeriesProfileParser(timeSeriesProfileParser, false); + + TimeSeriesProfileParser retrieved = timeSeriesProfileParserDao.retrieveTimeSeriesProfileParser(timeSeriesProfileParser.getLocationId(), + timeSeriesProfileParser.getKeyParameter(), timeSeriesProfileParser.getOfficeId()); + assertEquals(timeSeriesProfileParser, retrieved); + + timeSeriesProfileParserDao.deleteTimeSeriesProfileParser(timeSeriesProfileParser.getLocationId(), + timeSeriesProfileParser.getKeyParameter(), timeSeriesProfileParser.getOfficeId()); + }); + } + + @Test + void testStoreAndDelete() throws SQLException + { + CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); + databaseLink.connection(c -> { + DSLContext context = getDslContext(c, databaseLink.getOfficeId()); + + TimeSeriesProfileDao timeSeriesProfileDao = new TimeSeriesProfileDao(context); + + TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile(); + timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfile, false); + + TimeSeriesProfileParserDao timeSeriesProfileParserDao = new TimeSeriesProfileParserDao(context); + TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser(); + timeSeriesProfileParserDao.storeTimeSeriesProfileParser(timeSeriesProfileParser, false); + + timeSeriesProfileParserDao.deleteTimeSeriesProfileParser(timeSeriesProfileParser.getLocationId(), + timeSeriesProfileParser.getKeyParameter(), timeSeriesProfileParser.getOfficeId()); + + assertThrows(Exception.class, ()->timeSeriesProfileParserDao.retrieveTimeSeriesProfileParser( + timeSeriesProfileParser.getLocationId(), + timeSeriesProfileParser.getKeyParameter(), timeSeriesProfileParser.getOfficeId())); + + }); + } + + @Test + void testStoreAndRetrieveMultiple() + { + // TODO + } + @Test + void testStoreAndCopy() + { + // TODO + } + private static TimeSeriesProfile buildTestTimeSeriesProfile() + { + String officeId = CwmsDataApiSetupCallback.getDatabaseLink().getOfficeId(); + return new TimeSeriesProfile.Builder() + .withOfficeId(officeId) + .withLocationId("TIMESERIESPROFILE_LOC") + .withKeyParameter("Depth") + .withParameterList(Arrays.asList(new String[]{"Pres", "Depth"})) + .build(); + + } + private static TimeSeriesProfileParser buildTestTimeSeriesProfileParser() { + List parameterInfoList = new ArrayList<>(); + parameterInfoList.add( new ParameterInfo.Builder() + .withParameter("Depth") + .withIndex(3) + .withUnit("m") + .build()); + parameterInfoList.add( new ParameterInfo.Builder() + .withParameter("Temp-Water") + .withIndex(4) + .withUnit("F") + .build()); + + String officeId = CwmsDataApiSetupCallback.getDatabaseLink().getOfficeId(); + return + + new TimeSeriesProfileParser.Builder() + .withOfficeId(officeId) + .withLocationId("TIMESERIESPROFILE_LOC") + .withKeyParameter("Depth") + .withRecordDelimiter((char) 10) + .withFieldDelimiter(',') + .withTimeFormat("MM/DD/YYYY,HH24:MI:SS") + .withTimeZone("UTC") + .withTimeField(1) + .withTimeInTwoFields(false) + .withParameterInfoList(parameterInfoList) + .build(); + } + + private static Location buildTestLocation() { + String officeId = CwmsDataApiSetupCallback.getDatabaseLink().getOfficeId(); + return new Location.Builder("TIMESERIESPROFILE_LOC", "SITE", ZoneId.of("UTC"), + 38.5613824, -121.7298432, "NVGD29", officeId) + .withElevation(10.0) + .withLocationType("SITE") + .withCountyName("Sacramento") + .withNation(Nation.US) + .withActive(true) + .withStateInitial("CA") + .withBoundingOfficeId(officeId) + .withPublishedLatitude(38.5613824) + .withPublishedLongitude(-121.7298432) + .withLongName("UNITED STATES") + .withDescription("for testing") + .build(); + } +} From 814dd5469e0cb72a2922fa1e82ce3959e75548fd Mon Sep 17 00:00:00 2001 From: Andreas Christmann Date: Thu, 20 Jun 2024 12:32:33 -0700 Subject: [PATCH 10/26] time series profile unit test --- .../TimeSeriesProfileTest.java | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileTest.java b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileTest.java index c5520bf73..91568871b 100644 --- a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileTest.java +++ b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileTest.java @@ -36,30 +36,6 @@ void testTimeSeriesProfileSerializationRoundTripFromFile() throws Exception { assertEquals(timeSeriesProfile, deserialized, "Roundtrip serialization failed"); } -// @Test -// void testValidate() { -// Location location = buildTestLocation(); -// String projectId = "project"; -// assertAll(() -> { -// Embankment embankment = new Embankment.Builder().build(); -// assertThrows(FieldException.class, embankment::validate, -// "Expected validate() to throw FieldException because Location field can't be null, but it didn't"); -// }, () -> { -// Embankment embankment = new Embankment.Builder().withLocation(location).build(); -// assertThrows(FieldException.class, embankment::validate, -// "Expected validate() to throw FieldException because Project Id field can't be null, but it didn't"); -// }, () -> { -// Embankment embankment = new Embankment.Builder().withLocation(location).withProjectId(projectId).build(); -// assertThrows(FieldException.class, embankment::validate, -// "Expected validate() to throw FieldException because Project Office Id field can't be null, but it didn't"); -// }, () -> { -// Embankment embankment = new Embankment.Builder().withLocation(location).withProjectId(projectId).withProjectOfficeId("SPK").build(); -// assertThrows(FieldException.class, embankment::validate, -// "Expected validate() to throw FieldException because Structure type field can't be null, but it didn't"); -// } -// ); -// } - private TimeSeriesProfile buildTestTimeSeriesProfile() { return new TimeSeriesProfile.Builder() .withOfficeId("Office") From 5c8ed92d20adb1bcb955e23d3cb85f4eda9af280 Mon Sep 17 00:00:00 2001 From: Andreas Christmann Date: Fri, 21 Jun 2024 12:55:35 -0700 Subject: [PATCH 11/26] added db cleanup --- .../TimeSeriesProfileDaoIT.java | 182 ++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileDaoIT.java diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileDaoIT.java b/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileDaoIT.java new file mode 100644 index 000000000..e76b22627 --- /dev/null +++ b/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileDaoIT.java @@ -0,0 +1,182 @@ +package cwms.cda.data.dao.timeseriesprofile; + +import java.io.IOException; +import java.sql.SQLException; +import java.time.ZoneId; +import java.util.Arrays; +import java.util.List; + +import cwms.cda.api.DataApiTestIT; +import cwms.cda.api.enums.Nation; +import cwms.cda.data.dao.LocationsDaoImpl; +import cwms.cda.data.dto.Location; +import cwms.cda.data.dto.timeseriesprofile.TimeSeriesProfile; +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 static cwms.cda.data.dao.DaoTest.getDslContext; +import static org.junit.jupiter.api.Assertions.assertEquals; + +@Tag("integration") +public class TimeSeriesProfileDaoIT extends DataApiTestIT +{ + private static final Location LOCATION_AAA = buildTestLocation("AAA"); + private static final Location TIMESERIESPROFILE_LOC = buildTestLocation("TIMESERIESPROFILE_LOC"); + @BeforeAll + public static void setup() throws Exception + { + CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); + databaseLink.connection(c -> { + DSLContext context = getDslContext(c, databaseLink.getOfficeId()); + LocationsDaoImpl locationsDao = new LocationsDaoImpl(context); + try + { + locationsDao.storeLocation(LOCATION_AAA); + locationsDao.storeLocation(TIMESERIESPROFILE_LOC); + } + catch(IOException e) + { + throw new RuntimeException(e); + } + }); + } + + @AfterAll + public static void tearDown() throws Exception { + + CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); + databaseLink.connection(c -> { + DSLContext context = getDslContext(c, databaseLink.getOfficeId()); + LocationsDaoImpl locationsDao = new LocationsDaoImpl(context); + locationsDao.deleteLocation(LOCATION_AAA.getName(), LOCATION_AAA.getOfficeId()); + locationsDao.deleteLocation(TIMESERIESPROFILE_LOC.getName(), TIMESERIESPROFILE_LOC.getOfficeId()); + }); + } + + @Test + void testCopyTimeSeriesProfile() throws SQLException + { + CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); + databaseLink.connection(c -> { + DSLContext context = getDslContext(c, databaseLink.getOfficeId()); + + TimeSeriesProfileDao timeSeriesProfileDao = new TimeSeriesProfileDao(context); + + TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile("Depth"); + + timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfile, false); + timeSeriesProfileDao.copyTimeSeriesProfile(timeSeriesProfile.getLocationId(), timeSeriesProfile.getKeyParameter(), + "AAA","",timeSeriesProfile.getOfficeId()); + TimeSeriesProfile timeSeriesProfileCopied = timeSeriesProfileDao.retrieveTimeSeriesProfile("AAA", + timeSeriesProfile.getKeyParameter(), timeSeriesProfile.getOfficeId()); + assertEquals("AAA", timeSeriesProfileCopied.getLocationId()); + assertEquals(timeSeriesProfile.getKeyParameter(), timeSeriesProfileCopied.getKeyParameter()); + assertEquals(timeSeriesProfile.getParameterList(),timeSeriesProfileCopied.getParameterList()); + + timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfile.getLocationId(),timeSeriesProfile.getKeyParameter(),timeSeriesProfile.getOfficeId()); + timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfileCopied.getLocationId(),timeSeriesProfileCopied.getKeyParameter(),timeSeriesProfileCopied.getOfficeId()); + }); + } + @Test + void testRetrieveTimeSeriesProfile() throws Exception { + CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); + databaseLink.connection(c -> { + DSLContext context = getDslContext(c, databaseLink.getOfficeId()); + + TimeSeriesProfileDao timeSeriesProfileDao = new TimeSeriesProfileDao(context); + + TimeSeriesProfile timeSeriesProfileIn = (buildTestTimeSeriesProfile("Depth")); + timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfileIn, false); + + TimeSeriesProfile timeSeriesProfileOut = timeSeriesProfileDao.retrieveTimeSeriesProfile(timeSeriesProfileIn.getLocationId(), + timeSeriesProfileIn.getKeyParameter(), timeSeriesProfileIn.getOfficeId()); + + assertEquals(timeSeriesProfileOut, timeSeriesProfileIn); + + timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfileIn.getLocationId(), + timeSeriesProfileIn.getKeyParameter(), timeSeriesProfileIn.getOfficeId()); + }); + } + + @Test + void testRetrieveCatalog() throws Exception { + CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); + databaseLink.connection(c -> { + DSLContext context = getDslContext(c, databaseLink.getOfficeId()); + + TimeSeriesProfileDao timeSeriesProfileDao = new TimeSeriesProfileDao(context); + timeSeriesProfileDao.storeTimeSeriesProfile(buildTestTimeSeriesProfile("Depth"), false); + timeSeriesProfileDao.storeTimeSeriesProfile(buildTestTimeSeriesProfile("Pres"), false); + + + List timeSeriesProfileListBefore = + timeSeriesProfileDao.retrieveTimeSeriesProfiles("*", "*", "*"); + + for(TimeSeriesProfile timeSeriesProfile: timeSeriesProfileListBefore) + { + timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfile.getLocationId(), timeSeriesProfile.getKeyParameter(), + timeSeriesProfile.getOfficeId()); + } + List timeSeriesProfileListAfter = timeSeriesProfileDao.retrieveTimeSeriesProfiles("*", "*", "*"); + + assertEquals(0,timeSeriesProfileListAfter.size()); + assertEquals(2,timeSeriesProfileListBefore.size()); + }); + } + @Test + void testDeleteTimeSeriesProfile() throws Exception { + CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); + databaseLink.connection(c -> { + DSLContext context = getDslContext(c, databaseLink.getOfficeId()); + + TimeSeriesProfileDao timeSeriesProfileDao = new TimeSeriesProfileDao(context); + TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile("Depth"); + timeSeriesProfileDao.storeTimeSeriesProfile(buildTestTimeSeriesProfile("Depth"), false); + + List timeSeriesProfileListBefore = + timeSeriesProfileDao.retrieveTimeSeriesProfiles("*", "*", "*"); + + timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfile.getLocationId(), timeSeriesProfile.getKeyParameter(), + timeSeriesProfile.getOfficeId()); + + List timeSeriesProfileListAfter = + timeSeriesProfileDao.retrieveTimeSeriesProfiles("*", "*", "*"); + + + assertEquals(timeSeriesProfileListBefore.size()-1,timeSeriesProfileListAfter.size()); + }); + } + private static Location buildTestLocation(String location) { + String officeId = CwmsDataApiSetupCallback.getDatabaseLink().getOfficeId(); + return new Location.Builder(location, "SITE", ZoneId.of("UTC"), + 38.5613824, -121.7298432, "NVGD29", officeId) + .withElevation(10.0) + .withLocationType("SITE") + .withCountyName("Sacramento") + .withNation(Nation.US) + .withActive(true) + .withStateInitial("CA") + .withBoundingOfficeId(officeId) + .withPublishedLatitude(38.5613824) + .withPublishedLongitude(-121.7298432) + .withLongName("UNITED STATES") + .withDescription("for testing") + .build(); + } + private static TimeSeriesProfile buildTestTimeSeriesProfile(String keyParameter) + { + String officeId = CwmsDataApiSetupCallback.getDatabaseLink().getOfficeId(); + return new TimeSeriesProfile.Builder() + .withOfficeId(officeId) + .withLocationId("TIMESERIESPROFILE_LOC") + .withKeyParameter(keyParameter) + .withParameterList(Arrays.asList("Pres", "Depth")) + .build(); + + } +} From a1aead4ff74d8c697e4939d7556bd426d8de5cd8 Mon Sep 17 00:00:00 2001 From: Andreas Christmann Date: Tue, 25 Jun 2024 14:46:33 -0700 Subject: [PATCH 12/26] moved equals to test classes and removed hashcode --- .../timeseriesprofile/TimeSeriesProfile.java | 31 +--------- .../TimeSeriesProfileParser.java | 61 ++++--------------- .../TimeSeriesProfileParserTest.java | 45 +++++++++----- .../TimeSeriesProfileTest.java | 17 +++--- .../timeseriesprofileparser.json | 6 +- 5 files changed, 59 insertions(+), 101 deletions(-) diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfile.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfile.java index 16805ff59..30f89f170 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfile.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfile.java @@ -2,7 +2,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.Objects; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.PropertyNamingStrategies; @@ -23,6 +22,7 @@ public final class TimeSeriesProfile extends CwmsDTO { @Schema(description = "Location ID") + // TODO replace with CWMSID private final String locationId; @Schema(description = "Description") private final String description; @@ -31,6 +31,7 @@ public final class TimeSeriesProfile extends CwmsDTO @Schema(description = "Key Parameter") private final String keyParameter; @Schema(description = "Reference TS") + // TODO replace with CWMSID private final String refTsId; private TimeSeriesProfile(Builder builder) @@ -89,34 +90,6 @@ public void validate() throws FieldException } } - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - TimeSeriesProfile that = (TimeSeriesProfile) o; - return Objects.equals(getLocationId(), that.getLocationId()) - && Objects.equals(getOfficeId(), that.getOfficeId()) - && Objects.equals(getDescription(), that.getDescription()) - && Objects.equals(getKeyParameter(), that.getKeyParameter()) - && Objects.equals(getRefTsId(), that.getRefTsId()) - && Objects.equals(getParameterList(), that.getParameterList()) - ; - } - @Override - public int hashCode() { - int result = Objects.hashCode(getDescription()); - result = 31 * result + Objects.hashCode(getKeyParameter()); - result = 31 * result + Objects.hashCode(getLocationId()); - result = 31 * result + Objects.hashCode(getParameterList()); - result = 31 * result + Objects.hashCode(getOfficeId()); - result = 31 * result + Objects.hashCode(getRefTsId()); - return result; - } @JsonPOJOBuilder @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) public static final class Builder { diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParser.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParser.java index 19532bb72..b9774a380 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParser.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParser.java @@ -2,8 +2,6 @@ import java.math.BigInteger; import java.util.List; -import java.util.Objects; - import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.PropertyNamingStrategies; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; @@ -28,7 +26,7 @@ public class TimeSeriesProfileParser extends CwmsDTO private final String timeFormat; private final String timeZone; private final int timeField; - private final List parameterInfo; + private final List parameterInfoList; private final boolean timeInTwoFields; protected TimeSeriesProfileParser(Builder builder) { @@ -40,14 +38,16 @@ protected TimeSeriesProfileParser(Builder builder) timeFormat = builder.timeFormat; timeZone = builder.timeZone; timeField = builder.timeField; - parameterInfo = builder.parameterInfo; + parameterInfoList = builder.parameterInfoList; timeInTwoFields = builder.timeInTwoFields; } @Override public void validate() throws FieldException { - + if (this.keyParameter == null) { + throw new FieldException("Key Parameter field can't be null"); + } } @@ -60,11 +60,11 @@ public String getKeyParameter() { return keyParameter; } - public String getRecordDelimiter(){ return String.valueOf(recordDelimiter); } - public String getFieldDelimiter(){ return String.valueOf(fieldDelimiter); } - public List getParameterInfo () + public char getRecordDelimiter(){ return recordDelimiter; } + public char getFieldDelimiter(){ return fieldDelimiter; } + public List getParameterInfoList () { - return parameterInfo; + return parameterInfoList; } public String getTimeFormat() @@ -82,52 +82,17 @@ public BigInteger getTimeField() return BigInteger.valueOf(timeField); } - public String getTimeInTwoFields() + public boolean getTimeInTwoFields() { - return timeInTwoFields?"T":"F"; - } - - @Override - public int hashCode() { - int result = Objects.hashCode(getLocationId()); - result = 31 * result + Objects.hashCode(getFieldDelimiter()); - result = 31 * result + Objects.hashCode(getOfficeId()); - result = 31 * result + Objects.hashCode(getKeyParameter()); - result = 31 * result + Objects.hashCode(getTimeField()); - result = 31 * result + Objects.hashCode(getTimeFormat()); - result = 31 * result + Objects.hashCode(getParameterInfo()); - result = 31 * result + Objects.hashCode(getRecordDelimiter()); - result = 31 * result + Objects.hashCode(getTimeZone()); - result = 31 * result + Objects.hashCode(getTimeInTwoFields()); - return result; + return timeInTwoFields; } - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - TimeSeriesProfileParser that = (TimeSeriesProfileParser) o; - return Objects.equals(getLocationId(), that.getLocationId()) - && Objects.equals(getFieldDelimiter(), that.getFieldDelimiter()) - && Objects.equals(getOfficeId(), that.getOfficeId()) - && Objects.equals(getKeyParameter(), that.getKeyParameter()) - && Objects.equals(getTimeField(), that.getTimeField()) - && Objects.equals(getTimeFormat(), that.getTimeFormat()) - && Objects.equals(getParameterInfo(), that.getParameterInfo()) - && Objects.equals(getRecordDelimiter(), that.getRecordDelimiter()) - && Objects.equals(getTimeZone(), that.getTimeZone()) - && Objects.equals(getTimeInTwoFields(), that.getTimeInTwoFields()); - } @JsonPOJOBuilder @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) public static final class Builder { private String officeId; - private List parameterInfo; + private List parameterInfoList; private String keyParameter; private char recordDelimiter; private char fieldDelimiter; @@ -176,7 +141,7 @@ public TimeSeriesProfileParser.Builder withTimeInTwoFields(boolean timeInTwoFiel } public TimeSeriesProfileParser.Builder withParameterInfoList(List parameterInfoList) { - this.parameterInfo =parameterInfoList; + this.parameterInfoList =parameterInfoList; return this; } diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserTest.java b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserTest.java index a59003f7f..ab1c514c4 100644 --- a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserTest.java +++ b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserTest.java @@ -1,34 +1,39 @@ package cwms.cda.data.dto.timeseriesprofile; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import cwms.cda.formatters.ContentType; import cwms.cda.formatters.Formats; -import cwms.cda.formatters.json.JsonV2; -import fixtures.CwmsDataApiSetupCallback; +import org.apache.commons.io.IOUtils; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; -public class TimeSeriesProfileParserTest +final class TimeSeriesProfileParserTest { @Test - void testTimeSeriesProfileSerializationRoundTrip() throws JsonProcessingException + void testTimeSeriesProfileSerializationRoundTrip() { TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser(); ContentType contentType = Formats.parseHeader(Formats.JSONV2); - ObjectMapper om = JsonV2.buildObjectMapper(); - String serializedLocation = om.writeValueAsString(timeSeriesProfileParser); - String serialized = Formats.format(contentType, timeSeriesProfileParser); TimeSeriesProfileParser deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2), serialized, TimeSeriesProfileParser.class); - assertEquals(timeSeriesProfileParser, deserialized, "Roundtrip serialization failed"); - assertEquals( timeSeriesProfileParser.hashCode(), deserialized.hashCode(), - "Roundtrip serialization failed"); + testAssertEquals(timeSeriesProfileParser, deserialized, "Roundtrip serialization failed"); + } + + @Test + void testTimeSeriesProfileSerializationRoundTripFromFile() throws Exception { + TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser(); + InputStream resource = this.getClass().getResourceAsStream("/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileparser.json"); + assertNotNull(resource); + String serialized = IOUtils.toString(resource, StandardCharsets.UTF_8); + TimeSeriesProfileParser deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2), serialized, TimeSeriesProfileParser.class); + testAssertEquals(timeSeriesProfileParser, deserialized, "Roundtrip serialization from file failed"); } private static TimeSeriesProfileParser buildTestTimeSeriesProfileParser() { List parameterInfo= new ArrayList<>(); @@ -46,7 +51,7 @@ private static TimeSeriesProfileParser buildTestTimeSeriesProfileParser() { new TimeSeriesProfileParser.Builder() .withOfficeId("SWT") - .withLocationId("TIMESERIESPROFILE_LOC") + .withLocationId("location") .withKeyParameter("Depth") .withRecordDelimiter((char) 10) .withFieldDelimiter(',') @@ -57,5 +62,17 @@ private static TimeSeriesProfileParser buildTestTimeSeriesProfileParser() { .withParameterInfoList(parameterInfo) .build(); } - + private void testAssertEquals(TimeSeriesProfileParser expected, TimeSeriesProfileParser actual, String message) + { + assertEquals(expected.getLocationId(), actual.getLocationId(), message); + assertEquals(expected.getFieldDelimiter(), actual.getFieldDelimiter(), message); + assertEquals(expected.getOfficeId(), actual.getOfficeId(), message); + assertEquals(expected.getKeyParameter(), actual.getKeyParameter(), message); + assertEquals(expected.getTimeField(), actual.getTimeField(), message); + assertEquals(expected.getTimeFormat(), actual.getTimeFormat(), message); + // assertEquals(expected.getParameterInfo(), actual.getParameterInfo(),message); + assertEquals(expected.getRecordDelimiter(), actual.getRecordDelimiter(), message); + assertEquals(expected.getTimeZone(), actual.getTimeZone()); + assertEquals(expected.getTimeInTwoFields(), actual.getTimeInTwoFields()); + } } diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileTest.java b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileTest.java index 91568871b..a8825e05e 100644 --- a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileTest.java +++ b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileTest.java @@ -9,10 +9,8 @@ import org.apache.commons.io.IOUtils; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; final class TimeSeriesProfileTest { @@ -22,8 +20,7 @@ void testTimeSeriesProfileSerializationRoundTrip() { ContentType contentType = Formats.parseHeader(Formats.JSONV2); String serialized = Formats.format(contentType, timeSeriesProfile); TimeSeriesProfile deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2), serialized, TimeSeriesProfile.class); - assertEquals(timeSeriesProfile, deserialized, "Roundtrip serialization failed"); - assertEquals(timeSeriesProfile.hashCode(), deserialized.hashCode(), "Roundtrip serialization failed"); + testAssertEquals(timeSeriesProfile, deserialized, "Roundtrip serialization failed"); } @Test @@ -33,7 +30,7 @@ void testTimeSeriesProfileSerializationRoundTripFromFile() throws Exception { assertNotNull(resource); String serialized = IOUtils.toString(resource, StandardCharsets.UTF_8); TimeSeriesProfile deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2), serialized, TimeSeriesProfile.class); - assertEquals(timeSeriesProfile, deserialized, "Roundtrip serialization failed"); + testAssertEquals(timeSeriesProfile, deserialized, "Roundtrip serialization from file failed"); } private TimeSeriesProfile buildTestTimeSeriesProfile() { @@ -43,8 +40,14 @@ private TimeSeriesProfile buildTestTimeSeriesProfile() { .withRefTsId("TimeSeries") .withLocationId("Location") .withDescription("Description") - .withParameterList(Arrays.asList(new String[]{"Temperature", "Depth"})) + .withParameterList(Arrays.asList("Temperature", "Depth")) .build(); } - + private void testAssertEquals(TimeSeriesProfile expected, TimeSeriesProfile actual, String message) { + assertEquals(expected.getLocationId(), actual.getLocationId(), message); + assertEquals(expected.getDescription(), actual.getDescription(), message); + assertEquals(expected.getParameterList(), actual.getParameterList(), message); + assertEquals(expected.getKeyParameter(), actual.getKeyParameter(), message); + assertEquals(expected.getRefTsId(), actual.getRefTsId(), message); + } } diff --git a/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileparser.json b/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileparser.json index 7ca2c30e3..4a907c4bb 100644 --- a/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileparser.json +++ b/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileparser.json @@ -1,14 +1,14 @@ { "office-id": "SWT", - "location-id": "TIMESERIESPROFILE_LOC", + "location-id": "location", "key-parameter": "Depth", "record-delimiter": "\n", "field-delimiter": ",", "time-format": "MM/DD/YYYY,HH24:MI:SS", "time-zone": "UTC", "time-field": 1, - "time-in-two-fields": "F", - "parameter-info": [ + "time-in-two-fields": false, + "parameter-info-list": [ { "parameter":"Depth", "unit":"m", From 3d5ddcef7ca09684c4a0ddddb57d5f81ad812579 Mon Sep 17 00:00:00 2001 From: Andreas Christmann Date: Wed, 26 Jun 2024 12:00:33 -0700 Subject: [PATCH 13/26] reformatted code --- .../dto/timeseriesprofile/ParameterInfo.java | 156 +++++----- .../timeseriesprofile/TimeSeriesProfile.java | 223 +++++++------- .../TimeSeriesProfileInstance.java | 17 +- .../TimeSeriesProfileParser.java | 277 +++++++++--------- .../timeseriesprofile/ParameterInfoTest.java | 3 +- .../TimeSeriesProfileInstanceTest.java | 3 +- .../TimeSeriesProfileParserTest.java | 117 ++++---- .../TimeSeriesProfileTest.java | 72 ++--- 8 files changed, 429 insertions(+), 439 deletions(-) diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfo.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfo.java index 02640b45d..819aa2b9a 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfo.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfo.java @@ -17,80 +17,84 @@ @JsonDeserialize(builder = ParameterInfo.Builder.class) @JsonInclude(JsonInclude.Include.NON_NULL) @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) -public class ParameterInfo implements CwmsDTOBase -{ - private final String parameter; - private final String unit; - private final int index; - protected ParameterInfo(ParameterInfo.Builder builder) - { - parameter= builder.parameter; - unit = builder.unit; - index = builder.index; - } - public String getParameter() - { - return parameter; - } - public String getUnit() - { - return unit; - } - - public int getIndex(){ return index; } - - - @Override - public void validate() throws FieldException - { - - } - @Override - public int hashCode() { - int result = Objects.hashCode(getParameter()); - result = 31 * result + Objects.hashCode(getUnit()); - result = 31 * result + Objects.hashCode(getIndex()); - return result; - }@Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - ParameterInfo that = (ParameterInfo) o; - return Objects.equals(getParameter(), that.getParameter()) - && Objects.equals(getUnit(), that.getUnit()) - && Objects.equals(getIndex(), that.getIndex()); - } - @JsonPOJOBuilder - @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) - public static final class Builder - { - private String parameter; - private String unit; - private int index; - - - public ParameterInfo.Builder withParameter(String parameter) { - this.parameter = parameter; - return this; - } - public ParameterInfo.Builder withUnit(String unit) { - this.unit = unit; - return this; - } - public ParameterInfo.Builder withIndex(int index) - { - this.index = index; - return this; - } - - public ParameterInfo build() { - return new ParameterInfo(this); - } - - } +public class ParameterInfo implements CwmsDTOBase { + private final String parameter; + private final String unit; + private final int index; + + protected ParameterInfo(ParameterInfo.Builder builder) { + parameter = builder.parameter; + unit = builder.unit; + index = builder.index; + } + + public String getParameter() { + return parameter; + } + + public String getUnit() { + return unit; + } + + public int getIndex() { + return index; + } + + + @Override + public void validate() throws FieldException { + + } + + @Override + public int hashCode() { + int result = Objects.hashCode(getParameter()); + result = 31 * result + Objects.hashCode(getUnit()); + result = 31 * result + Objects.hashCode(getIndex()); + return result; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + ParameterInfo that = (ParameterInfo) o; + return Objects.equals(getParameter(), that.getParameter()) + && Objects.equals(getUnit(), that.getUnit()) + && Objects.equals(getIndex(), that.getIndex()); + } + + @JsonPOJOBuilder + @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) + public static final class Builder { + private String parameter; + private String unit; + private int index; + + + public ParameterInfo.Builder withParameter(String parameter) { + this.parameter = parameter; + return this; + } + + public ParameterInfo.Builder withUnit(String unit) { + this.unit = unit; + return this; + } + + public ParameterInfo.Builder withIndex(int index) { + this.index = index; + return this; + } + + public ParameterInfo build() { + return new ParameterInfo(this); + } + + } } \ No newline at end of file diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfile.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfile.java index 30f89f170..ec64f2212 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfile.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfile.java @@ -19,120 +19,111 @@ @JsonDeserialize(builder = TimeSeriesProfile.Builder.class) @JsonInclude(JsonInclude.Include.NON_NULL) @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) -public final class TimeSeriesProfile extends CwmsDTO -{ - @Schema(description = "Location ID") - // TODO replace with CWMSID - private final String locationId; - @Schema(description = "Description") - private final String description; - @Schema(description = "Parameter List") - private final List parameterList; - @Schema(description = "Key Parameter") - private final String keyParameter; - @Schema(description = "Reference TS") - // TODO replace with CWMSID - private final String refTsId; - - private TimeSeriesProfile(Builder builder) - { - super(builder.officeId); - this.locationId = builder.locationId; - this.description = builder.description; - this.keyParameter = builder.keyParameter; - this.parameterList = builder.parameterList; - this.refTsId = builder.refTsId; - } - - public String getLocationId() - { - return locationId; - } - - public String getDescription() - { - return description; - } - - public String getKeyParameter() - { - return keyParameter; - } - - public List getParameterList() - { - return parameterList!=null ? new ArrayList<>(parameterList) : null; - } - - public String getRefTsId() - { - return refTsId; - } - - @Override - public void validate() throws FieldException - { - if (this.parameterList == null) { - throw new FieldException("Parameter list field can't be null"); - } - if (this.keyParameter == null) { - throw new FieldException("Key Parameter field can't be null"); - } - if (this.officeId == null) { - throw new FieldException("Office Id field can't be null"); - } - if (this.locationId == null) { - throw new FieldException("Location Id field can't be null"); - } - if (!parameterList.contains(keyParameter)) - { - throw new FieldException("Key Parameter must be part of Parameter list"); - } - } - - @JsonPOJOBuilder - @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) - public static final class Builder { - private String officeId; - private List parameterList; - private String keyParameter; - private String description; - private String locationId; - private String refTsId; - - public TimeSeriesProfile.Builder withLocationId(String locationId) { - this.locationId = locationId; - return this; - } - - public TimeSeriesProfile.Builder withDescription(String description) { - this.description = description; - return this; - } - public TimeSeriesProfile.Builder withKeyParameter(String keyParameter) { - this.keyParameter = keyParameter; - return this; - } - - public TimeSeriesProfile.Builder withParameterList(List parameterList) - { - this.parameterList = parameterList!=null ? new ArrayList<>(parameterList) : null; - return this; - } - - public TimeSeriesProfile.Builder withOfficeId(String officeId) { - this.officeId = officeId; - return this; - } - - public TimeSeriesProfile.Builder withRefTsId(String refTsId) { - this.refTsId = refTsId; - return this; - } - - - public TimeSeriesProfile build() { - return new TimeSeriesProfile(this); - } - } +public final class TimeSeriesProfile extends CwmsDTO { + @Schema(description = "Location ID") + // TODO replace with CWMSID + private final String locationId; + @Schema(description = "Description") + private final String description; + @Schema(description = "Parameter List") + private final List parameterList; + @Schema(description = "Key Parameter") + private final String keyParameter; + @Schema(description = "Reference TS") + // TODO replace with CWMSID + private final String refTsId; + + private TimeSeriesProfile(Builder builder) { + super(builder.officeId); + this.locationId = builder.locationId; + this.description = builder.description; + this.keyParameter = builder.keyParameter; + this.parameterList = builder.parameterList; + this.refTsId = builder.refTsId; + } + + public String getLocationId() { + return locationId; + } + + public String getDescription() { + return description; + } + + public String getKeyParameter() { + return keyParameter; + } + + public List getParameterList() { + return parameterList != null ? new ArrayList<>(parameterList) : null; + } + + public String getRefTsId() { + return refTsId; + } + + @Override + public void validate() throws FieldException { + if (this.parameterList == null) { + throw new FieldException("Parameter list field can't be null"); + } + if (this.keyParameter == null) { + throw new FieldException("Key Parameter field can't be null"); + } + if (this.officeId == null) { + throw new FieldException("Office Id field can't be null"); + } + if (this.locationId == null) { + throw new FieldException("Location Id field can't be null"); + } + if (!parameterList.contains(keyParameter)) { + throw new FieldException("Key Parameter must be part of Parameter list"); + } + } + + @JsonPOJOBuilder + @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) + public static final class Builder { + private String officeId; + private List parameterList; + private String keyParameter; + private String description; + private String locationId; + private String refTsId; + + public TimeSeriesProfile.Builder withLocationId(String locationId) { + this.locationId = locationId; + return this; + } + + public TimeSeriesProfile.Builder withDescription(String description) { + this.description = description; + return this; + } + + public TimeSeriesProfile.Builder withKeyParameter(String keyParameter) { + this.keyParameter = keyParameter; + return this; + } + + public TimeSeriesProfile.Builder withParameterList(List parameterList) { + this.parameterList = parameterList != null ? new ArrayList<>(parameterList) : null; + return this; + } + + public TimeSeriesProfile.Builder withOfficeId(String officeId) { + this.officeId = officeId; + return this; + } + + public TimeSeriesProfile.Builder withRefTsId(String refTsId) { + this.refTsId = refTsId; + return this; + } + + + public TimeSeriesProfile build() { + return new TimeSeriesProfile(this); + } + } } diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstance.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstance.java index 67a26b1aa..dde9d4e4f 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstance.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstance.java @@ -14,16 +14,13 @@ @JsonDeserialize(builder = TimeSeriesProfile.Builder.class) @JsonInclude(JsonInclude.Include.NON_NULL) @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) -public final class TimeSeriesProfileInstance extends CwmsDTO -{ - protected TimeSeriesProfileInstance(String office) - { - super(office); - } +public final class TimeSeriesProfileInstance extends CwmsDTO { + protected TimeSeriesProfileInstance(String office) { + super(office); + } - @Override - public void validate() throws FieldException - { + @Override + public void validate() throws FieldException { - } + } } diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParser.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParser.java index b9774a380..c1e413fec 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParser.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParser.java @@ -2,6 +2,7 @@ import java.math.BigInteger; import java.util.List; + import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.PropertyNamingStrategies; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; @@ -17,143 +18,143 @@ @JsonDeserialize(builder = TimeSeriesProfileParser.Builder.class) @JsonInclude(JsonInclude.Include.NON_NULL) @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) -public class TimeSeriesProfileParser extends CwmsDTO -{ - private final String locationId; - private final String keyParameter; - private final char recordDelimiter; - private final char fieldDelimiter; - private final String timeFormat; - private final String timeZone; - private final int timeField; - private final List parameterInfoList; - private final boolean timeInTwoFields; - protected TimeSeriesProfileParser(Builder builder) - { - super(builder.officeId); - locationId = builder.locationId; - keyParameter = builder.keyParameter; - recordDelimiter = builder.recordDelimiter; - fieldDelimiter = builder.fieldDelimiter; - timeFormat = builder.timeFormat; - timeZone = builder.timeZone; - timeField = builder.timeField; - parameterInfoList = builder.parameterInfoList; - timeInTwoFields = builder.timeInTwoFields; - } - - @Override - public void validate() throws FieldException - { - if (this.keyParameter == null) { - throw new FieldException("Key Parameter field can't be null"); - } - } - - - public String getLocationId() - { - return locationId; - } - - public String getKeyParameter() - { - return keyParameter; - } - public char getRecordDelimiter(){ return recordDelimiter; } - public char getFieldDelimiter(){ return fieldDelimiter; } - public List getParameterInfoList () - { - return parameterInfoList; - } - - public String getTimeFormat() - { - return timeFormat; - } - - public String getTimeZone() - { - return timeZone; - } - - public BigInteger getTimeField() - { - return BigInteger.valueOf(timeField); - } - - public boolean getTimeInTwoFields() - { - return timeInTwoFields; - } - - - @JsonPOJOBuilder - @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) - public static final class Builder { - private String officeId; - private List parameterInfoList; - private String keyParameter; - private char recordDelimiter; - private char fieldDelimiter; - private String timeFormat; - private String timeZone; - private int timeField; - private boolean timeInTwoFields; - private String locationId; - - public TimeSeriesProfileParser.Builder withLocationId(String locationId) { - this.locationId = locationId; - return this; - } - - public TimeSeriesProfileParser.Builder withKeyParameter(String keyParameter) { - this.keyParameter = keyParameter; - return this; - } - public TimeSeriesProfileParser.Builder withRecordDelimiter(char delimiter) { - this.recordDelimiter = delimiter; - return this; - } - public TimeSeriesProfileParser.Builder withFieldDelimiter(char delimiter) { - this.fieldDelimiter = delimiter; - return this; - } - public TimeSeriesProfileParser.Builder withTimeFormat(String timeFormat) - { - this.timeFormat = timeFormat; - return this; - } - public TimeSeriesProfileParser.Builder withTimeZone(String timeZone) - { - this.timeZone = timeZone; - return this; - } - public TimeSeriesProfileParser.Builder withTimeField(int field) - { - this.timeField = field; - return this; - } - public TimeSeriesProfileParser.Builder withTimeInTwoFields(boolean timeInTwoFields) - { - this.timeInTwoFields = timeInTwoFields; - return this; - } - public TimeSeriesProfileParser.Builder withParameterInfoList(List parameterInfoList) - { - this.parameterInfoList =parameterInfoList; - return this; - } - - public TimeSeriesProfileParser.Builder withOfficeId(String officeId) { - this.officeId = officeId; - return this; - } - - - public TimeSeriesProfileParser build() { - return new TimeSeriesProfileParser(this); - } - } +public class TimeSeriesProfileParser extends CwmsDTO { + private final String locationId; + private final String keyParameter; + private final char recordDelimiter; + private final char fieldDelimiter; + private final String timeFormat; + private final String timeZone; + private final int timeField; + private final List parameterInfoList; + private final boolean timeInTwoFields; + + protected TimeSeriesProfileParser(Builder builder) { + super(builder.officeId); + locationId = builder.locationId; + keyParameter = builder.keyParameter; + recordDelimiter = builder.recordDelimiter; + fieldDelimiter = builder.fieldDelimiter; + timeFormat = builder.timeFormat; + timeZone = builder.timeZone; + timeField = builder.timeField; + parameterInfoList = builder.parameterInfoList; + timeInTwoFields = builder.timeInTwoFields; + } + + @Override + public void validate() throws FieldException { + if (this.keyParameter == null) { + throw new FieldException("Key Parameter field can't be null"); + } + } + + + public String getLocationId() { + return locationId; + } + + public String getKeyParameter() { + return keyParameter; + } + + public char getRecordDelimiter() { + return recordDelimiter; + } + + public char getFieldDelimiter() { + return fieldDelimiter; + } + + public List getParameterInfoList() { + return parameterInfoList; + } + + public String getTimeFormat() { + return timeFormat; + } + + public String getTimeZone() { + return timeZone; + } + + public BigInteger getTimeField() { + return BigInteger.valueOf(timeField); + } + + public boolean getTimeInTwoFields() { + return timeInTwoFields; + } + + + @JsonPOJOBuilder + @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) + public static final class Builder { + private String officeId; + private List parameterInfoList; + private String keyParameter; + private char recordDelimiter; + private char fieldDelimiter; + private String timeFormat; + private String timeZone; + private int timeField; + private boolean timeInTwoFields; + private String locationId; + + public TimeSeriesProfileParser.Builder withLocationId(String locationId) { + this.locationId = locationId; + return this; + } + + public TimeSeriesProfileParser.Builder withKeyParameter(String keyParameter) { + this.keyParameter = keyParameter; + return this; + } + + public TimeSeriesProfileParser.Builder withRecordDelimiter(char delimiter) { + this.recordDelimiter = delimiter; + return this; + } + + public TimeSeriesProfileParser.Builder withFieldDelimiter(char delimiter) { + this.fieldDelimiter = delimiter; + return this; + } + + public TimeSeriesProfileParser.Builder withTimeFormat(String timeFormat) { + this.timeFormat = timeFormat; + return this; + } + + public TimeSeriesProfileParser.Builder withTimeZone(String timeZone) { + this.timeZone = timeZone; + return this; + } + + public TimeSeriesProfileParser.Builder withTimeField(int field) { + this.timeField = field; + return this; + } + + public TimeSeriesProfileParser.Builder withTimeInTwoFields(boolean timeInTwoFields) { + this.timeInTwoFields = timeInTwoFields; + return this; + } + + public TimeSeriesProfileParser.Builder withParameterInfoList(List parameterInfoList) { + this.parameterInfoList = parameterInfoList; + return this; + } + + public TimeSeriesProfileParser.Builder withOfficeId(String officeId) { + this.officeId = officeId; + return this; + } + + + public TimeSeriesProfileParser build() { + return new TimeSeriesProfileParser(this); + } + } } diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfoTest.java b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfoTest.java index 7de1adaca..2539a6c88 100644 --- a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfoTest.java +++ b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfoTest.java @@ -1,5 +1,4 @@ package cwms.cda.data.dto.timeseriesprofile; -public class ParameterInfoTest -{ +public class ParameterInfoTest { } diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstanceTest.java b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstanceTest.java index bb05555cd..cfe9955b3 100644 --- a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstanceTest.java +++ b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstanceTest.java @@ -1,5 +1,4 @@ package cwms.cda.data.dto.timeseriesprofile; -public class TimeSeriesProfileInstanceTest -{ +public class TimeSeriesProfileInstanceTest { } diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserTest.java b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserTest.java index ab1c514c4..8f7647691 100644 --- a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserTest.java +++ b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserTest.java @@ -13,66 +13,65 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -final class TimeSeriesProfileParserTest -{ - @Test - void testTimeSeriesProfileSerializationRoundTrip() - { - TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser(); - ContentType contentType = Formats.parseHeader(Formats.JSONV2); +final class TimeSeriesProfileParserTest { + @Test + void testTimeSeriesProfileSerializationRoundTrip() { + TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser(); + ContentType contentType = Formats.parseHeader(Formats.JSONV2); - String serialized = Formats.format(contentType, timeSeriesProfileParser); - TimeSeriesProfileParser deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2), serialized, TimeSeriesProfileParser.class); - testAssertEquals(timeSeriesProfileParser, deserialized, "Roundtrip serialization failed"); - } + String serialized = Formats.format(contentType, timeSeriesProfileParser); + TimeSeriesProfileParser deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2), serialized, TimeSeriesProfileParser.class); + testAssertEquals(timeSeriesProfileParser, deserialized, "Roundtrip serialization failed"); + } - @Test - void testTimeSeriesProfileSerializationRoundTripFromFile() throws Exception { - TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser(); - InputStream resource = this.getClass().getResourceAsStream("/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileparser.json"); - assertNotNull(resource); - String serialized = IOUtils.toString(resource, StandardCharsets.UTF_8); - TimeSeriesProfileParser deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2), serialized, TimeSeriesProfileParser.class); - testAssertEquals(timeSeriesProfileParser, deserialized, "Roundtrip serialization from file failed"); - } - private static TimeSeriesProfileParser buildTestTimeSeriesProfileParser() { - List parameterInfo= new ArrayList<>(); - parameterInfo.add (new ParameterInfo.Builder() - .withParameter("Depth") - .withIndex(3) - .withUnit("m") - .build()); - parameterInfo.add (new ParameterInfo.Builder() - .withParameter("Temp-Water") - .withIndex(5) - .withUnit("F") - .build()); - return + @Test + void testTimeSeriesProfileSerializationRoundTripFromFile() throws Exception { + TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser(); + InputStream resource = this.getClass().getResourceAsStream("/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileparser.json"); + assertNotNull(resource); + String serialized = IOUtils.toString(resource, StandardCharsets.UTF_8); + TimeSeriesProfileParser deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2), serialized, TimeSeriesProfileParser.class); + testAssertEquals(timeSeriesProfileParser, deserialized, "Roundtrip serialization from file failed"); + } - new TimeSeriesProfileParser.Builder() - .withOfficeId("SWT") - .withLocationId("location") - .withKeyParameter("Depth") - .withRecordDelimiter((char) 10) - .withFieldDelimiter(',') - .withTimeFormat("MM/DD/YYYY,HH24:MI:SS") - .withTimeZone("UTC") - .withTimeField(1) - .withTimeInTwoFields(false) - .withParameterInfoList(parameterInfo) - .build(); - } - private void testAssertEquals(TimeSeriesProfileParser expected, TimeSeriesProfileParser actual, String message) - { - assertEquals(expected.getLocationId(), actual.getLocationId(), message); - assertEquals(expected.getFieldDelimiter(), actual.getFieldDelimiter(), message); - assertEquals(expected.getOfficeId(), actual.getOfficeId(), message); - assertEquals(expected.getKeyParameter(), actual.getKeyParameter(), message); - assertEquals(expected.getTimeField(), actual.getTimeField(), message); - assertEquals(expected.getTimeFormat(), actual.getTimeFormat(), message); - // assertEquals(expected.getParameterInfo(), actual.getParameterInfo(),message); - assertEquals(expected.getRecordDelimiter(), actual.getRecordDelimiter(), message); - assertEquals(expected.getTimeZone(), actual.getTimeZone()); - assertEquals(expected.getTimeInTwoFields(), actual.getTimeInTwoFields()); - } + private static TimeSeriesProfileParser buildTestTimeSeriesProfileParser() { + List parameterInfo = new ArrayList<>(); + parameterInfo.add(new ParameterInfo.Builder() + .withParameter("Depth") + .withIndex(3) + .withUnit("m") + .build()); + parameterInfo.add(new ParameterInfo.Builder() + .withParameter("Temp-Water") + .withIndex(5) + .withUnit("F") + .build()); + return + + new TimeSeriesProfileParser.Builder() + .withOfficeId("SWT") + .withLocationId("location") + .withKeyParameter("Depth") + .withRecordDelimiter((char) 10) + .withFieldDelimiter(',') + .withTimeFormat("MM/DD/YYYY,HH24:MI:SS") + .withTimeZone("UTC") + .withTimeField(1) + .withTimeInTwoFields(false) + .withParameterInfoList(parameterInfo) + .build(); + } + + private void testAssertEquals(TimeSeriesProfileParser expected, TimeSeriesProfileParser actual, String message) { + assertEquals(expected.getLocationId(), actual.getLocationId(), message); + assertEquals(expected.getFieldDelimiter(), actual.getFieldDelimiter(), message); + assertEquals(expected.getOfficeId(), actual.getOfficeId(), message); + assertEquals(expected.getKeyParameter(), actual.getKeyParameter(), message); + assertEquals(expected.getTimeField(), actual.getTimeField(), message); + assertEquals(expected.getTimeFormat(), actual.getTimeFormat(), message); + // assertEquals(expected.getParameterInfo(), actual.getParameterInfo(),message); + assertEquals(expected.getRecordDelimiter(), actual.getRecordDelimiter(), message); + assertEquals(expected.getTimeZone(), actual.getTimeZone()); + assertEquals(expected.getTimeInTwoFields(), actual.getTimeInTwoFields()); + } } diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileTest.java b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileTest.java index a8825e05e..626d385a2 100644 --- a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileTest.java +++ b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileTest.java @@ -12,42 +12,42 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -final class TimeSeriesProfileTest -{ - @Test - void testTimeSeriesProfileSerializationRoundTrip() { - TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile(); - ContentType contentType = Formats.parseHeader(Formats.JSONV2); - String serialized = Formats.format(contentType, timeSeriesProfile); - TimeSeriesProfile deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2), serialized, TimeSeriesProfile.class); - testAssertEquals(timeSeriesProfile, deserialized, "Roundtrip serialization failed"); - } +final class TimeSeriesProfileTest { + @Test + void testTimeSeriesProfileSerializationRoundTrip() { + TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile(); + ContentType contentType = Formats.parseHeader(Formats.JSONV2); + String serialized = Formats.format(contentType, timeSeriesProfile); + TimeSeriesProfile deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2), serialized, TimeSeriesProfile.class); + testAssertEquals(timeSeriesProfile, deserialized, "Roundtrip serialization failed"); + } - @Test - void testTimeSeriesProfileSerializationRoundTripFromFile() throws Exception { - TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile(); - InputStream resource = this.getClass().getResourceAsStream("/cwms/cda/data/dto/timeseriesprofile/timeseriesprofile.json"); - assertNotNull(resource); - String serialized = IOUtils.toString(resource, StandardCharsets.UTF_8); - TimeSeriesProfile deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2), serialized, TimeSeriesProfile.class); - testAssertEquals(timeSeriesProfile, deserialized, "Roundtrip serialization from file failed"); - } + @Test + void testTimeSeriesProfileSerializationRoundTripFromFile() throws Exception { + TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile(); + InputStream resource = this.getClass().getResourceAsStream("/cwms/cda/data/dto/timeseriesprofile/timeseriesprofile.json"); + assertNotNull(resource); + String serialized = IOUtils.toString(resource, StandardCharsets.UTF_8); + TimeSeriesProfile deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2), serialized, TimeSeriesProfile.class); + testAssertEquals(timeSeriesProfile, deserialized, "Roundtrip serialization from file failed"); + } - private TimeSeriesProfile buildTestTimeSeriesProfile() { - return new TimeSeriesProfile.Builder() - .withOfficeId("Office") - .withKeyParameter("Depth") - .withRefTsId("TimeSeries") - .withLocationId("Location") - .withDescription("Description") - .withParameterList(Arrays.asList("Temperature", "Depth")) - .build(); - } - private void testAssertEquals(TimeSeriesProfile expected, TimeSeriesProfile actual, String message) { - assertEquals(expected.getLocationId(), actual.getLocationId(), message); - assertEquals(expected.getDescription(), actual.getDescription(), message); - assertEquals(expected.getParameterList(), actual.getParameterList(), message); - assertEquals(expected.getKeyParameter(), actual.getKeyParameter(), message); - assertEquals(expected.getRefTsId(), actual.getRefTsId(), message); - } + private TimeSeriesProfile buildTestTimeSeriesProfile() { + return new TimeSeriesProfile.Builder() + .withOfficeId("Office") + .withKeyParameter("Depth") + .withRefTsId("TimeSeries") + .withLocationId("Location") + .withDescription("Description") + .withParameterList(Arrays.asList("Temperature", "Depth")) + .build(); + } + + private void testAssertEquals(TimeSeriesProfile expected, TimeSeriesProfile actual, String message) { + assertEquals(expected.getLocationId(), actual.getLocationId(), message); + assertEquals(expected.getDescription(), actual.getDescription(), message); + assertEquals(expected.getParameterList(), actual.getParameterList(), message); + assertEquals(expected.getKeyParameter(), actual.getKeyParameter(), message); + assertEquals(expected.getRefTsId(), actual.getRefTsId(), message); + } } From 4712033fb5dd05118a85f433a68732e83b32a1e9 Mon Sep 17 00:00:00 2001 From: Andreas Christmann Date: Wed, 26 Jun 2024 18:13:19 -0700 Subject: [PATCH 14/26] use CWMS-Id for location id --- .../timeseriesprofile/TimeSeriesProfile.java | 39 +++++++------------ .../TimeSeriesProfileParser.java | 21 ++++------ .../TimeSeriesProfileParserTest.java | 23 ++++++----- .../TimeSeriesProfileTest.java | 26 +++++++++---- .../timeseriesprofile/timeseriesprofile.json | 17 +++++--- .../timeseriesprofileparser.json | 6 ++- 6 files changed, 68 insertions(+), 64 deletions(-) diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfile.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfile.java index ec64f2212..1fad5af2a 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfile.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfile.java @@ -9,7 +9,8 @@ import com.fasterxml.jackson.databind.annotation.JsonNaming; import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; import cwms.cda.api.errors.FieldException; -import cwms.cda.data.dto.CwmsDTO; +import cwms.cda.data.dto.CwmsDTOBase; +import cwms.cda.data.dto.CwmsId; import cwms.cda.formatters.Formats; import cwms.cda.formatters.annotations.FormattableWith; import cwms.cda.formatters.json.JsonV2; @@ -19,10 +20,9 @@ @JsonDeserialize(builder = TimeSeriesProfile.Builder.class) @JsonInclude(JsonInclude.Include.NON_NULL) @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) -public final class TimeSeriesProfile extends CwmsDTO { +public final class TimeSeriesProfile implements CwmsDTOBase { @Schema(description = "Location ID") - // TODO replace with CWMSID - private final String locationId; + private final CwmsId locationId; @Schema(description = "Description") private final String description; @Schema(description = "Parameter List") @@ -30,19 +30,17 @@ public final class TimeSeriesProfile extends CwmsDTO { @Schema(description = "Key Parameter") private final String keyParameter; @Schema(description = "Reference TS") - // TODO replace with CWMSID - private final String refTsId; + private final CwmsId referenceTsId; private TimeSeriesProfile(Builder builder) { - super(builder.officeId); this.locationId = builder.locationId; this.description = builder.description; this.keyParameter = builder.keyParameter; this.parameterList = builder.parameterList; - this.refTsId = builder.refTsId; + this.referenceTsId = builder.referenceTsId; } - public String getLocationId() { + public CwmsId getLocationId() { return locationId; } @@ -58,8 +56,8 @@ public List getParameterList() { return parameterList != null ? new ArrayList<>(parameterList) : null; } - public String getRefTsId() { - return refTsId; + public CwmsId getReferenceTsId() { + return referenceTsId; } @Override @@ -70,9 +68,6 @@ public void validate() throws FieldException { if (this.keyParameter == null) { throw new FieldException("Key Parameter field can't be null"); } - if (this.officeId == null) { - throw new FieldException("Office Id field can't be null"); - } if (this.locationId == null) { throw new FieldException("Location Id field can't be null"); } @@ -84,14 +79,13 @@ public void validate() throws FieldException { @JsonPOJOBuilder @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) public static final class Builder { - private String officeId; private List parameterList; private String keyParameter; private String description; - private String locationId; - private String refTsId; + private CwmsId locationId; + private CwmsId referenceTsId; - public TimeSeriesProfile.Builder withLocationId(String locationId) { + public TimeSeriesProfile.Builder withLocationId(CwmsId locationId) { this.locationId = locationId; return this; } @@ -111,13 +105,8 @@ public TimeSeriesProfile.Builder withParameterList(List parameterList) { return this; } - public TimeSeriesProfile.Builder withOfficeId(String officeId) { - this.officeId = officeId; - return this; - } - - public TimeSeriesProfile.Builder withRefTsId(String refTsId) { - this.refTsId = refTsId; + public TimeSeriesProfile.Builder withReferenceTsId(CwmsId referenceTsId) { + this.referenceTsId = referenceTsId; return this; } diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParser.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParser.java index c1e413fec..146d3977d 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParser.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParser.java @@ -9,7 +9,8 @@ import com.fasterxml.jackson.databind.annotation.JsonNaming; import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; import cwms.cda.api.errors.FieldException; -import cwms.cda.data.dto.CwmsDTO; +import cwms.cda.data.dto.CwmsDTOBase; +import cwms.cda.data.dto.CwmsId; import cwms.cda.formatters.Formats; import cwms.cda.formatters.annotations.FormattableWith; import cwms.cda.formatters.json.JsonV2; @@ -18,8 +19,8 @@ @JsonDeserialize(builder = TimeSeriesProfileParser.Builder.class) @JsonInclude(JsonInclude.Include.NON_NULL) @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) -public class TimeSeriesProfileParser extends CwmsDTO { - private final String locationId; +public class TimeSeriesProfileParser implements CwmsDTOBase { + private final CwmsId locationId; private final String keyParameter; private final char recordDelimiter; private final char fieldDelimiter; @@ -30,7 +31,6 @@ public class TimeSeriesProfileParser extends CwmsDTO { private final boolean timeInTwoFields; protected TimeSeriesProfileParser(Builder builder) { - super(builder.officeId); locationId = builder.locationId; keyParameter = builder.keyParameter; recordDelimiter = builder.recordDelimiter; @@ -50,7 +50,7 @@ public void validate() throws FieldException { } - public String getLocationId() { + public CwmsId getLocationId() { return locationId; } @@ -90,7 +90,6 @@ public boolean getTimeInTwoFields() { @JsonPOJOBuilder @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) public static final class Builder { - private String officeId; private List parameterInfoList; private String keyParameter; private char recordDelimiter; @@ -99,9 +98,9 @@ public static final class Builder { private String timeZone; private int timeField; private boolean timeInTwoFields; - private String locationId; + private CwmsId locationId; - public TimeSeriesProfileParser.Builder withLocationId(String locationId) { + public TimeSeriesProfileParser.Builder withLocationId(CwmsId locationId) { this.locationId = locationId; return this; } @@ -146,12 +145,6 @@ public TimeSeriesProfileParser.Builder withParameterInfoList(List return this; } - public TimeSeriesProfileParser.Builder withOfficeId(String officeId) { - this.officeId = officeId; - return this; - } - - public TimeSeriesProfileParser build() { return new TimeSeriesProfileParser(this); } diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserTest.java b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserTest.java index 8f7647691..88a823735 100644 --- a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserTest.java +++ b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserTest.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import java.util.List; +import cwms.cda.data.dto.CwmsId; import cwms.cda.formatters.ContentType; import cwms.cda.formatters.Formats; import org.apache.commons.io.IOUtils; @@ -17,10 +18,10 @@ final class TimeSeriesProfileParserTest { @Test void testTimeSeriesProfileSerializationRoundTrip() { TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser(); - ContentType contentType = Formats.parseHeader(Formats.JSONV2); + ContentType contentType = Formats.parseHeader(Formats.JSONV2, TimeSeriesProfileParser.class); String serialized = Formats.format(contentType, timeSeriesProfileParser); - TimeSeriesProfileParser deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2), serialized, TimeSeriesProfileParser.class); + TimeSeriesProfileParser deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2, TimeSeriesProfileParser.class), serialized, TimeSeriesProfileParser.class); testAssertEquals(timeSeriesProfileParser, deserialized, "Roundtrip serialization failed"); } @@ -30,7 +31,7 @@ void testTimeSeriesProfileSerializationRoundTripFromFile() throws Exception { InputStream resource = this.getClass().getResourceAsStream("/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileparser.json"); assertNotNull(resource); String serialized = IOUtils.toString(resource, StandardCharsets.UTF_8); - TimeSeriesProfileParser deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2), serialized, TimeSeriesProfileParser.class); + TimeSeriesProfileParser deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2, TimeSeriesProfileParser.class), serialized, TimeSeriesProfileParser.class); testAssertEquals(timeSeriesProfileParser, deserialized, "Roundtrip serialization from file failed"); } @@ -46,11 +47,13 @@ private static TimeSeriesProfileParser buildTestTimeSeriesProfileParser() { .withIndex(5) .withUnit("F") .build()); + CwmsId locationId = new CwmsId.Builder() + .withOfficeId("SWT") + .withName("location") + .build(); return - new TimeSeriesProfileParser.Builder() - .withOfficeId("SWT") - .withLocationId("location") + .withLocationId(locationId) .withKeyParameter("Depth") .withRecordDelimiter((char) 10) .withFieldDelimiter(',') @@ -63,13 +66,15 @@ private static TimeSeriesProfileParser buildTestTimeSeriesProfileParser() { } private void testAssertEquals(TimeSeriesProfileParser expected, TimeSeriesProfileParser actual, String message) { - assertEquals(expected.getLocationId(), actual.getLocationId(), message); + assertEquals(expected.getLocationId().getName(), actual.getLocationId().getName(), message); + assertEquals(expected.getLocationId().getOfficeId(), actual.getLocationId().getOfficeId(), message); assertEquals(expected.getFieldDelimiter(), actual.getFieldDelimiter(), message); - assertEquals(expected.getOfficeId(), actual.getOfficeId(), message); + assertEquals(expected.getLocationId().getName(), actual.getLocationId().getName(), message); + assertEquals(expected.getLocationId().getOfficeId(), actual.getLocationId().getOfficeId(), message); assertEquals(expected.getKeyParameter(), actual.getKeyParameter(), message); assertEquals(expected.getTimeField(), actual.getTimeField(), message); assertEquals(expected.getTimeFormat(), actual.getTimeFormat(), message); - // assertEquals(expected.getParameterInfo(), actual.getParameterInfo(),message); + assertEquals(expected.getParameterInfoList(), actual.getParameterInfoList(),message); assertEquals(expected.getRecordDelimiter(), actual.getRecordDelimiter(), message); assertEquals(expected.getTimeZone(), actual.getTimeZone()); assertEquals(expected.getTimeInTwoFields(), actual.getTimeInTwoFields()); diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileTest.java b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileTest.java index 626d385a2..e5992f4fd 100644 --- a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileTest.java +++ b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileTest.java @@ -4,6 +4,7 @@ import java.nio.charset.StandardCharsets; import java.util.Arrays; +import cwms.cda.data.dto.CwmsId; import cwms.cda.formatters.ContentType; import cwms.cda.formatters.Formats; import org.apache.commons.io.IOUtils; @@ -16,9 +17,9 @@ final class TimeSeriesProfileTest { @Test void testTimeSeriesProfileSerializationRoundTrip() { TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile(); - ContentType contentType = Formats.parseHeader(Formats.JSONV2); + ContentType contentType = Formats.parseHeader(Formats.JSONV2, TimeSeriesProfile.class); String serialized = Formats.format(contentType, timeSeriesProfile); - TimeSeriesProfile deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2), serialized, TimeSeriesProfile.class); + TimeSeriesProfile deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2, TimeSeriesProfile.class), serialized, TimeSeriesProfile.class); testAssertEquals(timeSeriesProfile, deserialized, "Roundtrip serialization failed"); } @@ -28,26 +29,35 @@ void testTimeSeriesProfileSerializationRoundTripFromFile() throws Exception { InputStream resource = this.getClass().getResourceAsStream("/cwms/cda/data/dto/timeseriesprofile/timeseriesprofile.json"); assertNotNull(resource); String serialized = IOUtils.toString(resource, StandardCharsets.UTF_8); - TimeSeriesProfile deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2), serialized, TimeSeriesProfile.class); + TimeSeriesProfile deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2, TimeSeriesProfile.class), serialized, TimeSeriesProfile.class); testAssertEquals(timeSeriesProfile, deserialized, "Roundtrip serialization from file failed"); } private TimeSeriesProfile buildTestTimeSeriesProfile() { + CwmsId locationId = new CwmsId.Builder() + .withName("location") + .withOfficeId("office") + .build(); + CwmsId referenceTsId = new CwmsId.Builder() + .withName("location.Elev.Inst.0.0.REV") + .withOfficeId("office") + .build(); return new TimeSeriesProfile.Builder() - .withOfficeId("Office") .withKeyParameter("Depth") - .withRefTsId("TimeSeries") - .withLocationId("Location") + .withReferenceTsId(referenceTsId) + .withLocationId(locationId) .withDescription("Description") .withParameterList(Arrays.asList("Temperature", "Depth")) .build(); } private void testAssertEquals(TimeSeriesProfile expected, TimeSeriesProfile actual, String message) { - assertEquals(expected.getLocationId(), actual.getLocationId(), message); + assertEquals(expected.getLocationId().getName(), actual.getLocationId().getName(), message); + assertEquals(expected.getLocationId().getOfficeId(), actual.getLocationId().getOfficeId(), message); assertEquals(expected.getDescription(), actual.getDescription(), message); assertEquals(expected.getParameterList(), actual.getParameterList(), message); assertEquals(expected.getKeyParameter(), actual.getKeyParameter(), message); - assertEquals(expected.getRefTsId(), actual.getRefTsId(), message); + assertEquals(expected.getReferenceTsId().getName(), actual.getReferenceTsId().getName(), message); + assertEquals(expected.getReferenceTsId().getOfficeId(), actual.getReferenceTsId().getOfficeId(), message); } } diff --git a/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofile.json b/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofile.json index 5222856a6..7213fe007 100644 --- a/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofile.json +++ b/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofile.json @@ -1,8 +1,13 @@ { - "description": "Description", - "parameter-list": ["Temperature","Depth"], - "location-id": "Location", - "office-id": "Office", - "ref-ts-id": "TimeSeries", - "key-parameter": "Depth" + "description" : "Description", + "parameter-list" : ["Temperature","Depth"], + "location-id" : { + "office-id" : "office", + "name" : "location" + }, + "reference-ts-id" : { + "office-id" : "office", + "name" : "location.Elev.Inst.0.0.REV" + }, + "key-parameter" : "Depth" } \ No newline at end of file diff --git a/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileparser.json b/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileparser.json index 4a907c4bb..a06828412 100644 --- a/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileparser.json +++ b/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileparser.json @@ -1,6 +1,8 @@ { - "office-id": "SWT", - "location-id": "location", + "location-id": { + "office-id": "SWT", + "name": "location" + }, "key-parameter": "Depth", "record-delimiter": "\n", "field-delimiter": ",", From 011a1c2597a5657095341ba1369bc6331d82f0ca Mon Sep 17 00:00:00 2001 From: Andreas Christmann Date: Thu, 27 Jun 2024 13:58:59 -0700 Subject: [PATCH 15/26] use CWMSId, TimeSeriesProfile Instance DTO, json and unittest --- .../TimeSeriesProfileDao.java | 79 +++++++++-- .../timeseriesprofile/ProfileTimeSeries.java | 78 +++++++++++ .../timeseriesprofile/TimeSeriesProfile.java | 15 +- .../TimeSeriesProfileInstance.java | 46 ++++++- .../TimeSeriesProfileParser.java | 2 +- .../dto/timeseriesprofile/TimeValuePair.java | 55 ++++++++ .../TimeSeriesProfileDaoIT.java | 35 ++--- .../TimeSeriesProfileParserDaoIT.java | 128 +++++++++++++----- .../timeseriesprofile/ParameterInfoTest.java | 4 - .../TimeSeriesProfileInstanceTest.java | 100 ++++++++++++++ .../TimeSeriesProfileTest.java | 4 +- .../timeseriesprofileinstance.json | 38 +++--- 12 files changed, 491 insertions(+), 93 deletions(-) create mode 100644 cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ProfileTimeSeries.java create mode 100644 cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeValuePair.java delete mode 100644 cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfoTest.java diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileDao.java b/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileDao.java index a44a6d565..5ce24edb0 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileDao.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileDao.java @@ -1,13 +1,20 @@ package cwms.cda.data.dao.timeseriesprofile; +import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; import cwms.cda.data.dao.JooqDao; +import cwms.cda.data.dto.CwmsId; import cwms.cda.data.dto.timeseriesprofile.TimeSeriesProfile; import org.jooq.DSLContext; +import org.jooq.Record; +import org.jooq.Result; import org.jooq.impl.DSL; import usace.cwms.db.jooq.codegen.packages.CWMS_TS_PROFILE_PACKAGE; +import usace.cwms.db.jooq.codegen.udt.records.STR_TAB_T; +import usace.cwms.db.jooq.codegen.udt.records.TS_PROFILE_T; public class TimeSeriesProfileDao extends JooqDao { @@ -24,25 +31,77 @@ public void storeTimeSeriesProfile(TimeSeriesProfile timeSeriesProfile, boolean { parameterString += "," + parameterList.get(i); } - CWMS_TS_PROFILE_PACKAGE.call_STORE_TS_PROFILE(DSL.using(conn).configuration(),timeSeriesProfile.getLocationId(), + CWMS_TS_PROFILE_PACKAGE.call_STORE_TS_PROFILE(DSL.using(conn).configuration(),timeSeriesProfile.getLocationId().getName(), timeSeriesProfile.getKeyParameter(), - parameterString, null, null, "F","T",timeSeriesProfile.getOfficeId()); + parameterString, null, null, "F","T",timeSeriesProfile.getLocationId().getOfficeId()); }); } - public void retrieveTimeSeriesProfile() + public TimeSeriesProfile retrieveTimeSeriesProfile(String locationId, String parameterId, String officeId) { - // TODO + return connectionResult(dsl, conn -> { + TS_PROFILE_T timeSeriesProfile = CWMS_TS_PROFILE_PACKAGE.call_RETRIEVE_TS_PROFILE( + DSL.using(conn).configuration(), locationId, parameterId, officeId); + return map(timeSeriesProfile, locationId, parameterId, officeId); + }); + } + public void deleteTimeSeriesProfile(String locationId, String keyParameter, String officeId) + { + connection(dsl, conn -> + CWMS_TS_PROFILE_PACKAGE.call_DELETE_TS_PROFILE(DSL.using(conn).configuration(),locationId, keyParameter, "DELETE ALL", + officeId)); } - public void deleteTimeSeriesProfile() + public void copyTimeSeriesProfile(String locationId, String keyParameter, String destinationLocation, String destRefTsId, String officeId) { - // TODO + connection(dsl, conn -> + CWMS_TS_PROFILE_PACKAGE.call_COPY_TS_PROFILE(DSL.using(conn).configuration(),locationId, keyParameter, destinationLocation, + destRefTsId, "F", "F", + officeId)); } - public void copyTimeSeriesProfile() + public List retrieveTimeSeriesProfiles(String locationIdMask, String parameterIdMask, String officeIdMask) { - // TODO + return connectionResult(dsl, conn -> { + List timeSeriesProfileList = new ArrayList<>(); + Result timeSeriesProfileResults = CWMS_TS_PROFILE_PACKAGE.call_CAT_TS_PROFILE( + DSL.using(conn).configuration(), locationIdMask, parameterIdMask, officeIdMask); + for(int i=0; i values = ( Result)timeSeriesProfileResults.get(i).get("VALUE_PARAMETERS"); + List parameterList = new ArrayList<>(); + for(int j=0; j parameterList = profileParams.stream().collect(Collectors.toList()); + CwmsId locationId = new CwmsId.Builder().withName(locationName).withOfficeId(officeId).build(); + CwmsId referenceTsId = new CwmsId.Builder().withName(timeSeriesProfile.getREFERENCE_TS_ID()).withOfficeId(officeId).build(); + return new TimeSeriesProfile.Builder() + .withLocationId(locationId) + .withDescription(timeSeriesProfile.getDESCRIPTION()) + .withReferenceTsId(referenceTsId) + .withKeyParameter(keyParameter) + .withParameterList(parameterList) + .build(); } } diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ProfileTimeSeries.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ProfileTimeSeries.java new file mode 100644 index 000000000..3dd4f2e38 --- /dev/null +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ProfileTimeSeries.java @@ -0,0 +1,78 @@ +package cwms.cda.data.dto.timeseriesprofile; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.PropertyNamingStrategies; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; +import cwms.cda.formatters.Formats; +import cwms.cda.formatters.annotations.FormattableWith; +import cwms.cda.formatters.json.JsonV2; + +import java.util.List; + +@FormattableWith(contentType = Formats.JSONV2, formatter = JsonV2.class) +@JsonDeserialize(builder = ProfileTimeSeries.Builder.class) +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) +public class ProfileTimeSeries { + private final String parameter; + private final String unit; + private final String timeZone; + private final List timeValuePairList; + + protected ProfileTimeSeries(Builder builder) + { + parameter = builder.parameter; + unit = builder.unit; + timeValuePairList = builder.timeValuePairList; + timeZone = builder.timeZone; + } + public String getTimeZone() + { + return timeZone; + } + public String getParameter() + { + return parameter; + } + public String getUnit() + { + return unit; + } + public List getTimeValuePairList() + { + return timeValuePairList; + } + @JsonPOJOBuilder + @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) + public static final class Builder { + private List timeValuePairList; + private String unit; + private String parameter; + private String timeZone; + public Builder withTimeValuePairList(List timeValuePairList) { + this.timeValuePairList = timeValuePairList; + return this; + } + + public Builder withParameter(String parameter) { + this.parameter = parameter; + return this; + } + + public Builder withUnit(String unit) { + this.unit = unit; + return this; + } + + public Builder withTimeZone(String timeZone){ + this.timeZone = timeZone; + return this; + } + public ProfileTimeSeries build() { + return new ProfileTimeSeries(this); + } + } + +} diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfile.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfile.java index 1fad5af2a..831b4e097 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfile.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfile.java @@ -53,7 +53,7 @@ public String getKeyParameter() { } public List getParameterList() { - return parameterList != null ? new ArrayList<>(parameterList) : null; + return parameterList; } public CwmsId getReferenceTsId() { @@ -62,8 +62,8 @@ public CwmsId getReferenceTsId() { @Override public void validate() throws FieldException { - if (this.parameterList == null) { - throw new FieldException("Parameter list field can't be null"); + if (this.parameterList.isEmpty()) { + throw new FieldException("Parameter list field must not be empty"); } if (this.keyParameter == null) { throw new FieldException("Key Parameter field can't be null"); @@ -79,7 +79,7 @@ public void validate() throws FieldException { @JsonPOJOBuilder @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) public static final class Builder { - private List parameterList; + private final List parameterList = new ArrayList<>(); private String keyParameter; private String description; private CwmsId locationId; @@ -101,8 +101,11 @@ public TimeSeriesProfile.Builder withKeyParameter(String keyParameter) { } public TimeSeriesProfile.Builder withParameterList(List parameterList) { - this.parameterList = parameterList != null ? new ArrayList<>(parameterList) : null; - return this; + this.parameterList.clear(); + if (parameterList != null) { + this.parameterList.addAll(parameterList); + } + return this; } public TimeSeriesProfile.Builder withReferenceTsId(CwmsId referenceTsId) { diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstance.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstance.java index dde9d4e4f..469940e54 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstance.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstance.java @@ -4,23 +4,59 @@ import com.fasterxml.jackson.databind.PropertyNamingStrategies; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonNaming; +import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; import cwms.cda.api.errors.FieldException; -import cwms.cda.data.dto.CwmsDTO; +import cwms.cda.data.dto.CwmsDTOBase; import cwms.cda.formatters.Formats; import cwms.cda.formatters.annotations.FormattableWith; import cwms.cda.formatters.json.JsonV2; +import java.util.List; + @FormattableWith(contentType = Formats.JSONV2, formatter = JsonV2.class) -@JsonDeserialize(builder = TimeSeriesProfile.Builder.class) +@JsonDeserialize(builder = TimeSeriesProfileInstance.Builder.class) @JsonInclude(JsonInclude.Include.NON_NULL) @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) -public final class TimeSeriesProfileInstance extends CwmsDTO { - protected TimeSeriesProfileInstance(String office) { - super(office); +public final class TimeSeriesProfileInstance implements CwmsDTOBase { + private final TimeSeriesProfile timeSeriesProfile; + private final List timeSeriesList; + + private TimeSeriesProfileInstance(Builder builder) + { + timeSeriesList = builder.timeSeriesList; + timeSeriesProfile = builder.timeSeriesProfile; + } + + public TimeSeriesProfile getTimeSeriesProfile() { + return timeSeriesProfile; + } + + public List getTimeSeriesList() { + return timeSeriesList; } @Override public void validate() throws FieldException { } + @JsonPOJOBuilder + @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) + public static final class Builder { + private List timeSeriesList; + private TimeSeriesProfile timeSeriesProfile; + + public TimeSeriesProfileInstance.Builder withTimeSeriesProfile(TimeSeriesProfile timeSeriesProfile) { + this.timeSeriesProfile = timeSeriesProfile; + return this; + } + + public TimeSeriesProfileInstance.Builder withTimeSeriesList(List timeSeriesList) { + this.timeSeriesList = timeSeriesList; + return this; + } + + public TimeSeriesProfileInstance build() { + return new TimeSeriesProfileInstance(this); + } + } } diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParser.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParser.java index 146d3977d..9cf8f4494 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParser.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParser.java @@ -30,7 +30,7 @@ public class TimeSeriesProfileParser implements CwmsDTOBase { private final List parameterInfoList; private final boolean timeInTwoFields; - protected TimeSeriesProfileParser(Builder builder) { + private TimeSeriesProfileParser(Builder builder) { locationId = builder.locationId; keyParameter = builder.keyParameter; recordDelimiter = builder.recordDelimiter; diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeValuePair.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeValuePair.java new file mode 100644 index 000000000..fbf6985c0 --- /dev/null +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeValuePair.java @@ -0,0 +1,55 @@ +package cwms.cda.data.dto.timeseriesprofile; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.PropertyNamingStrategies; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; +import cwms.cda.formatters.Formats; +import cwms.cda.formatters.annotations.FormattableWith; +import cwms.cda.formatters.json.JsonV2; + +import java.time.Instant; + +@FormattableWith(contentType = Formats.JSONV2, formatter = JsonV2.class) +@JsonDeserialize(builder = TimeValuePair.Builder.class) +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) +public class TimeValuePair { + private final Instant dateTime; + private final double value; + + protected TimeValuePair(Builder builder) + { + dateTime = builder.dateTime; + value = builder.value; + } + public Instant getDateTime() + { + return dateTime; + } + public double getValue() + { + return value; + } + @JsonPOJOBuilder + @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) + public static final class Builder { + private Instant dateTime; + private double value; + + public Builder withDateTime(Instant dateTime) { + this.dateTime = dateTime; + return this; + } + + public Builder withValue(double value) { + this.value = value; + return this; + } + + public TimeValuePair build() { + return new TimeValuePair(this); + } + } +} diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileDaoIT.java b/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileDaoIT.java index e76b22627..c8e35946d 100644 --- a/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileDaoIT.java +++ b/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileDaoIT.java @@ -9,6 +9,7 @@ import cwms.cda.api.DataApiTestIT; import cwms.cda.api.enums.Nation; import cwms.cda.data.dao.LocationsDaoImpl; +import cwms.cda.data.dto.CwmsId; import cwms.cda.data.dto.Location; import cwms.cda.data.dto.timeseriesprofile.TimeSeriesProfile; import fixtures.CwmsDataApiSetupCallback; @@ -70,16 +71,18 @@ void testCopyTimeSeriesProfile() throws SQLException TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile("Depth"); timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfile, false); - timeSeriesProfileDao.copyTimeSeriesProfile(timeSeriesProfile.getLocationId(), timeSeriesProfile.getKeyParameter(), - "AAA","",timeSeriesProfile.getOfficeId()); - TimeSeriesProfile timeSeriesProfileCopied = timeSeriesProfileDao.retrieveTimeSeriesProfile("AAA", - timeSeriesProfile.getKeyParameter(), timeSeriesProfile.getOfficeId()); + timeSeriesProfileDao.copyTimeSeriesProfile(timeSeriesProfile.getLocationId().getName(), timeSeriesProfile.getKeyParameter(), + timeSeriesProfile.getLocationId().getName(),timeSeriesProfile.getReferenceTsId().getName(), + timeSeriesProfile.getLocationId().getOfficeId()); + TimeSeriesProfile timeSeriesProfileCopied = timeSeriesProfileDao.retrieveTimeSeriesProfile(timeSeriesProfile.getLocationId().getName(), + timeSeriesProfile.getKeyParameter(), timeSeriesProfile.getLocationId().getOfficeId()); assertEquals("AAA", timeSeriesProfileCopied.getLocationId()); assertEquals(timeSeriesProfile.getKeyParameter(), timeSeriesProfileCopied.getKeyParameter()); assertEquals(timeSeriesProfile.getParameterList(),timeSeriesProfileCopied.getParameterList()); - timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfile.getLocationId(),timeSeriesProfile.getKeyParameter(),timeSeriesProfile.getOfficeId()); - timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfileCopied.getLocationId(),timeSeriesProfileCopied.getKeyParameter(),timeSeriesProfileCopied.getOfficeId()); + timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfile.getLocationId().getName(),timeSeriesProfile.getKeyParameter(),timeSeriesProfile.getLocationId().getOfficeId()); + timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfileCopied.getLocationId().getName(), + timeSeriesProfileCopied.getKeyParameter(),timeSeriesProfileCopied.getLocationId().getName()); }); } @Test @@ -93,13 +96,13 @@ void testRetrieveTimeSeriesProfile() throws Exception { TimeSeriesProfile timeSeriesProfileIn = (buildTestTimeSeriesProfile("Depth")); timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfileIn, false); - TimeSeriesProfile timeSeriesProfileOut = timeSeriesProfileDao.retrieveTimeSeriesProfile(timeSeriesProfileIn.getLocationId(), - timeSeriesProfileIn.getKeyParameter(), timeSeriesProfileIn.getOfficeId()); + TimeSeriesProfile timeSeriesProfileOut = timeSeriesProfileDao.retrieveTimeSeriesProfile(timeSeriesProfileIn.getLocationId().getName(), + timeSeriesProfileIn.getKeyParameter(), timeSeriesProfileIn.getLocationId().getOfficeId()); assertEquals(timeSeriesProfileOut, timeSeriesProfileIn); - timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfileIn.getLocationId(), - timeSeriesProfileIn.getKeyParameter(), timeSeriesProfileIn.getOfficeId()); + timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfileIn.getLocationId().getName(), + timeSeriesProfileIn.getKeyParameter(), timeSeriesProfileIn.getLocationId().getOfficeId()); }); } @@ -119,8 +122,8 @@ void testRetrieveCatalog() throws Exception { for(TimeSeriesProfile timeSeriesProfile: timeSeriesProfileListBefore) { - timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfile.getLocationId(), timeSeriesProfile.getKeyParameter(), - timeSeriesProfile.getOfficeId()); + timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfile.getLocationId().getName(), timeSeriesProfile.getKeyParameter(), + timeSeriesProfile.getLocationId().getOfficeId()); } List timeSeriesProfileListAfter = timeSeriesProfileDao.retrieveTimeSeriesProfiles("*", "*", "*"); @@ -141,8 +144,8 @@ void testDeleteTimeSeriesProfile() throws Exception { List timeSeriesProfileListBefore = timeSeriesProfileDao.retrieveTimeSeriesProfiles("*", "*", "*"); - timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfile.getLocationId(), timeSeriesProfile.getKeyParameter(), - timeSeriesProfile.getOfficeId()); + timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfile.getLocationId().getName(), timeSeriesProfile.getKeyParameter(), + timeSeriesProfile.getLocationId().getOfficeId()); List timeSeriesProfileListAfter = timeSeriesProfileDao.retrieveTimeSeriesProfiles("*", "*", "*"); @@ -171,9 +174,9 @@ private static Location buildTestLocation(String location) { private static TimeSeriesProfile buildTestTimeSeriesProfile(String keyParameter) { String officeId = CwmsDataApiSetupCallback.getDatabaseLink().getOfficeId(); + CwmsId locationId = new CwmsId.Builder().withOfficeId(officeId).withName("location").build(); return new TimeSeriesProfile.Builder() - .withOfficeId(officeId) - .withLocationId("TIMESERIESPROFILE_LOC") + .withLocationId(locationId) .withKeyParameter(keyParameter) .withParameterList(Arrays.asList("Pres", "Depth")) .build(); diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDaoIT.java b/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDaoIT.java index a499ae723..8bbd3eb52 100644 --- a/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDaoIT.java +++ b/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDaoIT.java @@ -10,6 +10,7 @@ import cwms.cda.api.DataApiTestIT; import cwms.cda.api.enums.Nation; import cwms.cda.data.dao.LocationsDaoImpl; +import cwms.cda.data.dto.CwmsId; import cwms.cda.data.dto.Location; import cwms.cda.data.dto.timeseriesprofile.ParameterInfo; import cwms.cda.data.dto.timeseriesprofile.TimeSeriesProfile; @@ -31,7 +32,8 @@ @Tag("integration") final class TimeSeriesProfileParserDaoIT extends DataApiTestIT { - private static final Location TIMESERIESPORFILE_LOC = buildTestLocation(); + private static final Location TIMESERIESPROFILE_LOC = buildTestLocation("TIMESERIESPROFILE_LOC"); + private static final Location LOCATION_AAA = buildTestLocation("AAA"); @BeforeAll public static void setup() throws Exception @@ -42,7 +44,8 @@ public static void setup() throws Exception LocationsDaoImpl locationsDao = new LocationsDaoImpl(context); try { - locationsDao.storeLocation(TIMESERIESPORFILE_LOC); + locationsDao.storeLocation(TIMESERIESPROFILE_LOC); + locationsDao.storeLocation(LOCATION_AAA); } catch(IOException e) { @@ -58,7 +61,7 @@ public static void tearDown() throws Exception { databaseLink.connection(c -> { DSLContext context = getDslContext(c, databaseLink.getOfficeId()); LocationsDaoImpl locationsDao = new LocationsDaoImpl(context); - locationsDao.deleteLocation(TIMESERIESPORFILE_LOC.getName(), databaseLink.getOfficeId()); + // locationsDao.deleteLocation(TIMESERIESPORFILE_LOC.getName(), databaseLink.getOfficeId()); }); } @@ -70,19 +73,22 @@ void testStoreAndRetrieve() throws Exception { TimeSeriesProfileDao timeSeriesProfileDao = new TimeSeriesProfileDao(context); - TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile(); + TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile("Depth"); timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfile, false); TimeSeriesProfileParserDao timeSeriesProfileParserDao = new TimeSeriesProfileParserDao(context); - TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser(); + TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser("Depth"); timeSeriesProfileParserDao.storeTimeSeriesProfileParser(timeSeriesProfileParser, false); - TimeSeriesProfileParser retrieved = timeSeriesProfileParserDao.retrieveTimeSeriesProfileParser(timeSeriesProfileParser.getLocationId(), - timeSeriesProfileParser.getKeyParameter(), timeSeriesProfileParser.getOfficeId()); + TimeSeriesProfileParser retrieved = timeSeriesProfileParserDao.retrieveTimeSeriesProfileParser(timeSeriesProfileParser.getLocationId().getName(), + timeSeriesProfileParser.getKeyParameter(), timeSeriesProfileParser.getLocationId().getOfficeId()); assertEquals(timeSeriesProfileParser, retrieved); - timeSeriesProfileParserDao.deleteTimeSeriesProfileParser(timeSeriesProfileParser.getLocationId(), - timeSeriesProfileParser.getKeyParameter(), timeSeriesProfileParser.getOfficeId()); + timeSeriesProfileParserDao.deleteTimeSeriesProfileParser(timeSeriesProfileParser.getLocationId().getName(), + timeSeriesProfileParser.getKeyParameter(), timeSeriesProfileParser.getLocationId().getOfficeId()); + + timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfile.getLocationId().getName(),timeSeriesProfile.getKeyParameter(), + timeSeriesProfile.getLocationId().getOfficeId()); }); } @@ -95,45 +101,101 @@ void testStoreAndDelete() throws SQLException TimeSeriesProfileDao timeSeriesProfileDao = new TimeSeriesProfileDao(context); - TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile(); + TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile("Depth"); timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfile, false); TimeSeriesProfileParserDao timeSeriesProfileParserDao = new TimeSeriesProfileParserDao(context); - TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser(); + TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser("Depth"); timeSeriesProfileParserDao.storeTimeSeriesProfileParser(timeSeriesProfileParser, false); - timeSeriesProfileParserDao.deleteTimeSeriesProfileParser(timeSeriesProfileParser.getLocationId(), - timeSeriesProfileParser.getKeyParameter(), timeSeriesProfileParser.getOfficeId()); + timeSeriesProfileParserDao.deleteTimeSeriesProfileParser(timeSeriesProfileParser.getLocationId().getName(), + timeSeriesProfileParser.getKeyParameter(), timeSeriesProfileParser.getLocationId().getOfficeId()); assertThrows(Exception.class, ()->timeSeriesProfileParserDao.retrieveTimeSeriesProfileParser( - timeSeriesProfileParser.getLocationId(), - timeSeriesProfileParser.getKeyParameter(), timeSeriesProfileParser.getOfficeId())); + timeSeriesProfileParser.getLocationId().getName(), + timeSeriesProfileParser.getKeyParameter(), timeSeriesProfileParser.getLocationId().getOfficeId())); + timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfile.getLocationId().getName(), timeSeriesProfile.getKeyParameter(), + timeSeriesProfile.getLocationId().getOfficeId()); }); } @Test - void testStoreAndRetrieveMultiple() + void testStoreAndRetrieveMultiple() throws SQLException { - // TODO + CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); + databaseLink.connection(c -> { + DSLContext context = getDslContext(c, databaseLink.getOfficeId()); + + TimeSeriesProfileDao timeSeriesProfileDao = new TimeSeriesProfileDao(context); + + TimeSeriesProfile timeSeriesProfileDepth = buildTestTimeSeriesProfile("Depth"); + timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfileDepth, false); + TimeSeriesProfile timeSeriesProfileTemp = buildTestTimeSeriesProfile("Temp-Water"); + timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfileTemp, false); + + TimeSeriesProfileParserDao timeSeriesProfileParserDao = new TimeSeriesProfileParserDao(context); + TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser("Depth"); + timeSeriesProfileParserDao.storeTimeSeriesProfileParser(timeSeriesProfileParser, false); + + timeSeriesProfileParser = buildTestTimeSeriesProfileParser("Temp-Water"); + timeSeriesProfileParserDao.storeTimeSeriesProfileParser(timeSeriesProfileParser, false); + + List profileParserList = timeSeriesProfileParserDao.retrieveTimeSeriesProfileParsers("*", "*", "*"); + List profileParserList1; +// assertEquals(2, profileParserList.size()); + for(TimeSeriesProfileParser profileParser : profileParserList) + { + timeSeriesProfileParserDao.deleteTimeSeriesProfileParser(profileParser.getLocationId().getName(),profileParser.getKeyParameter(),profileParser.getLocationId().getOfficeId()); + profileParserList1 = timeSeriesProfileParserDao.retrieveTimeSeriesProfileParsers("*", "*", "*"); + } + + timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfileDepth.getLocationId().getName(),timeSeriesProfileDepth.getKeyParameter(), + timeSeriesProfileDepth.getLocationId().getOfficeId()); + timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfileTemp.getLocationId().getName(),timeSeriesProfileTemp.getKeyParameter(), + timeSeriesProfileTemp.getLocationId().getOfficeId()); + }); } @Test - void testStoreAndCopy() + void testStoreAndCopy() throws SQLException { - // TODO + CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); + databaseLink.connection(c -> { + DSLContext context = getDslContext(c, databaseLink.getOfficeId()); + + TimeSeriesProfileDao timeSeriesProfileDao = new TimeSeriesProfileDao(context); + + TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile("Depth"); + timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfile, false); + + TimeSeriesProfileParserDao timeSeriesProfileParserDao = new TimeSeriesProfileParserDao(context); + TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser("Depth"); + timeSeriesProfileParserDao.storeTimeSeriesProfileParser(timeSeriesProfileParser, false); + + TimeSeriesProfileParser retrieved = timeSeriesProfileParserDao.retrieveTimeSeriesProfileParser(timeSeriesProfileParser.getLocationId().getName(), + timeSeriesProfileParser.getKeyParameter(), timeSeriesProfileParser.getLocationId().getOfficeId()); + +// timeSeriesProfileParserDao.copyTimeSeriesProfileParser(timeSeriesProfileParser.getLocationId(), +// timeSeriesProfileParser.getKeyParameter(), timeSeriesProfileParser.getOfficeId(), "AAA"); + + TimeSeriesProfileParser retrieved1 = timeSeriesProfileParserDao.retrieveTimeSeriesProfileParser("AAA", + timeSeriesProfileParser.getKeyParameter(), timeSeriesProfileParser.getLocationId().getOfficeId()); + assertEquals(timeSeriesProfileParser, retrieved); + + }); } - private static TimeSeriesProfile buildTestTimeSeriesProfile() + private static TimeSeriesProfile buildTestTimeSeriesProfile(String parameter) { - String officeId = CwmsDataApiSetupCallback.getDatabaseLink().getOfficeId(); + String officeId = "HEC"; + CwmsId locationId = new CwmsId.Builder().withOfficeId(officeId).withName("location").build(); return new TimeSeriesProfile.Builder() - .withOfficeId(officeId) - .withLocationId("TIMESERIESPROFILE_LOC") - .withKeyParameter("Depth") - .withParameterList(Arrays.asList(new String[]{"Pres", "Depth"})) + .withLocationId(locationId) + .withKeyParameter(parameter) + .withParameterList(Arrays.asList(new String[]{"Temp-Water", "Depth"})) .build(); } - private static TimeSeriesProfileParser buildTestTimeSeriesProfileParser() { + private static TimeSeriesProfileParser buildTestTimeSeriesProfileParser(String keyParameter) { List parameterInfoList = new ArrayList<>(); parameterInfoList.add( new ParameterInfo.Builder() .withParameter("Depth") @@ -146,13 +208,13 @@ private static TimeSeriesProfileParser buildTestTimeSeriesProfileParser() { .withUnit("F") .build()); - String officeId = CwmsDataApiSetupCallback.getDatabaseLink().getOfficeId(); + String officeId = "HEC"; + CwmsId locationId = new CwmsId.Builder().withOfficeId(officeId).withName("location").build(); return new TimeSeriesProfileParser.Builder() - .withOfficeId(officeId) - .withLocationId("TIMESERIESPROFILE_LOC") - .withKeyParameter("Depth") + .withLocationId(locationId) + .withKeyParameter(keyParameter) .withRecordDelimiter((char) 10) .withFieldDelimiter(',') .withTimeFormat("MM/DD/YYYY,HH24:MI:SS") @@ -163,9 +225,9 @@ private static TimeSeriesProfileParser buildTestTimeSeriesProfileParser() { .build(); } - private static Location buildTestLocation() { - String officeId = CwmsDataApiSetupCallback.getDatabaseLink().getOfficeId(); - return new Location.Builder("TIMESERIESPROFILE_LOC", "SITE", ZoneId.of("UTC"), + private static Location buildTestLocation(String location) { + String officeId = "HEC";//CwmsDataApiSetupCallback.getDatabaseLink().getOfficeId(); + return new Location.Builder(location, "SITE", ZoneId.of("UTC"), 38.5613824, -121.7298432, "NVGD29", officeId) .withElevation(10.0) .withLocationType("SITE") diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfoTest.java b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfoTest.java deleted file mode 100644 index 2539a6c88..000000000 --- a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfoTest.java +++ /dev/null @@ -1,4 +0,0 @@ -package cwms.cda.data.dto.timeseriesprofile; - -public class ParameterInfoTest { -} diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstanceTest.java b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstanceTest.java index cfe9955b3..ea9c786cc 100644 --- a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstanceTest.java +++ b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstanceTest.java @@ -1,4 +1,104 @@ package cwms.cda.data.dto.timeseriesprofile; +import cwms.cda.formatters.ContentType; +import cwms.cda.formatters.Formats; +import org.apache.commons.io.IOUtils; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.time.Instant; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + public class TimeSeriesProfileInstanceTest { + private static final Map PARAMETER_UNIT_MAP = new HashMap<>(); + @BeforeAll + public static void setup() throws Exception { + PARAMETER_UNIT_MAP.put("Depth", "ft"); + PARAMETER_UNIT_MAP.put("Temperature", "F"); + } + @Test + void testTimeSeriesProfileInstanceSerializationRoundTrip() { + TimeSeriesProfileInstance timeSeriesProfileInstance = buildTestTimeSeriesProfileInstance(); + ContentType contentType = Formats.parseHeader(Formats.JSONV2, TimeSeriesProfileInstance.class); + + String serialized = Formats.format(contentType, timeSeriesProfileInstance); + TimeSeriesProfileInstance deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2, TimeSeriesProfileInstance.class), serialized, TimeSeriesProfileInstance.class); + testAssertEquals(timeSeriesProfileInstance, deserialized, "Roundtrip serialization failed"); + } + @Test + void testTimeSeriesProfileInstanceSerializationRoundTripFromFile() throws Exception { + TimeSeriesProfileInstance timeSeriesProfileInstance = buildTestTimeSeriesProfileInstance(); + InputStream resource = this.getClass().getResourceAsStream("/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileinstance.json"); + assertNotNull(resource); + String serialized = IOUtils.toString(resource, StandardCharsets.UTF_8); + TimeSeriesProfileInstance deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2, TimeSeriesProfileInstance.class), serialized, TimeSeriesProfileInstance.class); + testAssertEquals(timeSeriesProfileInstance, deserialized, "Roundtrip serialization from file failed"); + } + + private TimeSeriesProfileInstance buildTestTimeSeriesProfileInstance() { + TimeSeriesProfile timeSeriesProfile = TimeSeriesProfileTest.buildTestTimeSeriesProfile(); + List timeSeriesList = buildTimeSeriesList(timeSeriesProfile.getParameterList()); + return new TimeSeriesProfileInstance.Builder() + .withTimeSeriesProfile(timeSeriesProfile) + .withTimeSeriesList(timeSeriesList) + .build(); + } + + private List buildTimeSeriesList(List parameterList) { + List timeSeriesList = new ArrayList<>(); + for(String parameter : parameterList) + { + ProfileTimeSeries profileTimeSeries = new ProfileTimeSeries.Builder() + .withParameter(parameter) + .withUnit(PARAMETER_UNIT_MAP.get(parameter)) + .withTimeZone("PST") + .withTimeValuePairList(buildTimeValueList()) + .build(); + timeSeriesList.add(profileTimeSeries); + } + return timeSeriesList; + } + + private List buildTimeValueList() { + List timeValueList = new ArrayList<>(); + timeValueList.add( new TimeValuePair.Builder().withValue(1.0).withDateTime(Instant.parse("2021-02-09T11:19:42.12Z")).build()); + timeValueList.add( new TimeValuePair.Builder().withValue(3.0).withDateTime(Instant.parse("2021-02-09T11:19:42.22Z")).build()); + return timeValueList; + } + + private void testAssertEquals(TimeSeriesProfileInstance expected, TimeSeriesProfileInstance actual, String message) { + TimeSeriesProfileTest.testAssertEquals(expected.getTimeSeriesProfile(), actual.getTimeSeriesProfile(), message); + testAssertEquals(expected.getTimeSeriesList(), actual.getTimeSeriesList(), message); + } + + private void testAssertEquals(List expected, List actual, String message) { + assertEquals(expected.size(), actual.size(), message); + for (int i = 0; i < expected.size(); i++) { + testAssertEquals(expected.get(i), actual.get(i), message); + } + } + + private void testAssertEquals(ProfileTimeSeries expected, ProfileTimeSeries actual, String message) { + assertEquals(expected.getTimeZone(), actual.getTimeZone(), message); + assertEquals(expected.getParameter(), actual.getParameter(), message); + assertEquals(expected.getUnit(),actual.getUnit(), message); + testAssertEquals(expected.getTimeValuePairList(), actual.getTimeValuePairList()); + } + + private void testAssertEquals(List expected, List actual) { + assertEquals(expected.size(), actual.size()); + for(int i=0;i Date: Fri, 19 Jul 2024 13:12:43 -0700 Subject: [PATCH 16/26] unit test for timeseries profile instance, cleanup code --- .../TimeSeriesProfileDao.java | 180 +++---- .../TimeSeriesProfileInstanceDao.java | 330 ++++++++++++- .../TimeSeriesProfileInstance.java | 55 ++- .../dto/timeseriesprofile/TimeValuePair.java | 2 +- .../TimeSeriesProfileDaoIT.java | 275 +++++------ .../TimeSeriesProfileInstanceDaoIT.java | 460 ++++++++++++++++++ .../TimeSeriesProfileParserDaoIT.java | 391 +++++++-------- .../TimeSeriesProfileParserTest.java | 12 +- .../TimeSeriesProfileTest.java | 13 +- 9 files changed, 1227 insertions(+), 491 deletions(-) create mode 100644 cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDaoIT.java diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileDao.java b/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileDao.java index 5ce24edb0..090987ecb 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileDao.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileDao.java @@ -2,7 +2,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.stream.Collectors; import cwms.cda.data.dao.JooqDao; import cwms.cda.data.dto.CwmsId; @@ -16,92 +15,97 @@ import usace.cwms.db.jooq.codegen.udt.records.STR_TAB_T; import usace.cwms.db.jooq.codegen.udt.records.TS_PROFILE_T; -public class TimeSeriesProfileDao extends JooqDao -{ - public TimeSeriesProfileDao(DSLContext dsl) - { - super(dsl); - } - public void storeTimeSeriesProfile(TimeSeriesProfile timeSeriesProfile, boolean failIfExists) { +public class TimeSeriesProfileDao extends JooqDao { + public TimeSeriesProfileDao(DSLContext dsl) { + super(dsl); + } - connection(dsl, conn -> { - List parameterList = timeSeriesProfile.getParameterList(); - String parameterString = parameterList.get(0); - for(int i=1; i { - TS_PROFILE_T timeSeriesProfile = CWMS_TS_PROFILE_PACKAGE.call_RETRIEVE_TS_PROFILE( - DSL.using(conn).configuration(), locationId, parameterId, officeId); - return map(timeSeriesProfile, locationId, parameterId, officeId); - }); - } - public void deleteTimeSeriesProfile(String locationId, String keyParameter, String officeId) - { - connection(dsl, conn -> - CWMS_TS_PROFILE_PACKAGE.call_DELETE_TS_PROFILE(DSL.using(conn).configuration(),locationId, keyParameter, "DELETE ALL", - officeId)); - } - public void copyTimeSeriesProfile(String locationId, String keyParameter, String destinationLocation, String destRefTsId, String officeId) - { - connection(dsl, conn -> - CWMS_TS_PROFILE_PACKAGE.call_COPY_TS_PROFILE(DSL.using(conn).configuration(),locationId, keyParameter, destinationLocation, - destRefTsId, "F", "F", - officeId)); - } - public List retrieveTimeSeriesProfiles(String locationIdMask, String parameterIdMask, String officeIdMask) - { - return connectionResult(dsl, conn -> { - List timeSeriesProfileList = new ArrayList<>(); - Result timeSeriesProfileResults = CWMS_TS_PROFILE_PACKAGE.call_CAT_TS_PROFILE( - DSL.using(conn).configuration(), locationIdMask, parameterIdMask, officeIdMask); - for(int i=0; i values = ( Result)timeSeriesProfileResults.get(i).get("VALUE_PARAMETERS"); - List parameterList = new ArrayList<>(); - for(int j=0; j parameterList = profileParams.stream().collect(Collectors.toList()); - CwmsId locationId = new CwmsId.Builder().withName(locationName).withOfficeId(officeId).build(); - CwmsId referenceTsId = new CwmsId.Builder().withName(timeSeriesProfile.getREFERENCE_TS_ID()).withOfficeId(officeId).build(); - return new TimeSeriesProfile.Builder() - .withLocationId(locationId) - .withDescription(timeSeriesProfile.getDESCRIPTION()) - .withReferenceTsId(referenceTsId) - .withKeyParameter(keyParameter) - .withParameterList(parameterList) - .build(); - } + public void storeTimeSeriesProfile(TimeSeriesProfile timeSeriesProfile, boolean failIfExists) { + + connection(dsl, conn -> { + List parameterList = timeSeriesProfile.getParameterList(); + StringBuilder parameterString = new StringBuilder(parameterList.get(0)); + + for (int i = 1; i < parameterList.size(); i++) { + parameterString.append(",").append(parameterList.get(i)); + } + String referenceTsId = null; + if (timeSeriesProfile.getReferenceTsId() != null) { + referenceTsId = timeSeriesProfile.getReferenceTsId().getName(); + } + CWMS_TS_PROFILE_PACKAGE.call_STORE_TS_PROFILE(DSL.using(conn).configuration(), timeSeriesProfile.getLocationId().getName(), + timeSeriesProfile.getKeyParameter(), + parameterString.toString(), + timeSeriesProfile.getDescription(), referenceTsId, failIfExists?"T":"F", "T", timeSeriesProfile.getLocationId().getOfficeId()); + }); + } + + public TimeSeriesProfile retrieveTimeSeriesProfile(String locationId, String parameterId, String officeId) { + return connectionResult(dsl, conn -> { + TS_PROFILE_T timeSeriesProfile = CWMS_TS_PROFILE_PACKAGE.call_RETRIEVE_TS_PROFILE( + DSL.using(conn).configuration(), locationId, parameterId, officeId); + return map(timeSeriesProfile, locationId, parameterId, officeId); + }); + } + + public void deleteTimeSeriesProfile(String locationId, String keyParameter, String officeId) { + connection(dsl, conn -> + CWMS_TS_PROFILE_PACKAGE.call_DELETE_TS_PROFILE(DSL.using(conn).configuration(), locationId, keyParameter, "DELETE ALL", + officeId)); + } + + public void copyTimeSeriesProfile(String locationId, String keyParameter, String destinationLocation, String destRefTsId, String officeId) { + connection(dsl, conn -> + CWMS_TS_PROFILE_PACKAGE.call_COPY_TS_PROFILE(DSL.using(conn).configuration(), locationId, keyParameter, destinationLocation, + destRefTsId, "F", "F", + officeId)); + } + + public List retrieveTimeSeriesProfiles(String locationIdMask, String parameterIdMask, String officeIdMask) { + return connectionResult(dsl, conn -> { + List timeSeriesProfileList = new ArrayList<>(); + Result timeSeriesProfileResults = CWMS_TS_PROFILE_PACKAGE.call_CAT_TS_PROFILE( + DSL.using(conn).configuration(), locationIdMask, parameterIdMask, officeIdMask); + for (Record timeSeriesProfileResult : timeSeriesProfileResults) { + Result values = timeSeriesProfileResult.get("VALUE_PARAMETERS", Result.class); + List parameterList = new ArrayList<>(); + for (Record value : values) { + parameterList.add(value.get("PARMETER_ID", String.class)); + } + CwmsId locationId = new CwmsId.Builder() + .withName((String) timeSeriesProfileResult.get("LOCATION_ID")) + .withOfficeId((String) timeSeriesProfileResult.get("OFFICE_ID")) + .build(); + CwmsId referenceTsId = new CwmsId.Builder() + .withName((String) timeSeriesProfileResult.get("REF_TS_ID")) + .withOfficeId((String) timeSeriesProfileResult.get("OFFICE_ID")) + .build(); + timeSeriesProfileList.add(new TimeSeriesProfile.Builder() + .withDescription((String) timeSeriesProfileResult.get("DESCRIPTION")) + .withReferenceTsId(referenceTsId) + .withKeyParameter((String) timeSeriesProfileResult.get("KEY_PARAMETER_ID")) + .withLocationId(locationId) + .withParameterList(parameterList) + .build()); + } + return timeSeriesProfileList; + }); + } + + private TimeSeriesProfile map(TS_PROFILE_T timeSeriesProfile, String locationName, String keyParameter, String officeId) { + STR_TAB_T profileParams = timeSeriesProfile.getPROFILE_PARAMS(); + List parameterList = new ArrayList<>(profileParams); + CwmsId locationId = new CwmsId.Builder().withName(locationName).withOfficeId(officeId).build(); + CwmsId referenceTsId = null; + if (timeSeriesProfile.getREFERENCE_TS_ID() != null) { + referenceTsId = new CwmsId.Builder().withName(timeSeriesProfile.getREFERENCE_TS_ID()).withOfficeId(officeId).build(); + } + return new TimeSeriesProfile.Builder() + .withLocationId(locationId) + .withDescription(timeSeriesProfile.getDESCRIPTION()) + .withReferenceTsId(referenceTsId) + .withKeyParameter(keyParameter) + .withParameterList(parameterList) + .build(); + } } diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDao.java b/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDao.java index defae7ce6..0bdeffc02 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDao.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDao.java @@ -1,21 +1,331 @@ package cwms.cda.data.dao.timeseriesprofile; -public class TimeSeriesProfileInstanceDao +import cwms.cda.data.dao.JooqDao; +import cwms.cda.data.dto.CwmsId; +import cwms.cda.data.dto.timeseriesprofile.ProfileTimeSeries; +import cwms.cda.data.dto.timeseriesprofile.TimeSeriesProfile; +import cwms.cda.data.dto.timeseriesprofile.TimeSeriesProfileInstance; +import cwms.cda.data.dto.timeseriesprofile.TimeValuePair; +import org.jetbrains.annotations.NotNull; +import org.jooq.Configuration; +import org.jooq.DSLContext; +import org.jooq.Record; +import org.jooq.Result; +import org.jooq.impl.DSL; +import usace.cwms.db.jooq.codegen.packages.CWMS_LOC_PACKAGE; +import usace.cwms.db.jooq.codegen.packages.CWMS_TS_PROFILE_PACKAGE; +import usace.cwms.db.jooq.codegen.packages.CWMS_UTIL_PACKAGE; +import usace.cwms.db.jooq.codegen.udt.records.PVQ_T; +import usace.cwms.db.jooq.codegen.udt.records.PVQ_TAB_T; +import usace.cwms.db.jooq.codegen.udt.records.STR_TAB_T; +import usace.cwms.db.jooq.codegen.udt.records.TS_PROF_DATA_REC_T; +import usace.cwms.db.jooq.codegen.udt.records.TS_PROF_DATA_T; +import usace.cwms.db.jooq.codegen.udt.records.TS_PROF_DATA_TAB_T; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.sql.Timestamp; +import java.time.Instant; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class TimeSeriesProfileInstanceDao extends JooqDao { - void storeTimeSeriesProfileInstance() + public TimeSeriesProfileInstanceDao(DSLContext dsl) + { + super(dsl); + } + + void storeTimeSeriesProfileInstance(TimeSeriesProfile timeSeriesProfile, String profileData, Instant versionDate, + String versionId, String storeRule, boolean overrideProtection) + { + connection(dsl, conn -> { + try { + CWMS_TS_PROFILE_PACKAGE.call_STORE_TS_PROFILE_INSTANCE__2(DSL.using(conn).configuration(), + timeSeriesProfile.getLocationId().getName(), + timeSeriesProfile.getKeyParameter(), + profileData, + versionId, + storeRule, + overrideProtection?"T":"F", + Timestamp.from(versionDate), + timeSeriesProfile.getLocationId().getOfficeId()); + } catch (Exception ex) { + ex.printStackTrace(); + } + }); + } + + void storeTimeSeriesProfileInstance(TimeSeriesProfileInstance timeseriesProfileInstance, String versionId, Instant versionInstant, String storeRule,String overrideProtection) { - // TODO + connection(dsl, conn -> { + BigDecimal locationCodeId = CWMS_LOC_PACKAGE.call_GET_LOCATION_CODE(DSL.using(conn).configuration(), + timeseriesProfileInstance.getTimeSeriesProfile().getLocationId().getOfficeId(), + timeseriesProfileInstance.getTimeSeriesProfile().getLocationId().getName()); + + + Map parameterIdToCode = new HashMap<>(); + + String parameter = timeseriesProfileInstance.getTimeSeriesProfile().getKeyParameter(); + BigDecimal parameterCodeDec = CWMS_UTIL_PACKAGE.call_GET_PARAMETER_CODE(DSL.using(conn).configuration(), parameter, + timeseriesProfileInstance.getTimeSeriesProfile().getLocationId().getOfficeId()); + parameterIdToCode.put(parameter, parameterCodeDec.toBigInteger()); + + List timeSeriesList = timeseriesProfileInstance.getTimeSeriesList(); + for(ProfileTimeSeries profileTimeSeries : timeSeriesList) + { + parameter = profileTimeSeries.getParameter(); + parameterCodeDec = CWMS_UTIL_PACKAGE.call_GET_PARAMETER_CODE(DSL.using(conn).configuration(), parameter, + timeseriesProfileInstance.getTimeSeriesProfile().getLocationId().getOfficeId()); + parameterIdToCode.put(parameter, parameterCodeDec.toBigInteger()); + } + + TS_PROF_DATA_T tsProfileData = new TS_PROF_DATA_T(); + tsProfileData.attach(DSL.using(conn).configuration()); + + TS_PROF_DATA_TAB_T records = new TS_PROF_DATA_TAB_T(); + + for(int i=0; i retrieveTimeSeriesProfileInstances( String officeIdMask, String locationMask, String parameterMask, String versionMask, + Instant startTime, Instant endTime, String timeZone) { - // TODO + return connectionResult(dsl, conn -> { + List instanceList = new ArrayList<>(); + Result results = CWMS_TS_PROFILE_PACKAGE.call_CAT_TS_PROFILE_INSTANCE(DSL.using(conn).configuration(), + locationMask, parameterMask, versionMask, Timestamp.from(startTime), Timestamp.from(endTime), + timeZone, officeIdMask); + for (Record result : results) { + CwmsId locationId = new CwmsId.Builder() + .withOfficeId((String) result.get(0)) + .withName((String) result.get(1)) + .build(); + String parameterId = (String) result.get(2); + TimeSeriesProfile timeSeriesProfile = new TimeSeriesProfile.Builder() + .withLocationId(locationId) + .withKeyParameter(parameterId) + .build(); + TimeSeriesProfileInstance timeSeriesProfileInstance = new TimeSeriesProfileInstance.Builder() + .withTimeSeriesProfile(timeSeriesProfile) + .withVersion(result.get(3, String.class)) + .withVersionDate(result.get(4, Instant.class)) + .withFirstDate(result.get(5, Instant.class)) + .withLastDate(result.get(6, Instant.class)) + .build(); + + instanceList.add(timeSeriesProfileInstance); + } + return instanceList; + }); } - void retrieveTimeSeriesProfileInstances() + + TimeSeriesProfileInstance retrieveTimeSeriesProfileInstance(CwmsId location, String keyParameter, + String version, + String unit, + Instant startTime, + Instant endTime, + String timeZone, + String startInclusive, + String endInclusive, + String previous, + String next, + Instant versionDate, + String maxVersion) { - // TODO + return connectionResult(dsl, conn -> { + TS_PROF_DATA_T timeSeriesProfileData; + try { + timeSeriesProfileData = CWMS_TS_PROFILE_PACKAGE.call_RETRIEVE_TS_PROFILE_DATA( + DSL.using(conn).configuration(), + location.getName(), + keyParameter, + version, + unit, + Timestamp.from(startTime), + Timestamp.from(endTime), + timeZone, + startInclusive, + endInclusive, + previous, + next, + null,//Timestamp.from(versionDate), + maxVersion, + location.getOfficeId() + ); + } + catch(Exception ex) + { + ex.printStackTrace(); + return null; + } + return map(DSL.using(conn).configuration(), location.getOfficeId(), timeSeriesProfileData); + }); } - void deleteTimeSeriesProfileInstance() + void deleteTimeSeriesProfileInstance(CwmsId location, String keyParameter, + String version, Instant firstDate, String timeZone,boolean overrideProtection, Instant versionDate) { - // TODO + connection(dsl, conn -> { + + Timestamp versionTimestamp = null; + if(versionDate!=null) + { + versionTimestamp = Timestamp.from(versionDate); + } + + try { + CWMS_TS_PROFILE_PACKAGE.call_DELETE_TS_PROFILE_INSTANCE( + DSL.using(conn).configuration(), + location.getName(), + keyParameter, + version, + Timestamp.from(firstDate), + timeZone, + overrideProtection?"T":"F", + versionTimestamp, + location.getOfficeId() + ); + } + catch (Exception ex) + { + ex.printStackTrace(); + } + }); + } + + + private TimeSeriesProfileInstance map(@NotNull Configuration configuration, String officeId, TS_PROF_DATA_T timeSeriesProfileData) { + String timeZone = timeSeriesProfileData.getTIME_ZONE(); + STR_TAB_T units = timeSeriesProfileData.getUNITS(); + TS_PROF_DATA_TAB_T records = timeSeriesProfileData.getRECORDS(); + BigInteger locationCode = timeSeriesProfileData.getLOCATION_CODE(); + String location = CWMS_UTIL_PACKAGE.call_GET_LOCATION_ID(configuration, locationCode, officeId); + BigInteger keyParameterCode = timeSeriesProfileData.getKEY_PARAMETER(); + String keyParameter = CWMS_UTIL_PACKAGE.call_GET_PARAMETER_ID(configuration, keyParameterCode); + List timeList = new ArrayList<>(); + List> valuesList = new ArrayList<>(); + List> parametersList = new ArrayList<>(); + List> qualitiesList = new ArrayList<>(); + for(TS_PROF_DATA_REC_T dataRecord : records) + { + Instant dateTime = dataRecord.get(0, Instant.class); + timeList.add(dateTime); + PVQ_TAB_T parameters = dataRecord.getPARAMETERS(); + List valueList = new ArrayList<>(); + List qualityList = new ArrayList<>(); + List parameterList = new ArrayList<>(); + for(PVQ_T parameter : parameters) + { + qualityList.add(parameter.getQUALITY_CODE()); + valueList.add(parameter.getVALUE()); + parameterList.add(parameter.getPARAMETER_CODE()); + } + qualitiesList.add(qualityList); + valuesList.add(valueList); + parametersList.add(parameterList); + } + List parameterList = new ArrayList<>(); + List> timeValuePairList = new ArrayList<>(); + if(!parametersList.isEmpty()) { + for (int i = 0; i < parametersList.get(0).size(); i++) { + String parameter = CWMS_UTIL_PACKAGE.call_GET_PARAMETER_ID(configuration, parametersList.get(0).get(i)); + parameterList.add(parameter); + timeValuePairList.add(new ArrayList<>()); + } + } + if(!valuesList.isEmpty()) + { + for(int i = 0; i timeSeriesList = new ArrayList<>(); + if(!timeValuePairList.isEmpty()) { + for (int i = 0; i < timeValuePairList.size(); i++) { + ProfileTimeSeries timeSeries = new ProfileTimeSeries.Builder() + .withTimeValuePairList(timeValuePairList.get(i)) + .withTimeZone(timeZone) + .withParameter(parameterList.get(i)) + .withUnit(units.get(i)) + .build(); + timeSeriesList.add(timeSeries); + } + } + CwmsId locationId = new CwmsId.Builder() + .withOfficeId(officeId) + .withName(location) + .build(); + TimeSeriesProfile timeSeriesProfile = new TimeSeriesProfile.Builder() + .withKeyParameter(keyParameter) + .withLocationId(locationId) + .withParameterList(parameterList) + .build(); + return new TimeSeriesProfileInstance.Builder() + .withTimeSeriesProfile(timeSeriesProfile) + .withTimeSeriesList(timeSeriesList) + .build(); } -} +} \ No newline at end of file diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstance.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstance.java index 469940e54..cfa480fd9 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstance.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstance.java @@ -6,11 +6,13 @@ import com.fasterxml.jackson.databind.annotation.JsonNaming; import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; import cwms.cda.api.errors.FieldException; +import cwms.cda.api.errors.RequiredFieldException; import cwms.cda.data.dto.CwmsDTOBase; import cwms.cda.formatters.Formats; import cwms.cda.formatters.annotations.FormattableWith; import cwms.cda.formatters.json.JsonV2; +import java.time.Instant; import java.util.List; @FormattableWith(contentType = Formats.JSONV2, formatter = JsonV2.class) @@ -20,11 +22,19 @@ public final class TimeSeriesProfileInstance implements CwmsDTOBase { private final TimeSeriesProfile timeSeriesProfile; private final List timeSeriesList; + private final String version; + private final Instant versionDate; + private final Instant firstDate; + private final Instant lastDate; private TimeSeriesProfileInstance(Builder builder) { timeSeriesList = builder.timeSeriesList; timeSeriesProfile = builder.timeSeriesProfile; + version = builder.version; + versionDate = builder.versionDate; + firstDate = builder.firstDate; + lastDate = builder.lastDate; } public TimeSeriesProfile getTimeSeriesProfile() { @@ -35,15 +45,38 @@ public List getTimeSeriesList() { return timeSeriesList; } + public String getVersion() + { + return version; + } + public Instant getVersionDate() + { + return versionDate; + } + public Instant getFirstDate() + { + return firstDate; + } + public Instant getLastDate() + { + return lastDate; + } @Override public void validate() throws FieldException { - + if(timeSeriesProfile==null) + { + throw new RequiredFieldException("timeSeriesProfile"); + } } @JsonPOJOBuilder @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) public static final class Builder { private List timeSeriesList; private TimeSeriesProfile timeSeriesProfile; + private String version; + private Instant versionDate; + private Instant firstDate; + private Instant lastDate; public TimeSeriesProfileInstance.Builder withTimeSeriesProfile(TimeSeriesProfile timeSeriesProfile) { this.timeSeriesProfile = timeSeriesProfile; @@ -55,6 +88,26 @@ public TimeSeriesProfileInstance.Builder withTimeSeriesList(List databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); - databaseLink.connection(c -> { - DSLContext context = getDslContext(c, databaseLink.getOfficeId()); - LocationsDaoImpl locationsDao = new LocationsDaoImpl(context); - try - { - locationsDao.storeLocation(LOCATION_AAA); - locationsDao.storeLocation(TIMESERIESPROFILE_LOC); - } - catch(IOException e) - { - throw new RuntimeException(e); - } - }); - } - - @AfterAll - public static void tearDown() throws Exception { - - CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); - databaseLink.connection(c -> { - DSLContext context = getDslContext(c, databaseLink.getOfficeId()); - LocationsDaoImpl locationsDao = new LocationsDaoImpl(context); - locationsDao.deleteLocation(LOCATION_AAA.getName(), LOCATION_AAA.getOfficeId()); - locationsDao.deleteLocation(TIMESERIESPROFILE_LOC.getName(), TIMESERIESPROFILE_LOC.getOfficeId()); - }); - } - - @Test - void testCopyTimeSeriesProfile() throws SQLException - { - CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); - databaseLink.connection(c -> { - DSLContext context = getDslContext(c, databaseLink.getOfficeId()); - - TimeSeriesProfileDao timeSeriesProfileDao = new TimeSeriesProfileDao(context); - - TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile("Depth"); - - timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfile, false); - timeSeriesProfileDao.copyTimeSeriesProfile(timeSeriesProfile.getLocationId().getName(), timeSeriesProfile.getKeyParameter(), - timeSeriesProfile.getLocationId().getName(),timeSeriesProfile.getReferenceTsId().getName(), - timeSeriesProfile.getLocationId().getOfficeId()); - TimeSeriesProfile timeSeriesProfileCopied = timeSeriesProfileDao.retrieveTimeSeriesProfile(timeSeriesProfile.getLocationId().getName(), - timeSeriesProfile.getKeyParameter(), timeSeriesProfile.getLocationId().getOfficeId()); - assertEquals("AAA", timeSeriesProfileCopied.getLocationId()); - assertEquals(timeSeriesProfile.getKeyParameter(), timeSeriesProfileCopied.getKeyParameter()); - assertEquals(timeSeriesProfile.getParameterList(),timeSeriesProfileCopied.getParameterList()); - - timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfile.getLocationId().getName(),timeSeriesProfile.getKeyParameter(),timeSeriesProfile.getLocationId().getOfficeId()); - timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfileCopied.getLocationId().getName(), - timeSeriesProfileCopied.getKeyParameter(),timeSeriesProfileCopied.getLocationId().getName()); - }); - } - @Test - void testRetrieveTimeSeriesProfile() throws Exception { - CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); - databaseLink.connection(c -> { - DSLContext context = getDslContext(c, databaseLink.getOfficeId()); - - TimeSeriesProfileDao timeSeriesProfileDao = new TimeSeriesProfileDao(context); - - TimeSeriesProfile timeSeriesProfileIn = (buildTestTimeSeriesProfile("Depth")); - timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfileIn, false); - - TimeSeriesProfile timeSeriesProfileOut = timeSeriesProfileDao.retrieveTimeSeriesProfile(timeSeriesProfileIn.getLocationId().getName(), - timeSeriesProfileIn.getKeyParameter(), timeSeriesProfileIn.getLocationId().getOfficeId()); - - assertEquals(timeSeriesProfileOut, timeSeriesProfileIn); - - timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfileIn.getLocationId().getName(), - timeSeriesProfileIn.getKeyParameter(), timeSeriesProfileIn.getLocationId().getOfficeId()); - }); - } - - @Test - void testRetrieveCatalog() throws Exception { - CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); - databaseLink.connection(c -> { - DSLContext context = getDslContext(c, databaseLink.getOfficeId()); - - TimeSeriesProfileDao timeSeriesProfileDao = new TimeSeriesProfileDao(context); - timeSeriesProfileDao.storeTimeSeriesProfile(buildTestTimeSeriesProfile("Depth"), false); - timeSeriesProfileDao.storeTimeSeriesProfile(buildTestTimeSeriesProfile("Pres"), false); - - - List timeSeriesProfileListBefore = - timeSeriesProfileDao.retrieveTimeSeriesProfiles("*", "*", "*"); - - for(TimeSeriesProfile timeSeriesProfile: timeSeriesProfileListBefore) - { - timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfile.getLocationId().getName(), timeSeriesProfile.getKeyParameter(), - timeSeriesProfile.getLocationId().getOfficeId()); - } - List timeSeriesProfileListAfter = timeSeriesProfileDao.retrieveTimeSeriesProfiles("*", "*", "*"); - - assertEquals(0,timeSeriesProfileListAfter.size()); - assertEquals(2,timeSeriesProfileListBefore.size()); - }); - } - @Test - void testDeleteTimeSeriesProfile() throws Exception { - CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); - databaseLink.connection(c -> { - DSLContext context = getDslContext(c, databaseLink.getOfficeId()); - - TimeSeriesProfileDao timeSeriesProfileDao = new TimeSeriesProfileDao(context); - TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile("Depth"); - timeSeriesProfileDao.storeTimeSeriesProfile(buildTestTimeSeriesProfile("Depth"), false); - - List timeSeriesProfileListBefore = - timeSeriesProfileDao.retrieveTimeSeriesProfiles("*", "*", "*"); - - timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfile.getLocationId().getName(), timeSeriesProfile.getKeyParameter(), - timeSeriesProfile.getLocationId().getOfficeId()); - - List timeSeriesProfileListAfter = - timeSeriesProfileDao.retrieveTimeSeriesProfiles("*", "*", "*"); - - - assertEquals(timeSeriesProfileListBefore.size()-1,timeSeriesProfileListAfter.size()); - }); - } - private static Location buildTestLocation(String location) { - String officeId = CwmsDataApiSetupCallback.getDatabaseLink().getOfficeId(); - return new Location.Builder(location, "SITE", ZoneId.of("UTC"), - 38.5613824, -121.7298432, "NVGD29", officeId) - .withElevation(10.0) - .withLocationType("SITE") - .withCountyName("Sacramento") - .withNation(Nation.US) - .withActive(true) - .withStateInitial("CA") - .withBoundingOfficeId(officeId) - .withPublishedLatitude(38.5613824) - .withPublishedLongitude(-121.7298432) - .withLongName("UNITED STATES") - .withDescription("for testing") - .build(); - } - private static TimeSeriesProfile buildTestTimeSeriesProfile(String keyParameter) - { - String officeId = CwmsDataApiSetupCallback.getDatabaseLink().getOfficeId(); - CwmsId locationId = new CwmsId.Builder().withOfficeId(officeId).withName("location").build(); - return new TimeSeriesProfile.Builder() - .withLocationId(locationId) - .withKeyParameter(keyParameter) - .withParameterList(Arrays.asList("Pres", "Depth")) - .build(); - - } +class TimeSeriesProfileDaoIT extends DataApiTestIT { + @Test + void testCopyTimeSeriesProfile() throws SQLException { + CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); + databaseLink.connection(c -> { + DSLContext context = getDslContext(c, databaseLink.getOfficeId()); + TimeSeriesProfileDao timeSeriesProfileDao = new TimeSeriesProfileDao(context); + TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile("Depth"); + timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfile, false); + timeSeriesProfileDao.copyTimeSeriesProfile(timeSeriesProfile.getLocationId().getName(), timeSeriesProfile.getKeyParameter(), + "BBB", null, + timeSeriesProfile.getLocationId().getOfficeId()); + TimeSeriesProfile timeSeriesProfileCopied = timeSeriesProfileDao.retrieveTimeSeriesProfile( + "BBB", + timeSeriesProfile.getKeyParameter(), timeSeriesProfile.getLocationId().getOfficeId()); + assertEquals("BBB", timeSeriesProfileCopied.getLocationId().getName()); + assertEquals(timeSeriesProfile.getKeyParameter(), timeSeriesProfileCopied.getKeyParameter()); + assertEquals(timeSeriesProfile.getParameterList(), timeSeriesProfileCopied.getParameterList()); + + timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfile.getLocationId().getName(), timeSeriesProfile.getKeyParameter(), timeSeriesProfile.getLocationId().getOfficeId()); + timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfileCopied.getLocationId().getName(), + timeSeriesProfileCopied.getKeyParameter(), timeSeriesProfileCopied.getLocationId().getOfficeId()); + }); + } + + @Test + void testRetrieveTimeSeriesProfile() throws Exception { + CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); + databaseLink.connection(c -> { + DSLContext context = getDslContext(c, databaseLink.getOfficeId()); + + TimeSeriesProfileDao timeSeriesProfileDao = new TimeSeriesProfileDao(context); + + TimeSeriesProfile timeSeriesProfileIn = (buildTestTimeSeriesProfile("Depth")); + timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfileIn, false); + + TimeSeriesProfile timeSeriesProfileOut = timeSeriesProfileDao.retrieveTimeSeriesProfile(timeSeriesProfileIn.getLocationId().getName(), + timeSeriesProfileIn.getKeyParameter(), timeSeriesProfileIn.getLocationId().getOfficeId()); + + timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfileIn.getLocationId().getName(), + timeSeriesProfileIn.getKeyParameter(), timeSeriesProfileIn.getLocationId().getOfficeId()); + + TimeSeriesProfileTest.testAssertEquals(timeSeriesProfileOut, timeSeriesProfileIn, ""); + + }); + } + + @Test + void testRetrieveCatalog() throws Exception { + CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); + databaseLink.connection(c -> { + DSLContext context = getDslContext(c, databaseLink.getOfficeId()); + + TimeSeriesProfileDao timeSeriesProfileDao = new TimeSeriesProfileDao(context); + timeSeriesProfileDao.storeTimeSeriesProfile(buildTestTimeSeriesProfile("Depth"), false); + timeSeriesProfileDao.storeTimeSeriesProfile(buildTestTimeSeriesProfile("Pres"), false); + + + List timeSeriesProfileListBefore = + timeSeriesProfileDao.retrieveTimeSeriesProfiles("*", "*", "*"); + + for (TimeSeriesProfile timeSeriesProfile : timeSeriesProfileListBefore) { + timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfile.getLocationId().getName(), timeSeriesProfile.getKeyParameter(), + timeSeriesProfile.getLocationId().getOfficeId()); + } + List timeSeriesProfileListAfter = timeSeriesProfileDao.retrieveTimeSeriesProfiles("*", "*", "*"); + + assertEquals(0, timeSeriesProfileListAfter.size()); + assertEquals(2, timeSeriesProfileListBefore.size()); + }); + } + + @Test + void testDeleteTimeSeriesProfile() throws Exception { + CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); + databaseLink.connection(c -> { + DSLContext context = getDslContext(c, databaseLink.getOfficeId()); + + TimeSeriesProfileDao timeSeriesProfileDao = new TimeSeriesProfileDao(context); + TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile("Depth"); + timeSeriesProfileDao.storeTimeSeriesProfile(buildTestTimeSeriesProfile("Depth"), false); + + List timeSeriesProfileListBefore = + timeSeriesProfileDao.retrieveTimeSeriesProfiles("*", "*", "*"); + + timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfile.getLocationId().getName(), timeSeriesProfile.getKeyParameter(), + timeSeriesProfile.getLocationId().getOfficeId()); + + List timeSeriesProfileListAfter = + timeSeriesProfileDao.retrieveTimeSeriesProfiles("*", "*", "*"); + + + assertEquals(timeSeriesProfileListBefore.size() - 1, timeSeriesProfileListAfter.size()); + }); + } + + static private TimeSeriesProfile buildTestTimeSeriesProfile(String keyParameter) { + String officeId = "HEC"; + CwmsId locationId = new CwmsId.Builder().withOfficeId(officeId).withName("AAA").build(); + CwmsId refTsId = new CwmsId.Builder().withOfficeId(officeId).withName("AAA.Pres.Inst.0.0.VERSION").build(); + return new TimeSeriesProfile.Builder() + .withLocationId(locationId) + .withKeyParameter(keyParameter) + .withParameterList(Arrays.asList("Pres", "Depth")) + .withDescription("description") + .withReferenceTsId(refTsId) + .build(); + + } } diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDaoIT.java b/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDaoIT.java new file mode 100644 index 000000000..46eb9f376 --- /dev/null +++ b/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDaoIT.java @@ -0,0 +1,460 @@ +package cwms.cda.data.dao.timeseriesprofile; + +import cwms.cda.api.DataApiTestIT; +import cwms.cda.data.dao.StoreRule; +import cwms.cda.data.dao.TimeSeriesIdentifierDescriptorDao; +import cwms.cda.data.dto.CwmsId; +import cwms.cda.data.dto.timeseriesprofile.ParameterInfo; +import cwms.cda.data.dto.timeseriesprofile.ProfileTimeSeries; +import cwms.cda.data.dto.timeseriesprofile.TimeSeriesProfile; +import cwms.cda.data.dto.timeseriesprofile.TimeSeriesProfileInstance; +import cwms.cda.data.dto.timeseriesprofile.TimeSeriesProfileParser; +import cwms.cda.data.dto.timeseriesprofile.TimeValuePair; +import fixtures.CwmsDataApiSetupCallback; +import mil.army.usace.hec.test.database.CwmsDatabaseContainer; +import org.jooq.DSLContext; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import java.sql.SQLException; +import java.time.Instant; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static cwms.cda.data.dao.DaoTest.getDslContext; +import static org.junit.jupiter.api.Assertions.*; + +@Tag("integration") +class TimeSeriesProfileInstanceDaoIT extends DataApiTestIT { + + @Test + void testStoreTimeSeriesProfileInstanceWithDataBlock() throws SQLException { + CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); + databaseLink.connection(c -> { + String officeId = "HEC"; + String locationName = "CCC"; + try { + createLocation(locationName, true, officeId); + } catch (SQLException e) { + throw new RuntimeException(e); + } + + String versionId = "VERSION"; + String unit = "kPa,m"; + String[] parameterArray = {"Depth", "Pres"}; + int[] parameterIndexArray = {5, 6}; + String[] parameterUnitArray = {"m", "kPa"}; + Instant versionDate = Instant.parse("2024-07-09T12:00:00.00Z"); + Instant startTime = Instant.parse("2018-07-09T19:06:20.00Z"); + Instant endTime = Instant.parse("2025-07-09T19:06:20.00Z"); + String profileData = "a\n09/09/2019,12:48:37,,5,6,7,8,9,10,11,12,13,\n09/09/2019,12:58:57,,5,6,7,8,9,10,11,12,13,\n"; + String timeZone = "UTC"; + String firstDate = "2019-09-09T12:48:57.00Z"; + boolean startInclusive = true; + boolean endInclusive = true; + boolean previous = true; + boolean next = true; + boolean maxVersion = true; + char fieldDelimiter = ','; + char recordDelimiter = '\n'; + int timeField = 1; + String timeFormat = "MM/DD/YYYY,HH24:MI:SS"; + + DSLContext context = getDslContext(c, databaseLink.getOfficeId()); + + // store a time series profile + TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile(officeId, locationName, parameterArray[0], parameterArray[1]); + TimeSeriesProfileDao profileDao = new TimeSeriesProfileDao(context); + profileDao.storeTimeSeriesProfile(timeSeriesProfile, false); + + // store a time series parser + TimeSeriesProfileParser parser = buildTestTimeSeriesProfileParser(officeId, locationName, parameterArray, parameterIndexArray, parameterUnitArray, recordDelimiter, fieldDelimiter, + timeFormat, timeZone, timeField); + TimeSeriesProfileParserDao timeSeriesProfileParserDao = new TimeSeriesProfileParserDao(context); + timeSeriesProfileParserDao.storeTimeSeriesProfileParser(parser, false); + + // create a time series profile instance and test storeTimeSeriesProfileInstance + TimeSeriesProfileInstanceDao timeSeriesProfileInstanceDao = new TimeSeriesProfileInstanceDao(context); + String storeRule = StoreRule.REPLACE_ALL.toString(); + timeSeriesProfileInstanceDao.storeTimeSeriesProfileInstance(timeSeriesProfile, profileData, versionDate, versionId, storeRule, false); + + try { + // retrieve the time series profile instance we just stored + TimeSeriesProfileInstance timeSeriesProfileInstance = retrieveTimeSeriesProfileInstance(officeId, locationName, parameterArray[0], versionId, unit, + startTime, endTime, timeZone, startInclusive, endInclusive, previous, next, versionDate, maxVersion); + // cleanup: delete the instance + timeSeriesProfileInstanceDao.deleteTimeSeriesProfileInstance(timeSeriesProfileInstance.getTimeSeriesProfile().getLocationId(), + timeSeriesProfileInstance.getTimeSeriesProfile().getKeyParameter(), + versionId, Instant.parse(firstDate), timeZone, false, versionDate); + // check if the instant contains the timeseries we stpred + assertEquals(parameterArray.length, timeSeriesProfileInstance.getTimeSeriesList().size()); + } catch (SQLException e) { + throw new RuntimeException(e); + } + // cleanup: remove the timeseries we stored + TimeSeriesIdentifierDescriptorDao timeSeriesDao = new TimeSeriesIdentifierDescriptorDao(context); + for(String parameter: parameterArray) { + timeSeriesDao.deleteAll(officeId, locationName + "." + parameter + ".Inst.0.0." + versionId); + timeSeriesDao.deleteAll(officeId, locationName + "." + parameter + ".Inst.0.0." + versionId); + } + }); + } + + @Test + void testRetrieveTimeSeriesProfileInstances() throws SQLException { + Instant versionDate = Instant.parse("2024-07-09T12:00:00.00Z"); + String officeId = "HEC"; + String location = "AAA"; + String[] keyParameter = {"Depth", "m"}; + String[] parameter1 = {"Pres", "psi"}; + String[] versions = {"VERSION", "VERSION2", "VERSION3"}; + String officeIdMask = "*"; + String locationMask = "*"; + String parameterMask = "*"; + String versionMask = "*"; + Instant startDate = Instant.parse("2020-07-09T12:00:00.00Z"); + Instant endDate = Instant.parse("2025-07-09T12:00:00.00Z"); + String timeZone = "UTC"; + Instant firstDate = Instant.parse("2024-07-09T19:00:11.00Z"); + Instant[] dateTimeArray = {Instant.parse("2024-07-09T19:00:11.00Z"), Instant.parse("2024-07-09T20:00:22.00Z")}; + double[] valueArray = {1, 4}; + + // sore a few timeseries profile instances + for (String version : versions) { + storeTimeSeriesProfileInstance(officeId, location, keyParameter, parameter1, version, versionDate, dateTimeArray, valueArray, timeZone); + } + CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); + + databaseLink.connection(c -> { + DSLContext context = getDslContext(c, databaseLink.getOfficeId()); + TimeSeriesProfileInstanceDao timeSeriesProfileInstanceDao = new TimeSeriesProfileInstanceDao(context); + // test retrieveTimeSeriesProfileInstances + List result = timeSeriesProfileInstanceDao.retrieveTimeSeriesProfileInstances(officeIdMask, locationMask, parameterMask, + versionMask, startDate, endDate, timeZone); + + // cleanup: delete the time series profile instances we created + boolean overrideProtection = false; + for (TimeSeriesProfileInstance timeSeriesProfileInstance : result) { + timeSeriesProfileInstanceDao.deleteTimeSeriesProfileInstance(timeSeriesProfileInstance.getTimeSeriesProfile().getLocationId(), + timeSeriesProfileInstance.getTimeSeriesProfile().getKeyParameter(), timeSeriesProfileInstance.getVersion(), + firstDate, timeZone, overrideProtection, timeSeriesProfileInstance.getVersionDate()); + } + // check if we retrieve all the instances we stored + assertEquals(versions.length, result.size()); + }); + } + + @Test + void testRetrieveTimeSeriesProfileInstance() throws SQLException { + String officeId = "HEC"; + String versionID = "VERSION"; + String locationName = "AAA"; + String[] keyParameter = {"Depth", "m"}; + String[] parameter1 = {"Pres", "psi"}; + String unit = "bar,m"; + Instant startTime = Instant.parse("2023-07-09T19:00:11.00Z"); + Instant endTime = Instant.parse("2025-01-01T19:00:22.00Z"); + String timeZone = "UTC"; + String startInclusive = "T"; + String endInclusive = "T"; + String previous = "T"; + String next = "T"; + String maxVersion = "T"; + Instant[] dateTimeArray = {Instant.parse("2024-07-09T19:00:11.00Z"), Instant.parse("2024-07-09T20:00:22.00Z")}; + double[] valueArray = {1, 4}; + Instant versionDate = Instant.parse("2024-07-09T12:00:00.00Z"); + + // store a time series profile instance + storeTimeSeriesProfileInstance(officeId, locationName, keyParameter, parameter1, versionID, versionDate, dateTimeArray, valueArray, timeZone); + CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); + databaseLink.connection(c -> { + DSLContext context = getDslContext(c, databaseLink.getOfficeId()); + TimeSeriesProfileInstanceDao timeSeriesProfileInstanceDao = new TimeSeriesProfileInstanceDao(context); + CwmsId location = new CwmsId.Builder() + .withName(locationName) + .withOfficeId(officeId) + .build(); + // test the retrieveTimeSeriesProfileInstance method + TimeSeriesProfileInstance result = timeSeriesProfileInstanceDao.retrieveTimeSeriesProfileInstance(location, keyParameter[0], versionID, + unit, startTime, endTime, timeZone, startInclusive, endInclusive, previous, next, versionDate, + maxVersion); + + // cleanup: delete the timeseries we created + TimeSeriesIdentifierDescriptorDao timeSeriesDao = new TimeSeriesIdentifierDescriptorDao(context); + timeSeriesDao.deleteAll(officeId, locationName + "." + keyParameter[0] + ".Inst.0.0." + versionID); + timeSeriesDao.deleteAll(officeId, locationName + "." + parameter1[0] + ".Inst.0.0." + versionID); + + // check if the retrieved timeseries profile instance has the same tineseries as the one we stored + assertEquals(2, result.getTimeSeriesList().size()); + assertEquals(2, result.getTimeSeriesList().get(0).getTimeValuePairList().size()); + + }); + } + + @Test + void testDeleteTimeSeriesProfileInstance() throws SQLException { + Instant versionDate = Instant.parse("2024-07-09T12:00:00.00Z"); + String officeId = "HEC"; + String locationName = "AAA"; + String[] keyParameter = {"Depth", "m"}; + String[] parameter1 = {"Pres", "psi"}; + String unit = "kPa,m"; + String version = "VERSION"; + String timeZone = "UTC"; + Instant startTime = Instant.parse("2018-07-09T19:06:20.00Z"); + Instant endTime = Instant.parse("2025-07-09T19:06:20.00Z"); + boolean overrideProtection = false; + boolean startInclusive = true; + boolean endInclusive = true; + boolean previous = true; + boolean next = true; + boolean maxVersion = true; + Instant firstDate = Instant.parse("2024-07-09T19:00:11.00Z"); + Instant[] dateTimeArray = {Instant.parse("2024-07-09T19:00:11.00Z"), Instant.parse("2024-07-09T20:00:22.00Z")}; + double[] valueArray = {3, 5}; + + // store a time series profile instance + storeTimeSeriesProfileInstance(officeId, locationName, keyParameter, parameter1, version, versionDate, dateTimeArray, valueArray, timeZone); + CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); + databaseLink.connection(c -> { + DSLContext context = getDslContext(c, databaseLink.getOfficeId()); + TimeSeriesProfileInstanceDao timeSeriesProfileInstanceDao = new TimeSeriesProfileInstanceDao(context); + + // retrieve the instance make sure it exists + TimeSeriesProfileInstance timeSeriesProfileInstance; + try { + timeSeriesProfileInstance = retrieveTimeSeriesProfileInstance(officeId, locationName, keyParameter[0], version, unit, + startTime, endTime, timeZone, startInclusive, endInclusive, previous, next, versionDate, maxVersion); + } catch (SQLException e) { + throw new RuntimeException(e); + } + // instance exists? + assertNotNull(timeSeriesProfileInstance); + + CwmsId location = new CwmsId.Builder() + .withName(locationName) + .withOfficeId(officeId) + .build(); + + // testing delete + timeSeriesProfileInstanceDao.deleteTimeSeriesProfileInstance(location, keyParameter[0], version, + firstDate, timeZone, overrideProtection, versionDate); + + // check if instance was deleted + timeSeriesProfileInstance = null; + try { + timeSeriesProfileInstance = retrieveTimeSeriesProfileInstance(officeId, locationName, keyParameter[0], version, unit, + startTime, endTime, timeZone, startInclusive, endInclusive, previous, next, versionDate, maxVersion); + } catch (SQLException e) { + e.printStackTrace(); + } + // instance does not exist anymore + assertNull(timeSeriesProfileInstance); + + // cleanup the timeseries + TimeSeriesIdentifierDescriptorDao timeSeriesDao = new TimeSeriesIdentifierDescriptorDao(context); + timeSeriesDao.deleteAll(officeId, locationName + "." + keyParameter[0] + ".Inst.0.0." + version); + timeSeriesDao.deleteAll(officeId, locationName + "." + parameter1[0] + ".Inst.0.0." + version); + }); + } + + @Test + void testStoreTimeSeriesProfileInstance() throws SQLException { + String versionId = "VERSION"; + String officeId = "HEC"; + String locationName = "AAA"; + String[] parameterArray = {"Depth", "Pres"}; + String[] parameterUnitArray = {"m", "bar"}; + int[] parameterIndexArray = {5, 6}; + String[] keyParameter = {parameterArray[0], parameterUnitArray[0]}; + String[] parameter1 = {parameterArray[1], parameterUnitArray[1]}; + String unit = "kPa,m"; + Instant versionDate = Instant.parse("2024-07-09T12:00:00.00Z"); + String timeZone = "UTC"; + Instant startTime = Instant.parse("2018-07-09T19:06:20.00Z"); + Instant endTime = Instant.parse("2025-07-09T19:06:20.00Z"); + Instant firstDate = Instant.parse("2024-07-09T19:00:11.00Z"); + boolean startInclusive = true; + boolean endInclusive = true; + boolean previous = true; + boolean next = true; + boolean maxVersion = true; + Instant[] dateTimeArray = {Instant.parse("2024-07-09T19:00:11.00Z"), Instant.parse("2024-07-09T20:00:22.00Z")}; + double[] valueArray = {1.0, 5.0}; + char fieldDelimiter = ','; + char recordDelimiter = '\n'; + int timeField = 1; + String timeFormat = "MM/DD/YYYY,HH24:MI:SS"; + CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); + databaseLink.connection(c -> { + DSLContext context = getDslContext(c, databaseLink.getOfficeId()); + TimeSeriesProfileInstance timeSeriesProfileInstance; + + + // store a profile + TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile(officeId, locationName, keyParameter[0], parameter1[0]); + TimeSeriesProfileDao profileDao = new TimeSeriesProfileDao(context); + profileDao.storeTimeSeriesProfile(timeSeriesProfile, false); + + // store a parser + TimeSeriesProfileParser parser = buildTestTimeSeriesProfileParser(officeId, locationName, parameterArray, parameterIndexArray, parameterUnitArray, recordDelimiter, fieldDelimiter, + timeFormat, timeZone, timeField); + TimeSeriesProfileParserDao timeSeriesProfileParserDao = new TimeSeriesProfileParserDao(context); + timeSeriesProfileParserDao.storeTimeSeriesProfileParser(parser, false); + + String storeRule = StoreRule.REPLACE_ALL.toString(); + /// create an instance for parameter Depth + TimeSeriesProfileInstanceDao timeSeriesProfileInstanceDao = new TimeSeriesProfileInstanceDao(context); + TimeSeriesProfileInstance timeseriesProfileInstance = buildTestTimeSeriesProfileInstance(officeId, locationName, keyParameter, parameter1, versionId, + dateTimeArray, valueArray, timeZone, versionDate); + try { + // test storeTImeSeriesProfileInstance method + timeSeriesProfileInstanceDao.storeTimeSeriesProfileInstance(timeseriesProfileInstance, versionId, versionDate, storeRule, null); + } catch (Exception ex) { + ex.printStackTrace(); + throw (ex); + } + + // check is the timeseries profile instance can be retrieved + try { + timeSeriesProfileInstance = retrieveTimeSeriesProfileInstance(officeId, locationName, keyParameter[0], versionId, unit, + startTime, endTime, timeZone, startInclusive, endInclusive, previous, next, versionDate, maxVersion); + } catch (SQLException e) { + throw new RuntimeException(e); + } + // instance exists? + assertNotNull(timeSeriesProfileInstance); + + // cleanup delete the timeseries profile instance and its timeseries + boolean overrideProtection = false; + timeSeriesProfileInstanceDao.deleteTimeSeriesProfileInstance(timeseriesProfileInstance.getTimeSeriesProfile().getLocationId(), + timeSeriesProfile.getKeyParameter(), versionId, + firstDate, timeZone, overrideProtection, versionDate); + TimeSeriesIdentifierDescriptorDao timeSeriesDao = new TimeSeriesIdentifierDescriptorDao(context); + timeSeriesDao.deleteAll(officeId, locationName + "." + keyParameter[0] + ".Inst.0.0." + versionId); + timeSeriesDao.deleteAll(officeId, locationName + "." + parameter1[0] + ".Inst.0.0." + versionId); + }); + } + + private TimeSeriesProfileInstance retrieveTimeSeriesProfileInstance(String officeId, String locationName, String keyParameter, String version, String unit, + Instant startTime, Instant endTime, String timeZone, boolean startInclusive, boolean endInclusive, boolean previous, boolean next, + Instant versionDate, boolean maxVersion) throws SQLException { + final TimeSeriesProfileInstance[] result = {null}; + CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); + databaseLink.connection(c -> { + DSLContext context = getDslContext(c, databaseLink.getOfficeId()); + TimeSeriesProfileInstanceDao timeSeriesProfileInstanceDao = new TimeSeriesProfileInstanceDao(context); + CwmsId location = new CwmsId.Builder() + .withOfficeId(officeId) + .withName(locationName) + .build(); + try { + result[0] = timeSeriesProfileInstanceDao.retrieveTimeSeriesProfileInstance(location, keyParameter, version, + unit, startTime, endTime, timeZone, startInclusive ? "T" : "F", endInclusive ? "T" : "F", previous ? "T" : "F", next ? "T" : "F", versionDate, + maxVersion ? "T" : "F"); + } catch (Exception ex) { + ex.printStackTrace(); + } + }); + return result[0]; + } + + private void storeTimeSeriesProfileInstance(String officeId, String location, String[] keyParameter, String[] parameter1, String version, Instant versionInstant, Instant[] dateTimeArray, double[] valueArray, + String timeZone) throws SQLException { + CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); + databaseLink.connection(c -> { + DSLContext context = getDslContext(c, databaseLink.getOfficeId()); + + /// create an instance for parameter Depth + TimeSeriesProfileInstanceDao timeSeriesProfileInstanceDao = new TimeSeriesProfileInstanceDao(context); + TimeSeriesProfileInstance timeseriesProfileInstance = buildTestTimeSeriesProfileInstance(officeId, location, keyParameter, parameter1, version, dateTimeArray, valueArray, timeZone, versionInstant); + String storeRule = StoreRule.REPLACE_ALL.toString(); + + try { + timeSeriesProfileInstanceDao.storeTimeSeriesProfileInstance(timeseriesProfileInstance, version, versionInstant, storeRule, "F"); + } catch (Exception ex) { + ex.printStackTrace(); + throw (ex); + } + }); + } + + private static TimeSeriesProfileInstance buildTestTimeSeriesProfileInstance(String officeId, String locationName, String[] keyParameterUnit, String[] parameterUnit1, String version, + Instant[] dateTimeArray, double[] valueArray, String timeZone, Instant versionInstant) { + + TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile(officeId, locationName, keyParameterUnit[0], parameterUnit1[0]); + + + List timeValuePairList = new ArrayList<>(); + for (int i = 0; i < dateTimeArray.length; i++) { + TimeValuePair timeValuePair = new TimeValuePair.Builder() + .withValue(valueArray[i]) + .withDateTime(dateTimeArray[i]) + .build(); + timeValuePairList.add(timeValuePair); + } + + ProfileTimeSeries profileTimeSeries = new ProfileTimeSeries.Builder() + .withParameter(keyParameterUnit[0]) + .withUnit(keyParameterUnit[1]) + .withTimeZone(timeZone) + .withTimeValuePairList(timeValuePairList) + .build(); + + List timeSeriesList = new ArrayList<>(); + timeSeriesList.add(profileTimeSeries); + profileTimeSeries = new ProfileTimeSeries.Builder() + .withParameter(parameterUnit1[0]) + .withUnit(parameterUnit1[1]) + .withTimeZone(timeZone) + .withTimeValuePairList(timeValuePairList) + .build(); + + timeSeriesList.add(profileTimeSeries); + return new TimeSeriesProfileInstance.Builder() + .withTimeSeriesProfile(timeSeriesProfile) + .withTimeSeriesList(timeSeriesList) + .withVersion(version) + .withVersionDate(versionInstant) + .build(); + } + + static private TimeSeriesProfile buildTestTimeSeriesProfile(String officeId, String locationName, String keyParameter, String parameter1) { + CwmsId locationId = new CwmsId.Builder().withOfficeId(officeId).withName(locationName).build(); + return new TimeSeriesProfile.Builder() + .withLocationId(locationId) + .withKeyParameter(keyParameter) + .withParameterList(Arrays.asList(parameter1, keyParameter)) + .withDescription("description") + .build(); + + } + + static private TimeSeriesProfileParser buildTestTimeSeriesProfileParser(String officeId, String location, String[] parameterArray, int[] parameterIndexArray, String[] parameterUnitArray, + char recordDelimiter, char fieldDelimiter, String timeFormat, String timeZone, int timeField) { + List parameterInfoList = new ArrayList<>(); + for (int i = 0; i < parameterArray.length; i++) { + parameterInfoList.add(new ParameterInfo.Builder() + .withParameter(parameterArray[i]) + .withIndex(parameterIndexArray[i]) + .withUnit(parameterUnitArray[i]) + .build()); + } + + CwmsId locationId = new CwmsId.Builder().withOfficeId(officeId).withName(location).build(); + return + + new TimeSeriesProfileParser.Builder() + .withLocationId(locationId) + .withKeyParameter(parameterArray[0]) + .withRecordDelimiter(recordDelimiter) + .withFieldDelimiter(fieldDelimiter) + .withTimeFormat(timeFormat) + .withTimeZone(timeZone) + .withTimeField(timeField) + .withTimeInTwoFields(true) + .withParameterInfoList(parameterInfoList) + .build(); + } +} diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDaoIT.java b/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDaoIT.java index 8bbd3eb52..b2ad6d3c1 100644 --- a/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDaoIT.java +++ b/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDaoIT.java @@ -1,245 +1,194 @@ package cwms.cda.data.dao.timeseriesprofile; -import java.io.IOException; import java.sql.SQLException; -import java.time.ZoneId; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import cwms.cda.api.DataApiTestIT; -import cwms.cda.api.enums.Nation; -import cwms.cda.data.dao.LocationsDaoImpl; import cwms.cda.data.dto.CwmsId; -import cwms.cda.data.dto.Location; import cwms.cda.data.dto.timeseriesprofile.ParameterInfo; import cwms.cda.data.dto.timeseriesprofile.TimeSeriesProfile; import cwms.cda.data.dto.timeseriesprofile.TimeSeriesProfileParser; 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 static cwms.cda.data.dao.DaoTest.getDslContext; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertThrowsExactly; -import static org.junit.jupiter.api.Assertions.assertTrue; @Tag("integration") -final class TimeSeriesProfileParserDaoIT extends DataApiTestIT -{ - private static final Location TIMESERIESPROFILE_LOC = buildTestLocation("TIMESERIESPROFILE_LOC"); - private static final Location LOCATION_AAA = buildTestLocation("AAA"); - - @BeforeAll - public static void setup() throws Exception - { - CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); - databaseLink.connection(c -> { - DSLContext context = getDslContext(c, databaseLink.getOfficeId()); - LocationsDaoImpl locationsDao = new LocationsDaoImpl(context); - try - { - locationsDao.storeLocation(TIMESERIESPROFILE_LOC); - locationsDao.storeLocation(LOCATION_AAA); - } - catch(IOException e) - { - throw new RuntimeException(e); - } - }); - } - - @AfterAll - public static void tearDown() throws Exception { - - CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); - databaseLink.connection(c -> { - DSLContext context = getDslContext(c, databaseLink.getOfficeId()); - LocationsDaoImpl locationsDao = new LocationsDaoImpl(context); - // locationsDao.deleteLocation(TIMESERIESPORFILE_LOC.getName(), databaseLink.getOfficeId()); - }); - } - - @Test - void testStoreAndRetrieve() throws Exception { - CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); - databaseLink.connection(c -> { - DSLContext context = getDslContext(c, databaseLink.getOfficeId()); - - TimeSeriesProfileDao timeSeriesProfileDao = new TimeSeriesProfileDao(context); - - TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile("Depth"); - timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfile, false); - - TimeSeriesProfileParserDao timeSeriesProfileParserDao = new TimeSeriesProfileParserDao(context); - TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser("Depth"); - timeSeriesProfileParserDao.storeTimeSeriesProfileParser(timeSeriesProfileParser, false); - - TimeSeriesProfileParser retrieved = timeSeriesProfileParserDao.retrieveTimeSeriesProfileParser(timeSeriesProfileParser.getLocationId().getName(), - timeSeriesProfileParser.getKeyParameter(), timeSeriesProfileParser.getLocationId().getOfficeId()); - assertEquals(timeSeriesProfileParser, retrieved); - - timeSeriesProfileParserDao.deleteTimeSeriesProfileParser(timeSeriesProfileParser.getLocationId().getName(), - timeSeriesProfileParser.getKeyParameter(), timeSeriesProfileParser.getLocationId().getOfficeId()); - - timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfile.getLocationId().getName(),timeSeriesProfile.getKeyParameter(), - timeSeriesProfile.getLocationId().getOfficeId()); - }); - } - - @Test - void testStoreAndDelete() throws SQLException - { - CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); - databaseLink.connection(c -> { - DSLContext context = getDslContext(c, databaseLink.getOfficeId()); - - TimeSeriesProfileDao timeSeriesProfileDao = new TimeSeriesProfileDao(context); - - TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile("Depth"); - timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfile, false); - - TimeSeriesProfileParserDao timeSeriesProfileParserDao = new TimeSeriesProfileParserDao(context); - TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser("Depth"); - timeSeriesProfileParserDao.storeTimeSeriesProfileParser(timeSeriesProfileParser, false); - - timeSeriesProfileParserDao.deleteTimeSeriesProfileParser(timeSeriesProfileParser.getLocationId().getName(), - timeSeriesProfileParser.getKeyParameter(), timeSeriesProfileParser.getLocationId().getOfficeId()); - - assertThrows(Exception.class, ()->timeSeriesProfileParserDao.retrieveTimeSeriesProfileParser( - timeSeriesProfileParser.getLocationId().getName(), - timeSeriesProfileParser.getKeyParameter(), timeSeriesProfileParser.getLocationId().getOfficeId())); - - timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfile.getLocationId().getName(), timeSeriesProfile.getKeyParameter(), - timeSeriesProfile.getLocationId().getOfficeId()); - }); - } - - @Test - void testStoreAndRetrieveMultiple() throws SQLException - { - CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); - databaseLink.connection(c -> { - DSLContext context = getDslContext(c, databaseLink.getOfficeId()); - - TimeSeriesProfileDao timeSeriesProfileDao = new TimeSeriesProfileDao(context); - - TimeSeriesProfile timeSeriesProfileDepth = buildTestTimeSeriesProfile("Depth"); - timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfileDepth, false); - TimeSeriesProfile timeSeriesProfileTemp = buildTestTimeSeriesProfile("Temp-Water"); - timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfileTemp, false); - - TimeSeriesProfileParserDao timeSeriesProfileParserDao = new TimeSeriesProfileParserDao(context); - TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser("Depth"); - timeSeriesProfileParserDao.storeTimeSeriesProfileParser(timeSeriesProfileParser, false); - - timeSeriesProfileParser = buildTestTimeSeriesProfileParser("Temp-Water"); - timeSeriesProfileParserDao.storeTimeSeriesProfileParser(timeSeriesProfileParser, false); - - List profileParserList = timeSeriesProfileParserDao.retrieveTimeSeriesProfileParsers("*", "*", "*"); - List profileParserList1; -// assertEquals(2, profileParserList.size()); - for(TimeSeriesProfileParser profileParser : profileParserList) - { - timeSeriesProfileParserDao.deleteTimeSeriesProfileParser(profileParser.getLocationId().getName(),profileParser.getKeyParameter(),profileParser.getLocationId().getOfficeId()); - profileParserList1 = timeSeriesProfileParserDao.retrieveTimeSeriesProfileParsers("*", "*", "*"); - } - - timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfileDepth.getLocationId().getName(),timeSeriesProfileDepth.getKeyParameter(), - timeSeriesProfileDepth.getLocationId().getOfficeId()); - timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfileTemp.getLocationId().getName(),timeSeriesProfileTemp.getKeyParameter(), - timeSeriesProfileTemp.getLocationId().getOfficeId()); - }); - } - @Test - void testStoreAndCopy() throws SQLException - { - CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); - databaseLink.connection(c -> { - DSLContext context = getDslContext(c, databaseLink.getOfficeId()); - - TimeSeriesProfileDao timeSeriesProfileDao = new TimeSeriesProfileDao(context); - - TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile("Depth"); - timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfile, false); - - TimeSeriesProfileParserDao timeSeriesProfileParserDao = new TimeSeriesProfileParserDao(context); - TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser("Depth"); - timeSeriesProfileParserDao.storeTimeSeriesProfileParser(timeSeriesProfileParser, false); - - TimeSeriesProfileParser retrieved = timeSeriesProfileParserDao.retrieveTimeSeriesProfileParser(timeSeriesProfileParser.getLocationId().getName(), - timeSeriesProfileParser.getKeyParameter(), timeSeriesProfileParser.getLocationId().getOfficeId()); - -// timeSeriesProfileParserDao.copyTimeSeriesProfileParser(timeSeriesProfileParser.getLocationId(), -// timeSeriesProfileParser.getKeyParameter(), timeSeriesProfileParser.getOfficeId(), "AAA"); - - TimeSeriesProfileParser retrieved1 = timeSeriesProfileParserDao.retrieveTimeSeriesProfileParser("AAA", - timeSeriesProfileParser.getKeyParameter(), timeSeriesProfileParser.getLocationId().getOfficeId()); - assertEquals(timeSeriesProfileParser, retrieved); - - }); - } - private static TimeSeriesProfile buildTestTimeSeriesProfile(String parameter) - { - String officeId = "HEC"; - CwmsId locationId = new CwmsId.Builder().withOfficeId(officeId).withName("location").build(); - return new TimeSeriesProfile.Builder() - .withLocationId(locationId) - .withKeyParameter(parameter) - .withParameterList(Arrays.asList(new String[]{"Temp-Water", "Depth"})) - .build(); - - } - private static TimeSeriesProfileParser buildTestTimeSeriesProfileParser(String keyParameter) { - List parameterInfoList = new ArrayList<>(); - parameterInfoList.add( new ParameterInfo.Builder() - .withParameter("Depth") - .withIndex(3) - .withUnit("m") - .build()); - parameterInfoList.add( new ParameterInfo.Builder() - .withParameter("Temp-Water") - .withIndex(4) - .withUnit("F") - .build()); - - String officeId = "HEC"; - CwmsId locationId = new CwmsId.Builder().withOfficeId(officeId).withName("location").build(); - return - - new TimeSeriesProfileParser.Builder() - .withLocationId(locationId) - .withKeyParameter(keyParameter) - .withRecordDelimiter((char) 10) - .withFieldDelimiter(',') - .withTimeFormat("MM/DD/YYYY,HH24:MI:SS") - .withTimeZone("UTC") - .withTimeField(1) - .withTimeInTwoFields(false) - .withParameterInfoList(parameterInfoList) - .build(); - } - - private static Location buildTestLocation(String location) { - String officeId = "HEC";//CwmsDataApiSetupCallback.getDatabaseLink().getOfficeId(); - return new Location.Builder(location, "SITE", ZoneId.of("UTC"), - 38.5613824, -121.7298432, "NVGD29", officeId) - .withElevation(10.0) - .withLocationType("SITE") - .withCountyName("Sacramento") - .withNation(Nation.US) - .withActive(true) - .withStateInitial("CA") - .withBoundingOfficeId(officeId) - .withPublishedLatitude(38.5613824) - .withPublishedLongitude(-121.7298432) - .withLongName("UNITED STATES") - .withDescription("for testing") - .build(); - } +final class TimeSeriesProfileParserDaoIT extends DataApiTestIT { + + + @Test + void testStoreAndRetrieve() throws Exception { + CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); + databaseLink.connection(c -> { + DSLContext context = getDslContext(c, databaseLink.getOfficeId()); + + TimeSeriesProfileDao timeSeriesProfileDao = new TimeSeriesProfileDao(context); + + TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile("AAA", "Depth"); + timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfile, false); + + timeSeriesProfile = buildTestTimeSeriesProfile("BBB", "Depth"); + timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfile, false); + + TimeSeriesProfileParserDao timeSeriesProfileParserDao = new TimeSeriesProfileParserDao(context); + TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser("AAA", "Depth"); + timeSeriesProfileParserDao.storeTimeSeriesProfileParser(timeSeriesProfileParser, false); + + TimeSeriesProfileParser retrieved = timeSeriesProfileParserDao.retrieveTimeSeriesProfileParser(timeSeriesProfileParser.getLocationId().getName(), + timeSeriesProfileParser.getKeyParameter(), timeSeriesProfileParser.getLocationId().getOfficeId()); + assertEquals(timeSeriesProfileParser.getLocationId().getName(), retrieved.getLocationId().getName()); + assertEquals(timeSeriesProfileParser.getLocationId().getOfficeId(), retrieved.getLocationId().getOfficeId()); + assertEquals(timeSeriesProfileParser.getTimeFormat(), retrieved.getTimeFormat()); + assertEquals(timeSeriesProfileParser.getKeyParameter(), retrieved.getKeyParameter()); + + timeSeriesProfileParserDao.deleteTimeSeriesProfileParser(timeSeriesProfileParser.getLocationId().getName(), + timeSeriesProfileParser.getKeyParameter(), timeSeriesProfileParser.getLocationId().getOfficeId()); + + timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfile.getLocationId().getName(), timeSeriesProfile.getKeyParameter(), + timeSeriesProfile.getLocationId().getOfficeId()); + }); + } + + @Test + void testStoreAndDelete() throws SQLException { + CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); + databaseLink.connection(c -> { + DSLContext context = getDslContext(c, databaseLink.getOfficeId()); + + TimeSeriesProfileDao timeSeriesProfileDao = new TimeSeriesProfileDao(context); + + TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile("AAA", "Depth"); + timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfile, false); + + TimeSeriesProfileParserDao timeSeriesProfileParserDao = new TimeSeriesProfileParserDao(context); + TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser("AAA", "Depth"); + timeSeriesProfileParserDao.storeTimeSeriesProfileParser(timeSeriesProfileParser, false); + + timeSeriesProfileParserDao.deleteTimeSeriesProfileParser(timeSeriesProfileParser.getLocationId().getName(), + timeSeriesProfileParser.getKeyParameter(), timeSeriesProfileParser.getLocationId().getOfficeId()); + + assertThrows(Exception.class, () -> timeSeriesProfileParserDao.retrieveTimeSeriesProfileParser( + timeSeriesProfileParser.getLocationId().getName(), + timeSeriesProfileParser.getKeyParameter(), timeSeriesProfileParser.getLocationId().getOfficeId())); + + timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfile.getLocationId().getName(), timeSeriesProfile.getKeyParameter(), + timeSeriesProfile.getLocationId().getOfficeId()); + }); + } + + @Test + void testStoreAndRetrieveMultiple() throws SQLException { + CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); + databaseLink.connection(c -> { + DSLContext context = getDslContext(c, databaseLink.getOfficeId()); + + TimeSeriesProfileDao timeSeriesProfileDao = new TimeSeriesProfileDao(context); + + TimeSeriesProfile timeSeriesProfileDepth = buildTestTimeSeriesProfile("AAA", "Depth"); + timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfileDepth, false); + TimeSeriesProfile timeSeriesProfileTemp = buildTestTimeSeriesProfile("BBB", "Temp-Water"); + timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfileTemp, false); + + TimeSeriesProfileParserDao timeSeriesProfileParserDao = new TimeSeriesProfileParserDao(context); + TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser("AAA", "Depth"); + timeSeriesProfileParserDao.storeTimeSeriesProfileParser(timeSeriesProfileParser, false); + + timeSeriesProfileParser = buildTestTimeSeriesProfileParser("BBB", "Temp-Water"); + timeSeriesProfileParserDao.storeTimeSeriesProfileParser(timeSeriesProfileParser, false); + + List profileParserList = timeSeriesProfileParserDao.retrieveTimeSeriesProfileParsers("*", "*", "*"); + for (TimeSeriesProfileParser profileParser : profileParserList) { + timeSeriesProfileParserDao.deleteTimeSeriesProfileParser(profileParser.getLocationId().getName(), profileParser.getKeyParameter(), profileParser.getLocationId().getOfficeId()); + } + + timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfileDepth.getLocationId().getName(), timeSeriesProfileDepth.getKeyParameter(), + timeSeriesProfileDepth.getLocationId().getOfficeId()); + timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfileTemp.getLocationId().getName(), timeSeriesProfileTemp.getKeyParameter(), + timeSeriesProfileTemp.getLocationId().getOfficeId()); + assertEquals(2, profileParserList.size()); + }); + } + + @Test + void testStoreAndCopy() throws SQLException { + CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); + databaseLink.connection(c -> { + DSLContext context = getDslContext(c, databaseLink.getOfficeId()); + + TimeSeriesProfileDao timeSeriesProfileDao = new TimeSeriesProfileDao(context); + + TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile("AAA", "Depth"); + timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfile, false); + + timeSeriesProfile = buildTestTimeSeriesProfile("BBB", "Depth"); + timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfile, false); + + TimeSeriesProfileParserDao timeSeriesProfileParserDao = new TimeSeriesProfileParserDao(context); + TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser("AAA", "Depth"); + timeSeriesProfileParserDao.storeTimeSeriesProfileParser(timeSeriesProfileParser, false); + + TimeSeriesProfileParser retrieved = timeSeriesProfileParserDao.retrieveTimeSeriesProfileParser(timeSeriesProfileParser.getLocationId().getName(), + timeSeriesProfileParser.getKeyParameter(), timeSeriesProfileParser.getLocationId().getOfficeId()); + + timeSeriesProfileParserDao.copyTimeSeriesProfileParser(timeSeriesProfileParser.getLocationId().getName(), + timeSeriesProfileParser.getKeyParameter(), timeSeriesProfileParser.getLocationId().getOfficeId(), "BBB"); + + TimeSeriesProfileParser retrieved1 = timeSeriesProfileParserDao.retrieveTimeSeriesProfileParser("BBB", + timeSeriesProfileParser.getKeyParameter(), timeSeriesProfileParser.getLocationId().getOfficeId()); + assertEquals(timeSeriesProfileParser.getKeyParameter(), retrieved.getKeyParameter()); + assertEquals("BBB", retrieved1.getLocationId().getName()); + assertEquals(timeSeriesProfileParser.getTimeFormat(), retrieved1.getTimeFormat()); + + }); + } + + private static TimeSeriesProfile buildTestTimeSeriesProfile(String location, String parameter) { + String officeId = "HEC"; + CwmsId locationId = new CwmsId.Builder().withOfficeId(officeId).withName(location).build(); + return new TimeSeriesProfile.Builder() + .withLocationId(locationId) + .withKeyParameter(parameter) + .withParameterList(Arrays.asList("Temp-Water", "Depth")) + .build(); + + } + + static private TimeSeriesProfileParser buildTestTimeSeriesProfileParser(String location, String keyParameter) { + List parameterInfoList = new ArrayList<>(); + parameterInfoList.add(new ParameterInfo.Builder() + .withParameter("Depth") + .withIndex(6) + .withUnit("m") + .build()); + parameterInfoList.add(new ParameterInfo.Builder() + .withParameter("Pres") + .withIndex(5) + .withUnit("bar") + .build()); + String officeId = "HEC"; + CwmsId locationId = new CwmsId.Builder().withOfficeId(officeId).withName(location).build(); + return + + new TimeSeriesProfileParser.Builder() + .withLocationId(locationId) + .withKeyParameter(keyParameter) + .withRecordDelimiter((char) 10) + .withFieldDelimiter(',') + .withTimeFormat("MM/DD/YYYY,HH24:MI:SS") + .withTimeZone("UTC") + .withTimeField(1) + .withTimeInTwoFields(true) + .withParameterInfoList(parameterInfoList) + .build(); + } + + } diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserTest.java b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserTest.java index 88a823735..f1583d46c 100644 --- a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserTest.java +++ b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserTest.java @@ -74,9 +74,19 @@ private void testAssertEquals(TimeSeriesProfileParser expected, TimeSeriesProfil assertEquals(expected.getKeyParameter(), actual.getKeyParameter(), message); assertEquals(expected.getTimeField(), actual.getTimeField(), message); assertEquals(expected.getTimeFormat(), actual.getTimeFormat(), message); - assertEquals(expected.getParameterInfoList(), actual.getParameterInfoList(),message); + testAssertEquals(expected.getParameterInfoList(), actual.getParameterInfoList(),message); assertEquals(expected.getRecordDelimiter(), actual.getRecordDelimiter(), message); assertEquals(expected.getTimeZone(), actual.getTimeZone()); assertEquals(expected.getTimeInTwoFields(), actual.getTimeInTwoFields()); } + + private void testAssertEquals(List expected, List actual, String message) { + assertEquals(expected.size(), actual.size()); + for(int i=0;i Date: Wed, 24 Jul 2024 13:49:14 -0700 Subject: [PATCH 17/26] Timeseries profile instance dao and test, columnar data, timeseries profile parser columnar data --- .../TimeSeriesProfileInstanceDao.java | 9 +- .../dto/timeseriesprofile/ParameterInfo.java | 45 +++- .../timeseriesprofile/ProfileTimeSeries.java | 2 +- .../TimeSeriesProfileParser.java | 71 +++++- .../dto/timeseriesprofile/TimeValuePair.java | 6 +- .../TimeSeriesProfileDaoIT.java | 41 ++-- .../TimeSeriesProfileInstanceDaoIT.java | 228 +++++++++++++----- .../TimeSeriesProfileParserDaoIT.java | 85 ++++--- .../TimeSeriesProfileParserTest.java | 58 ++++- .../timeSeriesProfileData.txt | 5 +- .../timeSeriesProfileDataColumnar.txt | 3 + .../timeseriesprofileparsercolumnar.json | 27 +++ 12 files changed, 423 insertions(+), 157 deletions(-) create mode 100644 cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeSeriesProfileDataColumnar.txt create mode 100644 cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileparsercolumnar.json diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDao.java b/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDao.java index 0bdeffc02..f5ce9226a 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDao.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDao.java @@ -50,7 +50,7 @@ void storeTimeSeriesProfileInstance(TimeSeriesProfile timeSeriesProfile, String versionId, storeRule, overrideProtection?"T":"F", - Timestamp.from(versionDate), + versionDate!=null?Timestamp.from(versionDate):null, timeSeriesProfile.getLocationId().getOfficeId()); } catch (Exception ex) { ex.printStackTrace(); @@ -103,7 +103,6 @@ void storeTimeSeriesProfileInstance(TimeSeriesProfileInstance timeseriesProfileI String parameterId = timeseriesProfileInstance.getTimeSeriesList().get(i).getParameter(); BigInteger parameterCode = parameterIdToCode.get(parameterId); pvq.setPARAMETER_CODE(parameterCode); - pvq.setQUALITY_CODE(BigInteger.valueOf(9)); parameters.add(pvq); units.add(timeseriesProfileInstance.getTimeSeriesList().get(i).getUnit()); } @@ -207,7 +206,7 @@ TimeSeriesProfileInstance retrieveTimeSeriesProfileInstance(CwmsId location, Str endInclusive, previous, next, - null,//Timestamp.from(versionDate), + versionDate!=null?Timestamp.from(versionDate):null, maxVersion, location.getOfficeId() ); @@ -263,22 +262,18 @@ private TimeSeriesProfileInstance map(@NotNull Configuration configuration, Stri List timeList = new ArrayList<>(); List> valuesList = new ArrayList<>(); List> parametersList = new ArrayList<>(); - List> qualitiesList = new ArrayList<>(); for(TS_PROF_DATA_REC_T dataRecord : records) { Instant dateTime = dataRecord.get(0, Instant.class); timeList.add(dateTime); PVQ_TAB_T parameters = dataRecord.getPARAMETERS(); List valueList = new ArrayList<>(); - List qualityList = new ArrayList<>(); List parameterList = new ArrayList<>(); for(PVQ_T parameter : parameters) { - qualityList.add(parameter.getQUALITY_CODE()); valueList.add(parameter.getVALUE()); parameterList.add(parameter.getPARAMETER_CODE()); } - qualitiesList.add(qualityList); valuesList.add(valueList); parametersList.add(parameterList); } diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfo.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfo.java index 819aa2b9a..033b5a0e5 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfo.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfo.java @@ -9,23 +9,23 @@ import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; import cwms.cda.api.errors.FieldException; import cwms.cda.data.dto.CwmsDTOBase; -import cwms.cda.formatters.Formats; -import cwms.cda.formatters.annotations.FormattableWith; -import cwms.cda.formatters.json.JsonV2; -@FormattableWith(contentType = Formats.JSONV2, formatter = JsonV2.class) @JsonDeserialize(builder = ParameterInfo.Builder.class) @JsonInclude(JsonInclude.Include.NON_NULL) @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) -public class ParameterInfo implements CwmsDTOBase { +public final class ParameterInfo implements CwmsDTOBase { private final String parameter; private final String unit; - private final int index; + private final Integer index; + private final Integer startColumn; + private final Integer endColumn; - protected ParameterInfo(ParameterInfo.Builder builder) { + ParameterInfo(ParameterInfo.Builder builder) { parameter = builder.parameter; unit = builder.unit; index = builder.index; + startColumn = builder.startColumn; + endColumn = builder.endColumn; } public String getParameter() { @@ -36,14 +36,26 @@ public String getUnit() { return unit; } - public int getIndex() { + public Integer getIndex() { return index; } - + public Integer getStartColumn(){ + return startColumn; + } + public Integer getEndColumn(){ + return endColumn; + } @Override public void validate() throws FieldException { - + if(index==null && !(startColumn!=null && endColumn!=null)) + { + throw new FieldException("if index is null, startColumn and endColumn must be defined!"); + } + if(index!=null && (startColumn!=null || endColumn!=null)) + { + throw new FieldException("if index is defined, startColumn and endColumn must not be defined!"); + } } @Override @@ -74,8 +86,9 @@ public boolean equals(Object o) { public static final class Builder { private String parameter; private String unit; - private int index; - + private Integer index; + private Integer startColumn; + private Integer endColumn; public ParameterInfo.Builder withParameter(String parameter) { this.parameter = parameter; @@ -92,6 +105,14 @@ public ParameterInfo.Builder withIndex(int index) { return this; } + public ParameterInfo.Builder withStartColumn(int startColumn){ + this.startColumn = startColumn; + return this; + } + public ParameterInfo.Builder withEndColumn(int endColumn){ + this.endColumn = endColumn; + return this; + } public ParameterInfo build() { return new ParameterInfo(this); } diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ProfileTimeSeries.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ProfileTimeSeries.java index 3dd4f2e38..e0c0b0f2c 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ProfileTimeSeries.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ProfileTimeSeries.java @@ -15,7 +15,7 @@ @JsonDeserialize(builder = ProfileTimeSeries.Builder.class) @JsonInclude(JsonInclude.Include.NON_NULL) @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) -public class ProfileTimeSeries { +public final class ProfileTimeSeries { private final String parameter; private final String unit; private final String timeZone; diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParser.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParser.java index 9cf8f4494..54030d346 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParser.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParser.java @@ -19,16 +19,18 @@ @JsonDeserialize(builder = TimeSeriesProfileParser.Builder.class) @JsonInclude(JsonInclude.Include.NON_NULL) @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) -public class TimeSeriesProfileParser implements CwmsDTOBase { +public final class TimeSeriesProfileParser implements CwmsDTOBase { private final CwmsId locationId; private final String keyParameter; private final char recordDelimiter; - private final char fieldDelimiter; + private final Character fieldDelimiter; private final String timeFormat; private final String timeZone; - private final int timeField; + private final Integer timeField; private final List parameterInfoList; private final boolean timeInTwoFields; + private final Integer timeStartColumn; + private final Integer timeEndColumn; private TimeSeriesProfileParser(Builder builder) { locationId = builder.locationId; @@ -40,13 +42,44 @@ private TimeSeriesProfileParser(Builder builder) { timeField = builder.timeField; parameterInfoList = builder.parameterInfoList; timeInTwoFields = builder.timeInTwoFields; + timeStartColumn = builder.timeStartColumn; + timeEndColumn = builder.timeEndColumn; } @Override public void validate() throws FieldException { + // there must be a key parameter if (this.keyParameter == null) { throw new FieldException("Key Parameter field can't be null"); } + // if there is a field delimiter, and it is part of the time format, time in two fields must be true + // if we have a field delimiter and it is not contained in the timeformat, then timeInTwoField must be false + if(fieldDelimiter!=null && (-1==timeFormat.indexOf(fieldDelimiter) && timeInTwoFields)) + { + throw new FieldException("Field delimiter '"+fieldDelimiter+"' is not part of time format " + +timeFormat+". timeInTwoFields must be false."); + } + // if there is no field delimiter, time start column and time end column must be defined + if(fieldDelimiter==null && (timeStartColumn==null || timeEndColumn ==null)) + { + throw new FieldException("If Field delimiter is undefined, then timeStartColumn and timeEndColumn must be defined."); + } + // if there is no field delimiter, parameter info must provide a start and end column + if(fieldDelimiter==null) + { + for(ParameterInfo parameterInfo : parameterInfoList) + { + if(parameterInfo.getStartColumn()==null || parameterInfo.getEndColumn()==null) + { + throw new FieldException("If Field delimiter is undefined, then startColumn and endColumn must be defined for ParameterInfo."); + } + } + } + // if time field is undefined, it is columnar format and time start column and time end column must be defined + if(timeStartColumn!=null&&timeEndColumn!=null&&timeField!=null) + { + throw new FieldException("If time field is defined, then startColumn and endColumn must be undefined."); + } } @@ -62,7 +95,7 @@ public char getRecordDelimiter() { return recordDelimiter; } - public char getFieldDelimiter() { + public Character getFieldDelimiter() { return fieldDelimiter; } @@ -79,13 +112,25 @@ public String getTimeZone() { } public BigInteger getTimeField() { - return BigInteger.valueOf(timeField); + return timeField==null ? null : BigInteger.valueOf(timeField); } public boolean getTimeInTwoFields() { return timeInTwoFields; } + public BigInteger getTimeStartColumn() { + if (timeStartColumn != null) { + return BigInteger.valueOf(timeStartColumn); + } + return null; + } + public BigInteger getTimeEndColumn(){ + if (timeEndColumn != null) { + return BigInteger.valueOf(timeEndColumn); + } + return null; + } @JsonPOJOBuilder @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) @@ -93,18 +138,30 @@ public static final class Builder { private List parameterInfoList; private String keyParameter; private char recordDelimiter; - private char fieldDelimiter; + private Character fieldDelimiter = null; private String timeFormat; private String timeZone; - private int timeField; + private Integer timeField = null; private boolean timeInTwoFields; private CwmsId locationId; + private Integer timeStartColumn = null; + private Integer timeEndColumn = null; public TimeSeriesProfileParser.Builder withLocationId(CwmsId locationId) { this.locationId = locationId; return this; } + public TimeSeriesProfileParser.Builder withTimeStartColumn(int timeStartColumn) + { + this.timeStartColumn = timeStartColumn; + return this; + } + public TimeSeriesProfileParser.Builder withTimeEndColumn(int timeEndColumn) + { + this.timeEndColumn = timeEndColumn; + return this; + } public TimeSeriesProfileParser.Builder withKeyParameter(String keyParameter) { this.keyParameter = keyParameter; return this; diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeValuePair.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeValuePair.java index 461b257fc..0d3eb5582 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeValuePair.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeValuePair.java @@ -5,17 +5,13 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonNaming; import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; -import cwms.cda.formatters.Formats; -import cwms.cda.formatters.annotations.FormattableWith; -import cwms.cda.formatters.json.JsonV2; import java.time.Instant; -@FormattableWith(contentType = Formats.JSONV2, formatter = JsonV2.class) @JsonDeserialize(builder = TimeValuePair.Builder.class) @JsonInclude(JsonInclude.Include.NON_NULL) @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) -public class TimeValuePair { +public final class TimeValuePair { private final Instant dateTime; private final double value; diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileDaoIT.java b/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileDaoIT.java index 9bde8ff15..d89fe6257 100644 --- a/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileDaoIT.java +++ b/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileDaoIT.java @@ -23,24 +23,25 @@ class TimeSeriesProfileDaoIT extends DataApiTestIT { void testCopyTimeSeriesProfile() throws SQLException { CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); databaseLink.connection(c -> { + String officeId ="LRL"; DSLContext context = getDslContext(c, databaseLink.getOfficeId()); TimeSeriesProfileDao timeSeriesProfileDao = new TimeSeriesProfileDao(context); - TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile("Depth"); + TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile(officeId, "Glensboro", "Depth"); timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfile, false); timeSeriesProfileDao.copyTimeSeriesProfile(timeSeriesProfile.getLocationId().getName(), timeSeriesProfile.getKeyParameter(), - "BBB", null, + "Greensburg", null, timeSeriesProfile.getLocationId().getOfficeId()); TimeSeriesProfile timeSeriesProfileCopied = timeSeriesProfileDao.retrieveTimeSeriesProfile( - "BBB", + "Greensburg", timeSeriesProfile.getKeyParameter(), timeSeriesProfile.getLocationId().getOfficeId()); - assertEquals("BBB", timeSeriesProfileCopied.getLocationId().getName()); + assertEquals("Greensburg", timeSeriesProfileCopied.getLocationId().getName()); assertEquals(timeSeriesProfile.getKeyParameter(), timeSeriesProfileCopied.getKeyParameter()); assertEquals(timeSeriesProfile.getParameterList(), timeSeriesProfileCopied.getParameterList()); timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfile.getLocationId().getName(), timeSeriesProfile.getKeyParameter(), timeSeriesProfile.getLocationId().getOfficeId()); timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfileCopied.getLocationId().getName(), timeSeriesProfileCopied.getKeyParameter(), timeSeriesProfileCopied.getLocationId().getOfficeId()); - }); + }, CwmsDataApiSetupCallback.getWebUser()); } @Test @@ -48,10 +49,11 @@ void testRetrieveTimeSeriesProfile() throws Exception { CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); databaseLink.connection(c -> { DSLContext context = getDslContext(c, databaseLink.getOfficeId()); + String officeId = "LRL"; TimeSeriesProfileDao timeSeriesProfileDao = new TimeSeriesProfileDao(context); - TimeSeriesProfile timeSeriesProfileIn = (buildTestTimeSeriesProfile("Depth")); + TimeSeriesProfile timeSeriesProfileIn = buildTestTimeSeriesProfile(officeId,"Glensboro","Depth"); timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfileIn, false); TimeSeriesProfile timeSeriesProfileOut = timeSeriesProfileDao.retrieveTimeSeriesProfile(timeSeriesProfileIn.getLocationId().getName(), @@ -62,7 +64,7 @@ void testRetrieveTimeSeriesProfile() throws Exception { TimeSeriesProfileTest.testAssertEquals(timeSeriesProfileOut, timeSeriesProfileIn, ""); - }); + }, CwmsDataApiSetupCallback.getWebUser()); } @Test @@ -70,24 +72,25 @@ void testRetrieveCatalog() throws Exception { CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); databaseLink.connection(c -> { DSLContext context = getDslContext(c, databaseLink.getOfficeId()); + String officeId = "LRL"; TimeSeriesProfileDao timeSeriesProfileDao = new TimeSeriesProfileDao(context); - timeSeriesProfileDao.storeTimeSeriesProfile(buildTestTimeSeriesProfile("Depth"), false); - timeSeriesProfileDao.storeTimeSeriesProfile(buildTestTimeSeriesProfile("Pres"), false); + timeSeriesProfileDao.storeTimeSeriesProfile(buildTestTimeSeriesProfile(officeId,"Glensboro","Depth"), false); + timeSeriesProfileDao.storeTimeSeriesProfile(buildTestTimeSeriesProfile(officeId,"Greensburg","Pres"), false); List timeSeriesProfileListBefore = timeSeriesProfileDao.retrieveTimeSeriesProfiles("*", "*", "*"); for (TimeSeriesProfile timeSeriesProfile : timeSeriesProfileListBefore) { - timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfile.getLocationId().getName(), timeSeriesProfile.getKeyParameter(), - timeSeriesProfile.getLocationId().getOfficeId()); + timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfile.getLocationId().getName(), timeSeriesProfile.getKeyParameter(), + timeSeriesProfile.getLocationId().getOfficeId()); } List timeSeriesProfileListAfter = timeSeriesProfileDao.retrieveTimeSeriesProfiles("*", "*", "*"); assertEquals(0, timeSeriesProfileListAfter.size()); assertEquals(2, timeSeriesProfileListBefore.size()); - }); + }, CwmsDataApiSetupCallback.getWebUser()); } @Test @@ -95,10 +98,11 @@ void testDeleteTimeSeriesProfile() throws Exception { CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); databaseLink.connection(c -> { DSLContext context = getDslContext(c, databaseLink.getOfficeId()); + String officeId = "LRL"; TimeSeriesProfileDao timeSeriesProfileDao = new TimeSeriesProfileDao(context); - TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile("Depth"); - timeSeriesProfileDao.storeTimeSeriesProfile(buildTestTimeSeriesProfile("Depth"), false); + TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile(officeId,"Glensboro","Depth"); + timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfile, false); List timeSeriesProfileListBefore = timeSeriesProfileDao.retrieveTimeSeriesProfiles("*", "*", "*"); @@ -111,13 +115,12 @@ void testDeleteTimeSeriesProfile() throws Exception { assertEquals(timeSeriesProfileListBefore.size() - 1, timeSeriesProfileListAfter.size()); - }); + }, CwmsDataApiSetupCallback.getWebUser()); } - static private TimeSeriesProfile buildTestTimeSeriesProfile(String keyParameter) { - String officeId = "HEC"; - CwmsId locationId = new CwmsId.Builder().withOfficeId(officeId).withName("AAA").build(); - CwmsId refTsId = new CwmsId.Builder().withOfficeId(officeId).withName("AAA.Pres.Inst.0.0.VERSION").build(); + static private TimeSeriesProfile buildTestTimeSeriesProfile(String officeId, String location, String keyParameter) { + CwmsId locationId = new CwmsId.Builder().withOfficeId(officeId).withName(location).build(); + CwmsId refTsId = new CwmsId.Builder().withOfficeId(officeId).withName("Greensburg.Stage.Inst.1Hour.0.USGS-rev").build(); return new TimeSeriesProfile.Builder() .withLocationId(locationId) .withKeyParameter(keyParameter) diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDaoIT.java b/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDaoIT.java index 46eb9f376..f301ba550 100644 --- a/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDaoIT.java +++ b/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDaoIT.java @@ -2,7 +2,6 @@ import cwms.cda.api.DataApiTestIT; import cwms.cda.data.dao.StoreRule; -import cwms.cda.data.dao.TimeSeriesIdentifierDescriptorDao; import cwms.cda.data.dto.CwmsId; import cwms.cda.data.dto.timeseriesprofile.ParameterInfo; import cwms.cda.data.dto.timeseriesprofile.ProfileTimeSeries; @@ -12,10 +11,16 @@ import cwms.cda.data.dto.timeseriesprofile.TimeValuePair; import fixtures.CwmsDataApiSetupCallback; import mil.army.usace.hec.test.database.CwmsDatabaseContainer; +import org.apache.commons.io.IOUtils; import org.jooq.DSLContext; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; +import usace.cwms.db.dao.ifc.ts.CwmsDbTs; +import usace.cwms.db.dao.util.services.CwmsDbServiceLookup; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; import java.sql.SQLException; import java.time.Instant; import java.util.ArrayList; @@ -32,25 +37,25 @@ class TimeSeriesProfileInstanceDaoIT extends DataApiTestIT { void testStoreTimeSeriesProfileInstanceWithDataBlock() throws SQLException { CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); databaseLink.connection(c -> { - String officeId = "HEC"; - String locationName = "CCC"; - try { - createLocation(locationName, true, officeId); - } catch (SQLException e) { - throw new RuntimeException(e); - } - + String officeId = "LRL"; + String locationName = "Glensboro"; String versionId = "VERSION"; String unit = "kPa,m"; String[] parameterArray = {"Depth", "Pres"}; - int[] parameterIndexArray = {5, 6}; + int[] parameterIndexArray = {7, 8}; String[] parameterUnitArray = {"m", "kPa"}; Instant versionDate = Instant.parse("2024-07-09T12:00:00.00Z"); Instant startTime = Instant.parse("2018-07-09T19:06:20.00Z"); Instant endTime = Instant.parse("2025-07-09T19:06:20.00Z"); - String profileData = "a\n09/09/2019,12:48:37,,5,6,7,8,9,10,11,12,13,\n09/09/2019,12:58:57,,5,6,7,8,9,10,11,12,13,\n"; + String profileData; + InputStream resource = this.getClass().getResourceAsStream("/cwms/cda/data/dto/timeseriesprofile/timeSeriesProfileData.txt"); + assertNotNull(resource); + try { + profileData = IOUtils.toString(resource, StandardCharsets.UTF_8); + } catch (IOException e) { + throw new RuntimeException(e); + } String timeZone = "UTC"; - String firstDate = "2019-09-09T12:48:57.00Z"; boolean startInclusive = true; boolean endInclusive = true; boolean previous = true; @@ -72,6 +77,8 @@ void testStoreTimeSeriesProfileInstanceWithDataBlock() throws SQLException { TimeSeriesProfileParser parser = buildTestTimeSeriesProfileParser(officeId, locationName, parameterArray, parameterIndexArray, parameterUnitArray, recordDelimiter, fieldDelimiter, timeFormat, timeZone, timeField); TimeSeriesProfileParserDao timeSeriesProfileParserDao = new TimeSeriesProfileParserDao(context); + + // now store the new one. timeSeriesProfileParserDao.storeTimeSeriesProfileParser(parser, false); // create a time series profile instance and test storeTimeSeriesProfileInstance @@ -84,28 +91,88 @@ void testStoreTimeSeriesProfileInstanceWithDataBlock() throws SQLException { TimeSeriesProfileInstance timeSeriesProfileInstance = retrieveTimeSeriesProfileInstance(officeId, locationName, parameterArray[0], versionId, unit, startTime, endTime, timeZone, startInclusive, endInclusive, previous, next, versionDate, maxVersion); // cleanup: delete the instance - timeSeriesProfileInstanceDao.deleteTimeSeriesProfileInstance(timeSeriesProfileInstance.getTimeSeriesProfile().getLocationId(), - timeSeriesProfileInstance.getTimeSeriesProfile().getKeyParameter(), - versionId, Instant.parse(firstDate), timeZone, false, versionDate); + profileDao.deleteTimeSeriesProfile(timeSeriesProfileInstance.getTimeSeriesProfile().getLocationId().getName(), timeSeriesProfileInstance.getTimeSeriesProfile().getKeyParameter(), + timeSeriesProfileInstance.getTimeSeriesProfile().getLocationId().getOfficeId()); // check if the instant contains the timeseries we stpred assertEquals(parameterArray.length, timeSeriesProfileInstance.getTimeSeriesList().size()); } catch (SQLException e) { + throw new RuntimeException(e); + } + }, CwmsDataApiSetupCallback.getWebUser()); + } + @Test + void testStoreTimeSeriesProfileInstanceWithDataBlockColumnar() throws SQLException { + CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); + databaseLink.connection(c -> { + String officeId = "LRL"; + String locationName = "Glensboro"; + String versionId = "VERSION"; + String unit = "kPa,m"; + String[] parameterArray = {"Depth", "Pres"}; + int[][] parameterStartEndArray = {{21, 23}, {25, 27}}; + String[] parameterUnitArray = {"m", "kPa"}; + Instant versionDate = Instant.parse("2024-07-09T12:00:00.00Z"); + Instant startTime = Instant.parse("2018-07-09T19:06:20.00Z"); + Instant endTime = Instant.parse("2025-07-09T19:06:20.00Z"); + String profileData; + InputStream resource = this.getClass().getResourceAsStream("/cwms/cda/data/dto/timeseriesprofile/timeSeriesProfileDataColumnar.txt"); + assertNotNull(resource); + try { + profileData = IOUtils.toString(resource, StandardCharsets.UTF_8); + } catch (IOException e) { throw new RuntimeException(e); } - // cleanup: remove the timeseries we stored - TimeSeriesIdentifierDescriptorDao timeSeriesDao = new TimeSeriesIdentifierDescriptorDao(context); - for(String parameter: parameterArray) { - timeSeriesDao.deleteAll(officeId, locationName + "." + parameter + ".Inst.0.0." + versionId); - timeSeriesDao.deleteAll(officeId, locationName + "." + parameter + ".Inst.0.0." + versionId); + String timeZone = "UTC"; + boolean startInclusive = true; + boolean endInclusive = true; + boolean previous = true; + boolean next = true; + boolean maxVersion = true; + char recordDelimiter = '\n'; + int[] timeStartEnd = {1, 19}; + + String timeFormat = "MM/DD/YYYY,HH24:MI:SS"; + + DSLContext context = getDslContext(c, databaseLink.getOfficeId()); + + // store a time series profile + TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile(officeId, locationName, parameterArray[0], parameterArray[1]); + TimeSeriesProfileDao profileDao = new TimeSeriesProfileDao(context); + profileDao.storeTimeSeriesProfile(timeSeriesProfile, false); + + // store a time series parser + TimeSeriesProfileParser parser = buildTestTimeSeriesProfileParser(officeId, locationName, parameterArray, parameterStartEndArray, parameterUnitArray, recordDelimiter, + timeFormat, timeZone, timeStartEnd); + TimeSeriesProfileParserDao timeSeriesProfileParserDao = new TimeSeriesProfileParserDao(context); + timeSeriesProfileParserDao.storeTimeSeriesProfileParser(parser, false); + + // create a time series profile instance and test storeTimeSeriesProfileInstance + TimeSeriesProfileInstanceDao timeSeriesProfileInstanceDao = new TimeSeriesProfileInstanceDao(context); + String storeRule = StoreRule.REPLACE_ALL.toString(); + timeSeriesProfileInstanceDao.storeTimeSeriesProfileInstance(timeSeriesProfile, profileData, versionDate, versionId, storeRule, false); + + try { + // retrieve the time series profile instance we just stored + TimeSeriesProfileInstance timeSeriesProfileInstance = retrieveTimeSeriesProfileInstance(officeId, locationName, parameterArray[0], versionId, unit, + startTime, endTime, timeZone, startInclusive, endInclusive, previous, next, versionDate, maxVersion); + // cleanup: delete the instance + profileDao.deleteTimeSeriesProfile(timeSeriesProfileInstance.getTimeSeriesProfile().getLocationId().getName(), timeSeriesProfileInstance.getTimeSeriesProfile().getKeyParameter(), + timeSeriesProfileInstance.getTimeSeriesProfile().getLocationId().getOfficeId()); + + // check if the instant contains the timeseries we stpred + assertEquals(parameterArray.length, timeSeriesProfileInstance.getTimeSeriesList().size()); + } catch (SQLException e) { + throw new RuntimeException(e); } - }); + }, CwmsDataApiSetupCallback.getWebUser()); } + @Test void testRetrieveTimeSeriesProfileInstances() throws SQLException { Instant versionDate = Instant.parse("2024-07-09T12:00:00.00Z"); - String officeId = "HEC"; - String location = "AAA"; + String officeId = "LRL"; + String location = "Glensboro"; String[] keyParameter = {"Depth", "m"}; String[] parameter1 = {"Pres", "psi"}; String[] versions = {"VERSION", "VERSION2", "VERSION3"}; @@ -120,7 +187,7 @@ void testRetrieveTimeSeriesProfileInstances() throws SQLException { Instant[] dateTimeArray = {Instant.parse("2024-07-09T19:00:11.00Z"), Instant.parse("2024-07-09T20:00:22.00Z")}; double[] valueArray = {1, 4}; - // sore a few timeseries profile instances + // store a few timeseries profile instances for (String version : versions) { storeTimeSeriesProfileInstance(officeId, location, keyParameter, parameter1, version, versionDate, dateTimeArray, valueArray, timeZone); } @@ -141,15 +208,15 @@ void testRetrieveTimeSeriesProfileInstances() throws SQLException { firstDate, timeZone, overrideProtection, timeSeriesProfileInstance.getVersionDate()); } // check if we retrieve all the instances we stored - assertEquals(versions.length, result.size()); + assertEquals(versions.length, result.size(), CwmsDataApiSetupCallback.getWebUser()); }); } @Test void testRetrieveTimeSeriesProfileInstance() throws SQLException { - String officeId = "HEC"; + String officeId = "LRL"; String versionID = "VERSION"; - String locationName = "AAA"; + String locationName = "Glensboro"; String[] keyParameter = {"Depth", "m"}; String[] parameter1 = {"Pres", "psi"}; String unit = "bar,m"; @@ -181,22 +248,22 @@ void testRetrieveTimeSeriesProfileInstance() throws SQLException { maxVersion); // cleanup: delete the timeseries we created - TimeSeriesIdentifierDescriptorDao timeSeriesDao = new TimeSeriesIdentifierDescriptorDao(context); - timeSeriesDao.deleteAll(officeId, locationName + "." + keyParameter[0] + ".Inst.0.0." + versionID); - timeSeriesDao.deleteAll(officeId, locationName + "." + parameter1[0] + ".Inst.0.0." + versionID); + timeSeriesProfileInstanceDao.deleteTimeSeriesProfileInstance(result.getTimeSeriesProfile().getLocationId(), + result.getTimeSeriesProfile().getKeyParameter(), result.getVersion(), + startTime, timeZone, false, result.getVersionDate()); // check if the retrieved timeseries profile instance has the same tineseries as the one we stored assertEquals(2, result.getTimeSeriesList().size()); assertEquals(2, result.getTimeSeriesList().get(0).getTimeValuePairList().size()); - }); + }, CwmsDataApiSetupCallback.getWebUser()); } @Test void testDeleteTimeSeriesProfileInstance() throws SQLException { Instant versionDate = Instant.parse("2024-07-09T12:00:00.00Z"); - String officeId = "HEC"; - String locationName = "AAA"; + String officeId = "LRL"; + String locationName = "Glensboro"; String[] keyParameter = {"Depth", "m"}; String[] parameter1 = {"Pres", "psi"}; String unit = "kPa,m"; @@ -253,17 +320,21 @@ void testDeleteTimeSeriesProfileInstance() throws SQLException { assertNull(timeSeriesProfileInstance); // cleanup the timeseries - TimeSeriesIdentifierDescriptorDao timeSeriesDao = new TimeSeriesIdentifierDescriptorDao(context); - timeSeriesDao.deleteAll(officeId, locationName + "." + keyParameter[0] + ".Inst.0.0." + version); - timeSeriesDao.deleteAll(officeId, locationName + "." + parameter1[0] + ".Inst.0.0." + version); - }); + try { + CwmsDbTs tsDao = CwmsDbServiceLookup.buildCwmsDb(CwmsDbTs.class, c); + tsDao.deleteAll(c, officeId, locationName + "." + keyParameter[0] + ".Inst.0.0." + version); + tsDao.deleteAll(c, officeId, locationName + "." + parameter1[0] + ".Inst.0.0." + version); + } catch (SQLException e) { + throw(new RuntimeException(e)); + } + }, CwmsDataApiSetupCallback.getWebUser()); } @Test void testStoreTimeSeriesProfileInstance() throws SQLException { String versionId = "VERSION"; - String officeId = "HEC"; - String locationName = "AAA"; + String officeId = "LRL"; + String locationName = "Glensboro"; String[] parameterArray = {"Depth", "Pres"}; String[] parameterUnitArray = {"m", "bar"}; int[] parameterIndexArray = {5, 6}; @@ -308,33 +379,36 @@ void testStoreTimeSeriesProfileInstance() throws SQLException { TimeSeriesProfileInstanceDao timeSeriesProfileInstanceDao = new TimeSeriesProfileInstanceDao(context); TimeSeriesProfileInstance timeseriesProfileInstance = buildTestTimeSeriesProfileInstance(officeId, locationName, keyParameter, parameter1, versionId, dateTimeArray, valueArray, timeZone, versionDate); - try { - // test storeTImeSeriesProfileInstance method - timeSeriesProfileInstanceDao.storeTimeSeriesProfileInstance(timeseriesProfileInstance, versionId, versionDate, storeRule, null); - } catch (Exception ex) { - ex.printStackTrace(); - throw (ex); - } - + // test storeTImeSeriesProfileInstance method + timeSeriesProfileInstanceDao.storeTimeSeriesProfileInstance(timeseriesProfileInstance, versionId, versionDate, storeRule, null); + timeSeriesProfileInstance = null; // check is the timeseries profile instance can be retrieved try { timeSeriesProfileInstance = retrieveTimeSeriesProfileInstance(officeId, locationName, keyParameter[0], versionId, unit, startTime, endTime, timeZone, startInclusive, endInclusive, previous, next, versionDate, maxVersion); - } catch (SQLException e) { + } + catch (SQLException e) + { throw new RuntimeException(e); } // instance exists? - assertNotNull(timeSeriesProfileInstance); // cleanup delete the timeseries profile instance and its timeseries boolean overrideProtection = false; timeSeriesProfileInstanceDao.deleteTimeSeriesProfileInstance(timeseriesProfileInstance.getTimeSeriesProfile().getLocationId(), timeSeriesProfile.getKeyParameter(), versionId, firstDate, timeZone, overrideProtection, versionDate); - TimeSeriesIdentifierDescriptorDao timeSeriesDao = new TimeSeriesIdentifierDescriptorDao(context); - timeSeriesDao.deleteAll(officeId, locationName + "." + keyParameter[0] + ".Inst.0.0." + versionId); - timeSeriesDao.deleteAll(officeId, locationName + "." + parameter1[0] + ".Inst.0.0." + versionId); - }); + + try { + CwmsDbTs tsDao = CwmsDbServiceLookup.buildCwmsDb(CwmsDbTs.class, c); + tsDao.deleteAll(c, officeId, locationName + "." + keyParameter[0] + ".Inst.0.0." + versionId); + tsDao.deleteAll(c, officeId, locationName + "." + parameter1[0] + ".Inst.0.0." + versionId); + } catch (SQLException e) { + throw new RuntimeException(e); + } + + assertNotNull(timeSeriesProfileInstance); + }, CwmsDataApiSetupCallback.getWebUser()); } private TimeSeriesProfileInstance retrieveTimeSeriesProfileInstance(String officeId, String locationName, String keyParameter, String version, String unit, @@ -349,14 +423,11 @@ private TimeSeriesProfileInstance retrieveTimeSeriesProfileInstance(String offic .withOfficeId(officeId) .withName(locationName) .build(); - try { - result[0] = timeSeriesProfileInstanceDao.retrieveTimeSeriesProfileInstance(location, keyParameter, version, + result[0] = timeSeriesProfileInstanceDao.retrieveTimeSeriesProfileInstance(location, keyParameter, version, unit, startTime, endTime, timeZone, startInclusive ? "T" : "F", endInclusive ? "T" : "F", previous ? "T" : "F", next ? "T" : "F", versionDate, maxVersion ? "T" : "F"); - } catch (Exception ex) { - ex.printStackTrace(); - } - }); + + }, CwmsDataApiSetupCallback.getWebUser()); return result[0]; } @@ -365,19 +436,18 @@ private void storeTimeSeriesProfileInstance(String officeId, String location, St CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); databaseLink.connection(c -> { DSLContext context = getDslContext(c, databaseLink.getOfficeId()); + TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile(officeId, location, keyParameter[0], parameter1[0]); + TimeSeriesProfileDao profileDao = new TimeSeriesProfileDao(context); + profileDao.storeTimeSeriesProfile(timeSeriesProfile, false); /// create an instance for parameter Depth TimeSeriesProfileInstanceDao timeSeriesProfileInstanceDao = new TimeSeriesProfileInstanceDao(context); TimeSeriesProfileInstance timeseriesProfileInstance = buildTestTimeSeriesProfileInstance(officeId, location, keyParameter, parameter1, version, dateTimeArray, valueArray, timeZone, versionInstant); String storeRule = StoreRule.REPLACE_ALL.toString(); - try { - timeSeriesProfileInstanceDao.storeTimeSeriesProfileInstance(timeseriesProfileInstance, version, versionInstant, storeRule, "F"); - } catch (Exception ex) { - ex.printStackTrace(); - throw (ex); - } - }); + timeSeriesProfileInstanceDao.storeTimeSeriesProfileInstance(timeseriesProfileInstance, version, versionInstant, storeRule, "F"); + + }, CwmsDataApiSetupCallback.getWebUser()); } private static TimeSeriesProfileInstance buildTestTimeSeriesProfileInstance(String officeId, String locationName, String[] keyParameterUnit, String[] parameterUnit1, String version, @@ -430,6 +500,32 @@ static private TimeSeriesProfile buildTestTimeSeriesProfile(String officeId, Str .build(); } + private TimeSeriesProfileParser buildTestTimeSeriesProfileParser(String officeId, String location, String[] parameterArray, int[][] parameterStartEndArray, String[] parameterUnitArray, char recordDelimiter, String timeFormat, String timeZone, int[] timeStartEnd) { + List parameterInfoList = new ArrayList<>(); + for (int i = 0; i < parameterArray.length; i++) { + parameterInfoList.add(new ParameterInfo.Builder() + .withParameter(parameterArray[i]) + .withStartColumn(parameterStartEndArray[i][0]) + .withEndColumn(parameterStartEndArray[i][1]) + .withUnit(parameterUnitArray[i]) + .build()); + } + + CwmsId locationId = new CwmsId.Builder().withOfficeId(officeId).withName(location).build(); + return + + new TimeSeriesProfileParser.Builder() + .withLocationId(locationId) + .withKeyParameter(parameterArray[0]) + .withRecordDelimiter(recordDelimiter) + .withTimeFormat(timeFormat) + .withTimeZone(timeZone) + .withTimeStartColumn(timeStartEnd[0]) + .withTimeEndColumn(timeStartEnd[1]) + .withTimeInTwoFields(false) + .withParameterInfoList(parameterInfoList) + .build(); + } static private TimeSeriesProfileParser buildTestTimeSeriesProfileParser(String officeId, String location, String[] parameterArray, int[] parameterIndexArray, String[] parameterUnitArray, char recordDelimiter, char fieldDelimiter, String timeFormat, String timeZone, int timeField) { diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDaoIT.java b/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDaoIT.java index b2ad6d3c1..4052620fd 100644 --- a/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDaoIT.java +++ b/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDaoIT.java @@ -26,20 +26,24 @@ final class TimeSeriesProfileParserDaoIT extends DataApiTestIT { @Test void testStoreAndRetrieve() throws Exception { + String officeId = "LRL"; + String locationName = "Glensboro"; + String locationName1 = "Greensburg"; + String[] parameter = {"Depth", "Temp-Water"}; CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); databaseLink.connection(c -> { DSLContext context = getDslContext(c, databaseLink.getOfficeId()); TimeSeriesProfileDao timeSeriesProfileDao = new TimeSeriesProfileDao(context); - TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile("AAA", "Depth"); + TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile(officeId, locationName, parameter[0], parameter); timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfile, false); - timeSeriesProfile = buildTestTimeSeriesProfile("BBB", "Depth"); + timeSeriesProfile = buildTestTimeSeriesProfile(officeId, locationName1, parameter[0], parameter); timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfile, false); TimeSeriesProfileParserDao timeSeriesProfileParserDao = new TimeSeriesProfileParserDao(context); - TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser("AAA", "Depth"); + TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser(officeId, locationName, parameter[0]); timeSeriesProfileParserDao.storeTimeSeriesProfileParser(timeSeriesProfileParser, false); TimeSeriesProfileParser retrieved = timeSeriesProfileParserDao.retrieveTimeSeriesProfileParser(timeSeriesProfileParser.getLocationId().getName(), @@ -54,22 +58,25 @@ void testStoreAndRetrieve() throws Exception { timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfile.getLocationId().getName(), timeSeriesProfile.getKeyParameter(), timeSeriesProfile.getLocationId().getOfficeId()); - }); + }, CwmsDataApiSetupCallback.getWebUser()); } @Test void testStoreAndDelete() throws SQLException { + String officeId = "LRL"; + String locationName = "Glensboro"; + String[] parameter = { "Depth", "Temp-Water"}; CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); databaseLink.connection(c -> { DSLContext context = getDslContext(c, databaseLink.getOfficeId()); TimeSeriesProfileDao timeSeriesProfileDao = new TimeSeriesProfileDao(context); - TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile("AAA", "Depth"); + TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile(officeId, locationName, parameter[0], parameter); timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfile, false); TimeSeriesProfileParserDao timeSeriesProfileParserDao = new TimeSeriesProfileParserDao(context); - TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser("AAA", "Depth"); + TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser(officeId, locationName, parameter[0]); timeSeriesProfileParserDao.storeTimeSeriesProfileParser(timeSeriesProfileParser, false); timeSeriesProfileParserDao.deleteTimeSeriesProfileParser(timeSeriesProfileParser.getLocationId().getName(), @@ -81,87 +88,96 @@ void testStoreAndDelete() throws SQLException { timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfile.getLocationId().getName(), timeSeriesProfile.getKeyParameter(), timeSeriesProfile.getLocationId().getOfficeId()); - }); + }, CwmsDataApiSetupCallback.getWebUser()); } @Test void testStoreAndRetrieveMultiple() throws SQLException { CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); + String officeId = "LRL"; + String locationName = "Glensboro"; + String[] parameters = {"Depth", "Temp-Water"}; databaseLink.connection(c -> { DSLContext context = getDslContext(c, databaseLink.getOfficeId()); TimeSeriesProfileDao timeSeriesProfileDao = new TimeSeriesProfileDao(context); - TimeSeriesProfile timeSeriesProfileDepth = buildTestTimeSeriesProfile("AAA", "Depth"); - timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfileDepth, false); - TimeSeriesProfile timeSeriesProfileTemp = buildTestTimeSeriesProfile("BBB", "Temp-Water"); - timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfileTemp, false); - + List timeSeriesProfileList = new ArrayList<>(); + for(String parameter : parameters) { + TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile(officeId, locationName, parameter, parameters); + timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfile, false); + timeSeriesProfileList.add(timeSeriesProfile); + } TimeSeriesProfileParserDao timeSeriesProfileParserDao = new TimeSeriesProfileParserDao(context); - TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser("AAA", "Depth"); - timeSeriesProfileParserDao.storeTimeSeriesProfileParser(timeSeriesProfileParser, false); - timeSeriesProfileParser = buildTestTimeSeriesProfileParser("BBB", "Temp-Water"); - timeSeriesProfileParserDao.storeTimeSeriesProfileParser(timeSeriesProfileParser, false); + + for(String parameter : parameters) { + TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser(officeId, locationName, parameter); + timeSeriesProfileParserDao.storeTimeSeriesProfileParser(timeSeriesProfileParser, false); + } List profileParserList = timeSeriesProfileParserDao.retrieveTimeSeriesProfileParsers("*", "*", "*"); for (TimeSeriesProfileParser profileParser : profileParserList) { timeSeriesProfileParserDao.deleteTimeSeriesProfileParser(profileParser.getLocationId().getName(), profileParser.getKeyParameter(), profileParser.getLocationId().getOfficeId()); } - timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfileDepth.getLocationId().getName(), timeSeriesProfileDepth.getKeyParameter(), - timeSeriesProfileDepth.getLocationId().getOfficeId()); - timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfileTemp.getLocationId().getName(), timeSeriesProfileTemp.getKeyParameter(), - timeSeriesProfileTemp.getLocationId().getOfficeId()); + for(TimeSeriesProfile timeSeriesProfile : timeSeriesProfileList) { + timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfile.getLocationId().getName(), timeSeriesProfile.getKeyParameter(), + timeSeriesProfile.getLocationId().getOfficeId()); + } + assertEquals(2, profileParserList.size()); - }); + }, CwmsDataApiSetupCallback.getWebUser()); } @Test void testStoreAndCopy() throws SQLException { + String officeId = "LRL"; + String locationName = "Glensboro"; + String locationName1 = "Greensburg"; + String[] parameter = {"Depth", "Temp-Water"}; CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); databaseLink.connection(c -> { DSLContext context = getDslContext(c, databaseLink.getOfficeId()); TimeSeriesProfileDao timeSeriesProfileDao = new TimeSeriesProfileDao(context); - TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile("AAA", "Depth"); + TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile(officeId, locationName, parameter[0], parameter); timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfile, false); - timeSeriesProfile = buildTestTimeSeriesProfile("BBB", "Depth"); + timeSeriesProfile = buildTestTimeSeriesProfile(officeId, locationName1, parameter[0], parameter); timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfile, false); TimeSeriesProfileParserDao timeSeriesProfileParserDao = new TimeSeriesProfileParserDao(context); - TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser("AAA", "Depth"); + TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser(officeId, locationName, parameter[0]); timeSeriesProfileParserDao.storeTimeSeriesProfileParser(timeSeriesProfileParser, false); TimeSeriesProfileParser retrieved = timeSeriesProfileParserDao.retrieveTimeSeriesProfileParser(timeSeriesProfileParser.getLocationId().getName(), timeSeriesProfileParser.getKeyParameter(), timeSeriesProfileParser.getLocationId().getOfficeId()); timeSeriesProfileParserDao.copyTimeSeriesProfileParser(timeSeriesProfileParser.getLocationId().getName(), - timeSeriesProfileParser.getKeyParameter(), timeSeriesProfileParser.getLocationId().getOfficeId(), "BBB"); + timeSeriesProfileParser.getKeyParameter(), timeSeriesProfileParser.getLocationId().getOfficeId(), locationName1); - TimeSeriesProfileParser retrieved1 = timeSeriesProfileParserDao.retrieveTimeSeriesProfileParser("BBB", + TimeSeriesProfileParser retrieved1 = timeSeriesProfileParserDao.retrieveTimeSeriesProfileParser(locationName1, timeSeriesProfileParser.getKeyParameter(), timeSeriesProfileParser.getLocationId().getOfficeId()); assertEquals(timeSeriesProfileParser.getKeyParameter(), retrieved.getKeyParameter()); - assertEquals("BBB", retrieved1.getLocationId().getName()); + assertEquals(locationName1, retrieved1.getLocationId().getName()); assertEquals(timeSeriesProfileParser.getTimeFormat(), retrieved1.getTimeFormat()); - }); + }, CwmsDataApiSetupCallback.getWebUser()); } - private static TimeSeriesProfile buildTestTimeSeriesProfile(String location, String parameter) { - String officeId = "HEC"; + private static TimeSeriesProfile buildTestTimeSeriesProfile(String officeId, String location, String keyParameter, String[] parameters) { CwmsId locationId = new CwmsId.Builder().withOfficeId(officeId).withName(location).build(); return new TimeSeriesProfile.Builder() .withLocationId(locationId) - .withKeyParameter(parameter) - .withParameterList(Arrays.asList("Temp-Water", "Depth")) + .withKeyParameter(keyParameter) + .withParameterList(Arrays.asList(parameters)) .build(); } - static private TimeSeriesProfileParser buildTestTimeSeriesProfileParser(String location, String keyParameter) { + static private TimeSeriesProfileParser buildTestTimeSeriesProfileParser(String officeId, String location, String keyParameter) { List parameterInfoList = new ArrayList<>(); parameterInfoList.add(new ParameterInfo.Builder() .withParameter("Depth") @@ -173,8 +189,7 @@ static private TimeSeriesProfileParser buildTestTimeSeriesProfileParser(String l .withIndex(5) .withUnit("bar") .build()); - String officeId = "HEC"; - CwmsId locationId = new CwmsId.Builder().withOfficeId(officeId).withName(location).build(); + CwmsId locationId = new CwmsId.Builder().withOfficeId(officeId).withName(location).build(); return new TimeSeriesProfileParser.Builder() diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserTest.java b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserTest.java index f1583d46c..104cf51dc 100644 --- a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserTest.java +++ b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserTest.java @@ -24,7 +24,15 @@ void testTimeSeriesProfileSerializationRoundTrip() { TimeSeriesProfileParser deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2, TimeSeriesProfileParser.class), serialized, TimeSeriesProfileParser.class); testAssertEquals(timeSeriesProfileParser, deserialized, "Roundtrip serialization failed"); } + @Test + void testTimeSeriesProfileColumnarSerializationRoundTrip() { + TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParserColumnar(); + ContentType contentType = Formats.parseHeader(Formats.JSONV2, TimeSeriesProfileParser.class); + String serialized = Formats.format(contentType, timeSeriesProfileParser); + TimeSeriesProfileParser deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2, TimeSeriesProfileParser.class), serialized, TimeSeriesProfileParser.class); + testAssertEquals(timeSeriesProfileParser, deserialized, "Roundtrip serialization failed"); + } @Test void testTimeSeriesProfileSerializationRoundTripFromFile() throws Exception { TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser(); @@ -34,6 +42,15 @@ void testTimeSeriesProfileSerializationRoundTripFromFile() throws Exception { TimeSeriesProfileParser deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2, TimeSeriesProfileParser.class), serialized, TimeSeriesProfileParser.class); testAssertEquals(timeSeriesProfileParser, deserialized, "Roundtrip serialization from file failed"); } + @Test + void testTimeSeriesProfileSerializationRoundTripColumnarFromFile() throws Exception { + TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParserColumnar(); + InputStream resource = this.getClass().getResourceAsStream("/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileparsercolumnar.json"); + assertNotNull(resource); + String serialized = IOUtils.toString(resource, StandardCharsets.UTF_8); + TimeSeriesProfileParser deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2, TimeSeriesProfileParser.class), serialized, TimeSeriesProfileParser.class); + testAssertEquals(timeSeriesProfileParser, deserialized, "Roundtrip serialization from file failed"); + } private static TimeSeriesProfileParser buildTestTimeSeriesProfileParser() { List parameterInfo = new ArrayList<>(); @@ -64,6 +81,37 @@ private static TimeSeriesProfileParser buildTestTimeSeriesProfileParser() { .withParameterInfoList(parameterInfo) .build(); } + private static TimeSeriesProfileParser buildTestTimeSeriesProfileParserColumnar() { + List parameterInfo = new ArrayList<>(); + parameterInfo.add(new ParameterInfo.Builder() + .withParameter("Depth") + .withUnit("m") + .withStartColumn(11) + .withEndColumn(20) + .build()); + parameterInfo.add(new ParameterInfo.Builder() + .withParameter("Temp-Water") + .withUnit("F") + .withStartColumn(21) + .withEndColumn(30) + .build()); + CwmsId locationId = new CwmsId.Builder() + .withOfficeId("SWT") + .withName("location") + .build(); + return + new TimeSeriesProfileParser.Builder() + .withLocationId(locationId) + .withKeyParameter("Depth") + .withRecordDelimiter((char) 10) + .withTimeStartColumn(1) + .withTimeEndColumn(10) + .withTimeFormat("MM/DD/YYYY,HH24:MI:SS") + .withTimeZone("UTC") + .withTimeInTwoFields(false) + .withParameterInfoList(parameterInfo) + .build(); + } private void testAssertEquals(TimeSeriesProfileParser expected, TimeSeriesProfileParser actual, String message) { assertEquals(expected.getLocationId().getName(), actual.getLocationId().getName(), message); @@ -78,15 +126,19 @@ private void testAssertEquals(TimeSeriesProfileParser expected, TimeSeriesProfil assertEquals(expected.getRecordDelimiter(), actual.getRecordDelimiter(), message); assertEquals(expected.getTimeZone(), actual.getTimeZone()); assertEquals(expected.getTimeInTwoFields(), actual.getTimeInTwoFields()); + assertEquals(expected.getTimeEndColumn(), actual.getTimeEndColumn()); + assertEquals(expected.getTimeStartColumn(), actual.getTimeStartColumn()); } private void testAssertEquals(List expected, List actual, String message) { assertEquals(expected.size(), actual.size()); for(int i=0;i Date: Wed, 24 Jul 2024 13:56:13 -0700 Subject: [PATCH 18/26] use Temp-Water instead of Temperature --- .../data/dto/timeseriesprofile/timeseriesprofileinstance.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileinstance.json b/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileinstance.json index 364f3b5dc..8cdf6914e 100644 --- a/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileinstance.json +++ b/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileinstance.json @@ -6,7 +6,7 @@ "name": "location" }, "key-parameter": "Depth", - "parameter-list": [ "Temperature", "Depth"], + "parameter-list": [ "Temp-Water", "Depth"], "description": "Description", "reference-ts-id":{ "office-id": "office", @@ -15,7 +15,7 @@ }, "time-series-list" : [ { - "parameter": "Temperature", + "parameter": "Temp-Water", "unit": "F", "time-zone": "PST", "time-value-pair-list": From e6f9d96800c4e245b51fd785fc268d1e6fc9d1f6 Mon Sep 17 00:00:00 2001 From: Andreas Christmann Date: Wed, 24 Jul 2024 14:54:03 -0700 Subject: [PATCH 19/26] change profile time series json to match time series --- .../TimeSeriesProfileInstanceDao.java | 10 +-- .../timeseriesprofile/ProfileTimeSeries.java | 14 ++-- .../TimeSeriesProfileInstanceDaoIT.java | 6 +- .../TimeSeriesProfileInstanceTest.java | 4 +- .../timeseriesprofileinstance.json | 68 +++++++++---------- 5 files changed, 51 insertions(+), 51 deletions(-) diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDao.java b/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDao.java index f5ce9226a..29ddefaa1 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDao.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDao.java @@ -87,11 +87,11 @@ void storeTimeSeriesProfileInstance(TimeSeriesProfileInstance timeseriesProfileI TS_PROF_DATA_TAB_T records = new TS_PROF_DATA_TAB_T(); - for(int i=0; i timeValuePairList; + private final List values; protected ProfileTimeSeries(Builder builder) { parameter = builder.parameter; unit = builder.unit; - timeValuePairList = builder.timeValuePairList; + values = builder.values; timeZone = builder.timeZone; } public String getTimeZone() @@ -40,19 +40,19 @@ public String getUnit() { return unit; } - public List getTimeValuePairList() + public List getValues() { - return timeValuePairList; + return values; } @JsonPOJOBuilder @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) public static final class Builder { - private List timeValuePairList; + private List values; private String unit; private String parameter; private String timeZone; - public Builder withTimeValuePairList(List timeValuePairList) { - this.timeValuePairList = timeValuePairList; + public Builder withValues(List values) { + this.values = values; return this; } diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDaoIT.java b/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDaoIT.java index f301ba550..00eb79b74 100644 --- a/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDaoIT.java +++ b/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDaoIT.java @@ -254,7 +254,7 @@ void testRetrieveTimeSeriesProfileInstance() throws SQLException { // check if the retrieved timeseries profile instance has the same tineseries as the one we stored assertEquals(2, result.getTimeSeriesList().size()); - assertEquals(2, result.getTimeSeriesList().get(0).getTimeValuePairList().size()); + assertEquals(2, result.getTimeSeriesList().get(0).getValues().size()); }, CwmsDataApiSetupCallback.getWebUser()); } @@ -469,7 +469,7 @@ private static TimeSeriesProfileInstance buildTestTimeSeriesProfileInstance(Stri .withParameter(keyParameterUnit[0]) .withUnit(keyParameterUnit[1]) .withTimeZone(timeZone) - .withTimeValuePairList(timeValuePairList) + .withValues(timeValuePairList) .build(); List timeSeriesList = new ArrayList<>(); @@ -478,7 +478,7 @@ private static TimeSeriesProfileInstance buildTestTimeSeriesProfileInstance(Stri .withParameter(parameterUnit1[0]) .withUnit(parameterUnit1[1]) .withTimeZone(timeZone) - .withTimeValuePairList(timeValuePairList) + .withValues(timeValuePairList) .build(); timeSeriesList.add(profileTimeSeries); diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstanceTest.java b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstanceTest.java index ea9c786cc..de9369ea7 100644 --- a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstanceTest.java +++ b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstanceTest.java @@ -60,7 +60,7 @@ private List buildTimeSeriesList(List parameterList) .withParameter(parameter) .withUnit(PARAMETER_UNIT_MAP.get(parameter)) .withTimeZone("PST") - .withTimeValuePairList(buildTimeValueList()) + .withValues(buildTimeValueList()) .build(); timeSeriesList.add(profileTimeSeries); } @@ -90,7 +90,7 @@ private void testAssertEquals(ProfileTimeSeries expected, ProfileTimeSeries actu assertEquals(expected.getTimeZone(), actual.getTimeZone(), message); assertEquals(expected.getParameter(), actual.getParameter(), message); assertEquals(expected.getUnit(),actual.getUnit(), message); - testAssertEquals(expected.getTimeValuePairList(), actual.getTimeValuePairList()); + testAssertEquals(expected.getValues(), actual.getValues()); } private void testAssertEquals(List expected, List actual) { diff --git a/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileinstance.json b/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileinstance.json index 8cdf6914e..72a773b8f 100644 --- a/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileinstance.json +++ b/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileinstance.json @@ -1,50 +1,50 @@ { - "time-series-profile": - { + "time-series-profile": { "location-id": { "office-id": "office", "name": "location" }, - "key-parameter": "Depth", - "parameter-list": [ "Temp-Water", "Depth"], "description": "Description", - "reference-ts-id":{ + "parameter-list": [ + "Temperature", + "Depth" + ], + "key-parameter": "Depth", + "reference-ts-id": { "office-id": "office", "name": "location.Elev.Inst.0.0.REV" } }, - "time-series-list" : [ + "time-series-list": [ { - "parameter": "Temp-Water", - "unit": "F", - "time-zone": "PST", - "time-value-pair-list": - [ - { - "date-time": 1612869582120, - "value": "1.0" - }, - { - "date-time": 1612869582220, - "value": "3.0" - } - ] + "parameter": "Temperature", + "unit": "F", + "time-zone": "PST", + "values": [ + { + "date-time": 1612869582120, + "value": 1.0 + }, + { + "date-time": 1612869582220, + "value": 3.0 + } + ] }, { - "parameter": "Depth", - "unit": "ft", - "time-zone": "PST", - "time-value-pair-list": - [ - { - "date-time": 1612869582120, - "value": "1.0" - }, - { - "date-time": 1612869582220, - "value": "3.0" - } - ] + "parameter": "Depth", + "unit": "ft", + "time-zone": "PST", + "values": [ + { + "date-time": 1612869582120, + "value": 1.0 + }, + { + "date-time": 1612869582220, + "value": 3.0 + } + ] } ] } \ No newline at end of file From 4d9218408037ef8ef23a92582eaa87322b55c9dd Mon Sep 17 00:00:00 2001 From: Andreas Christmann Date: Wed, 24 Jul 2024 15:38:11 -0700 Subject: [PATCH 20/26] use real life names --- .../TimeSeriesProfileInstanceTest.java | 2 +- .../dto/timeseriesprofile/TimeSeriesProfileTest.java | 10 +++++----- .../timeseriesprofile/timeseriesprofileinstance.json | 12 ++++++------ 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstanceTest.java b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstanceTest.java index de9369ea7..87e1ddd25 100644 --- a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstanceTest.java +++ b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstanceTest.java @@ -22,7 +22,7 @@ public class TimeSeriesProfileInstanceTest { @BeforeAll public static void setup() throws Exception { PARAMETER_UNIT_MAP.put("Depth", "ft"); - PARAMETER_UNIT_MAP.put("Temperature", "F"); + PARAMETER_UNIT_MAP.put("Temp-Water", "F"); } @Test void testTimeSeriesProfileInstanceSerializationRoundTrip() { diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileTest.java b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileTest.java index d9332c0c6..acbf89072 100644 --- a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileTest.java +++ b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileTest.java @@ -35,19 +35,19 @@ void testTimeSeriesProfileSerializationRoundTripFromFile() throws Exception { static TimeSeriesProfile buildTestTimeSeriesProfile() { CwmsId locationId = new CwmsId.Builder() - .withName("location") - .withOfficeId("office") + .withName("SWAN") + .withOfficeId("SWT") .build(); CwmsId referenceTsId = new CwmsId.Builder() - .withName("location.Elev.Inst.0.0.REV") - .withOfficeId("office") + .withName("SWAN.Elev.Inst.1Hour.0.DSS-Obs") + .withOfficeId("SWT") .build(); return new TimeSeriesProfile.Builder() .withKeyParameter("Depth") .withReferenceTsId(referenceTsId) .withLocationId(locationId) .withDescription("Description") - .withParameterList(Arrays.asList("Temperature", "Depth")) + .withParameterList(Arrays.asList("Temp-Water", "Depth")) .build(); } diff --git a/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileinstance.json b/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileinstance.json index 72a773b8f..d4c82a026 100644 --- a/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileinstance.json +++ b/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileinstance.json @@ -1,23 +1,23 @@ { "time-series-profile": { "location-id": { - "office-id": "office", - "name": "location" + "office-id": "SWT", + "name": "SWAN" }, "description": "Description", "parameter-list": [ - "Temperature", + "Temp-Water", "Depth" ], "key-parameter": "Depth", "reference-ts-id": { - "office-id": "office", - "name": "location.Elev.Inst.0.0.REV" + "office-id": "SWT", + "name": "SWAN.Elev.Inst.1Hour.0.DSS-Obs" } }, "time-series-list": [ { - "parameter": "Temperature", + "parameter": "Temp-Water", "unit": "F", "time-zone": "PST", "values": [ From 614f9b272491b7ac5a02dba8f597a2091a6866f5 Mon Sep 17 00:00:00 2001 From: Andreas Christmann Date: Mon, 29 Jul 2024 10:09:38 -0700 Subject: [PATCH 21/26] Time series profile parser dao --- .../TimeSeriesProfileParserDao.java | 172 ++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDao.java diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDao.java b/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDao.java new file mode 100644 index 000000000..e7dd49c67 --- /dev/null +++ b/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDao.java @@ -0,0 +1,172 @@ +package cwms.cda.data.dao.timeseriesprofile; + +import java.util.ArrayList; +import java.util.List; + +import cwms.cda.data.dao.JooqDao; +import cwms.cda.data.dto.CwmsId; +import cwms.cda.data.dto.timeseriesprofile.ParameterInfo; +import cwms.cda.data.dto.timeseriesprofile.TimeSeriesProfileParser; +import org.jooq.DSLContext; +import org.jooq.Record; +import org.jooq.Result; +import org.jooq.impl.DSL; + +import usace.cwms.db.jooq.codegen.packages.CWMS_TS_PROFILE_PACKAGE; +import usace.cwms.db.jooq.codegen.packages.cwms_ts_profile.RETRIEVE_TS_PROFILE_PARSER; + + +public class TimeSeriesProfileParserDao extends JooqDao +{ + public TimeSeriesProfileParserDao(DSLContext dsl) + { + super(dsl); + } + + private List getParameterInfoList(String info, String recordDelimiter, String fieldDelimiter) + { + List parameterInfoList = new ArrayList<>(); + String[] records = info.split(recordDelimiter); + for(String aRecord : records) + { + String[] fields = aRecord.split(fieldDelimiter); + int index = Integer.parseInt(fields[2]); + ParameterInfo parameterInfo = new ParameterInfo.Builder().withParameter(fields[0]) + .withUnit(fields[1]) + .withIndex(index) + .build(); + parameterInfoList.add(parameterInfo); + } + return parameterInfoList; + } + + private String getParameterInfoString(TimeSeriesProfileParser timeSeriesProfileParser) + { + List parameterInfo = timeSeriesProfileParser.getParameterInfoList(); + + StringBuilder parameterInfoBuilder = new StringBuilder(); + parameterInfoBuilder.append(parameterInfo.get(0).getParameter()) + .append(",") + .append(parameterInfo.get(0).getUnit()) + .append(",") + .append( parameterInfo.get(0).getIndex()!=null?parameterInfo.get(0).getIndex():"") + .append(",") + .append( parameterInfo.get(0).getStartColumn()!=null?parameterInfo.get(0).getStartColumn():"") + .append(",") + .append( parameterInfo.get(0).getEndColumn()!=null?parameterInfo.get(0).getEndColumn():""); + for(int i = 1; i < parameterInfo.size(); i++) + { + parameterInfoBuilder.append(timeSeriesProfileParser.getRecordDelimiter()) + .append(parameterInfo.get(i).getParameter()) + .append(",") + .append(parameterInfo.get(i).getUnit()) + .append(",") + .append( parameterInfo.get(i).getIndex()!=null?parameterInfo.get(i).getIndex():"") + .append(",") + .append( parameterInfo.get(i).getStartColumn()!=null?parameterInfo.get(i).getStartColumn():"") + .append(",") + .append( parameterInfo.get(i).getEndColumn()!=null?parameterInfo.get(i).getEndColumn():""); + } + return parameterInfoBuilder.toString(); + } + + public void storeTimeSeriesProfileParser(TimeSeriesProfileParser timeSeriesProfileParser, boolean failIfExists) + { + connection(dsl, conn -> + CWMS_TS_PROFILE_PACKAGE.call_STORE_TS_PROFILE_PARSER(DSL.using(conn).configuration(), timeSeriesProfileParser.getLocationId().getName(), + timeSeriesProfileParser.getKeyParameter(), String.valueOf(timeSeriesProfileParser.getRecordDelimiter()), + timeSeriesProfileParser.getFieldDelimiter()!=null ? String.valueOf(timeSeriesProfileParser.getFieldDelimiter()) : null, timeSeriesProfileParser.getTimeField(), + timeSeriesProfileParser.getTimeStartColumn(), timeSeriesProfileParser.getTimeEndColumn(), timeSeriesProfileParser.getTimeFormat(), + timeSeriesProfileParser.getTimeZone(), getParameterInfoString(timeSeriesProfileParser), + timeSeriesProfileParser.getTimeInTwoFields()?"T":"F", + failIfExists?"T":"F", timeSeriesProfileParser.getFieldDelimiter()!=null?"T":"F", timeSeriesProfileParser.getLocationId().getOfficeId()) + ); + } + + public TimeSeriesProfileParser retrieveTimeSeriesProfileParser(String locationId, String parameterId, String officeId) + { + return connectionResult(dsl, conn -> { + RETRIEVE_TS_PROFILE_PARSER timeSeriesProfileParser = CWMS_TS_PROFILE_PACKAGE.call_RETRIEVE_TS_PROFILE_PARSER( + DSL.using(conn).configuration(), locationId, parameterId, officeId); + return map(timeSeriesProfileParser, locationId, parameterId, officeId); + }); + } + + public List retrieveTimeSeriesProfileParsers(String locationIdMask, String parameterIdMask, String officeIdMask) + { + return connectionResult(dsl, conn -> { + Result tsProfileParserResult = CWMS_TS_PROFILE_PACKAGE.call_CAT_TS_PROFILE_PARSER(DSL.using(conn).configuration(), + locationIdMask, parameterIdMask, officeIdMask); + List timeSeriesProfileParserList = new ArrayList<>(); + for(Record profileParser : tsProfileParserResult) + { + String recordDelimiter = profileParser.get("RECORD_DELIMITER", String.class); + String fieldDelimiter = profileParser.get("FIELD_DELIMITER", String.class); + Short timeField = profileParser.get("TIME_FIELD", Short.class); + + Result parameterInfoResult = profileParser.get("PARAMETER_INFO", Result.class); + + List parameterInfoList = new ArrayList<>(); + for(Record record : parameterInfoResult) + { + parameterInfoList.add(new ParameterInfo.Builder() + .withParameter((String) record.get("PARAMETER_ID")) + .withUnit((String) record.get("UNIT")) + .withIndex( record.get("FIELD_NUMBER", Short.class)) + .build()); + } + + + CwmsId locationId = new CwmsId.Builder() + .withOfficeId((String) profileParser.get("OFFICE_ID")) + .withName((String) profileParser.get("LOCATION_ID")) + .build(); + TimeSeriesProfileParser timeSeriesProfileParser = new TimeSeriesProfileParser.Builder() + .withLocationId(locationId) + .withKeyParameter((String) profileParser.get("KEY_PARAMTER_ID")) + .withTimeFormat((String) profileParser.get("TIME_FORMAT")) + .withTimeZone((String) profileParser.get("TIME_ZONE")) + .withRecordDelimiter(recordDelimiter.toCharArray()[0]) + .withFieldDelimiter(fieldDelimiter.toCharArray()[0]) + .withTimeField(timeField) + .withParameterInfoList(parameterInfoList) + .build(); + timeSeriesProfileParserList.add(timeSeriesProfileParser); + } + return timeSeriesProfileParserList; + }); + } + + + public void copyTimeSeriesProfileParser(String locationId, String parameterId, String officeId, String destinationLocation) + { + connection(dsl, conn -> + CWMS_TS_PROFILE_PACKAGE.call_COPY_TS_PROFILE_PARSER(DSL.using(conn).configuration(),locationId, parameterId, destinationLocation, + "F", officeId)); + } + public void deleteTimeSeriesProfileParser(String locationId, String parameterId, String officeId) + { + connection(dsl, conn -> + CWMS_TS_PROFILE_PACKAGE.call_DELETE_TS_PROFILE_PARSER(DSL.using(conn).configuration(), locationId, + parameterId, officeId) + ); + } + private TimeSeriesProfileParser map(RETRIEVE_TS_PROFILE_PARSER timeSeriesProfileParser, String locationName, String keyParameter, String officeId) + { + String info = timeSeriesProfileParser.getP_PARAMETER_INFO(); + List parameterInfo = getParameterInfoList(info, timeSeriesProfileParser.getP_RECORD_DELIMITER(), + timeSeriesProfileParser.getP_FIELD_DELIMITER()); + CwmsId locationId = new CwmsId.Builder().withOfficeId(officeId).withName(locationName).build(); + return new TimeSeriesProfileParser.Builder() + .withLocationId(locationId) + .withTimeField(timeSeriesProfileParser.getP_TIME_FIELD()) + .withTimeZone(timeSeriesProfileParser.getP_TIME_ZONE()) + .withTimeFormat(timeSeriesProfileParser.getP_TIME_FORMAT()) + .withKeyParameter(keyParameter) + .withFieldDelimiter(timeSeriesProfileParser.getP_FIELD_DELIMITER().toCharArray()[0]) + .withRecordDelimiter(timeSeriesProfileParser.getP_RECORD_DELIMITER().toCharArray()[0]) + .withTimeInTwoFields(false) + .withParameterInfoList(parameterInfo) + .build(); + } +} From a8432dc7d747513296c27150ffbfc1066d19d8a1 Mon Sep 17 00:00:00 2001 From: Andreas Christmann Date: Mon, 29 Jul 2024 10:12:14 -0700 Subject: [PATCH 22/26] changed record to recordParam --- .../dao/timeseriesprofile/TimeSeriesProfileParserDao.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDao.java b/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDao.java index e7dd49c67..e1cb32c41 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDao.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDao.java @@ -107,12 +107,12 @@ public List retrieveTimeSeriesProfileParsers(String loc Result parameterInfoResult = profileParser.get("PARAMETER_INFO", Result.class); List parameterInfoList = new ArrayList<>(); - for(Record record : parameterInfoResult) + for(Record recordParam : parameterInfoResult) { parameterInfoList.add(new ParameterInfo.Builder() - .withParameter((String) record.get("PARAMETER_ID")) - .withUnit((String) record.get("UNIT")) - .withIndex( record.get("FIELD_NUMBER", Short.class)) + .withParameter((String) recordParam.get("PARAMETER_ID")) + .withUnit((String) recordParam.get("UNIT")) + .withIndex( recordParam.get("FIELD_NUMBER", Short.class)) .build()); } From 691b79cafa4601705377e6f71548ee3321add0c0 Mon Sep 17 00:00:00 2001 From: Andreas Christmann Date: Tue, 30 Jul 2024 11:30:40 -0700 Subject: [PATCH 23/26] subclassed TimeSeriesProfileParser into Indexed and Columnar --- .../TimeSeriesProfileParserDao.java | 112 +++++++++++------ .../dto/timeseriesprofile/ParameterInfo.java | 97 ++------------ .../ParameterInfoColumnar.java | 67 ++++++++++ .../ParameterInfoIndexed.java | 59 +++++++++ .../timeseriesprofile/ProfileTimeSeries.java | 2 +- .../timeseriesprofile/TimeSeriesProfile.java | 7 +- .../TimeSeriesProfileInstance.java | 6 +- .../TimeSeriesProfileParser.java | 118 +++--------------- .../TimeSeriesProfileParserColumnar.java | 70 +++++++++++ .../TimeSeriesProfileParserIndexed.java | 68 ++++++++++ .../TimeSeriesProfileInstanceDaoIT.java | 46 +++---- .../TimeSeriesProfileParserDaoIT.java | 36 +++--- .../TimeSeriesProfileInstanceTest.java | 2 +- .../TimeSeriesProfileParserTest.java | 117 ++++++++++------- .../timeSeriesProfileDataColumnar.txt | 3 +- .../timeseriesprofile/timeseriesprofile.json | 23 ++-- .../timeseriesprofileparsercolumnar.json | 3 + ...on => timeseriesprofileparserindexed.json} | 3 + 18 files changed, 508 insertions(+), 331 deletions(-) create mode 100644 cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfoColumnar.java create mode 100644 cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfoIndexed.java create mode 100644 cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserColumnar.java create mode 100644 cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserIndexed.java rename cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/{timeseriesprofileparser.json => timeseriesprofileparserindexed.json} (79%) diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDao.java b/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDao.java index e1cb32c41..5a995859b 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDao.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDao.java @@ -6,7 +6,11 @@ import cwms.cda.data.dao.JooqDao; import cwms.cda.data.dto.CwmsId; import cwms.cda.data.dto.timeseriesprofile.ParameterInfo; +import cwms.cda.data.dto.timeseriesprofile.ParameterInfoColumnar; +import cwms.cda.data.dto.timeseriesprofile.ParameterInfoIndexed; import cwms.cda.data.dto.timeseriesprofile.TimeSeriesProfileParser; +import cwms.cda.data.dto.timeseriesprofile.TimeSeriesProfileParserColumnar; +import cwms.cda.data.dto.timeseriesprofile.TimeSeriesProfileParserIndexed; import org.jooq.DSLContext; import org.jooq.Record; import org.jooq.Result; @@ -31,9 +35,9 @@ private List getParameterInfoList(String info, String recordDelim { String[] fields = aRecord.split(fieldDelimiter); int index = Integer.parseInt(fields[2]); - ParameterInfo parameterInfo = new ParameterInfo.Builder().withParameter(fields[0]) + ParameterInfo parameterInfo = new ParameterInfoIndexed.Builder().withIndex(index) + .withParameter(fields[0]) .withUnit(fields[1]) - .withIndex(index) .build(); parameterInfoList.add(parameterInfo); } @@ -45,44 +49,40 @@ private String getParameterInfoString(TimeSeriesProfileParser timeSeriesProfileP List parameterInfo = timeSeriesProfileParser.getParameterInfoList(); StringBuilder parameterInfoBuilder = new StringBuilder(); - parameterInfoBuilder.append(parameterInfo.get(0).getParameter()) - .append(",") - .append(parameterInfo.get(0).getUnit()) - .append(",") - .append( parameterInfo.get(0).getIndex()!=null?parameterInfo.get(0).getIndex():"") - .append(",") - .append( parameterInfo.get(0).getStartColumn()!=null?parameterInfo.get(0).getStartColumn():"") - .append(",") - .append( parameterInfo.get(0).getEndColumn()!=null?parameterInfo.get(0).getEndColumn():""); + parameterInfoBuilder.append(parameterInfo.get(0).parameterInfoString()); + for(int i = 1; i < parameterInfo.size(); i++) { parameterInfoBuilder.append(timeSeriesProfileParser.getRecordDelimiter()) - .append(parameterInfo.get(i).getParameter()) - .append(",") - .append(parameterInfo.get(i).getUnit()) - .append(",") - .append( parameterInfo.get(i).getIndex()!=null?parameterInfo.get(i).getIndex():"") - .append(",") - .append( parameterInfo.get(i).getStartColumn()!=null?parameterInfo.get(i).getStartColumn():"") - .append(",") - .append( parameterInfo.get(i).getEndColumn()!=null?parameterInfo.get(i).getEndColumn():""); + .append(parameterInfo.get(i).parameterInfoString()); } return parameterInfoBuilder.toString(); } - public void storeTimeSeriesProfileParser(TimeSeriesProfileParser timeSeriesProfileParser, boolean failIfExists) + public void storeTimeSeriesProfileParser(TimeSeriesProfileParserIndexed timeSeriesProfileParser, boolean failIfExists) { connection(dsl, conn -> - CWMS_TS_PROFILE_PACKAGE.call_STORE_TS_PROFILE_PARSER(DSL.using(conn).configuration(), timeSeriesProfileParser.getLocationId().getName(), - timeSeriesProfileParser.getKeyParameter(), String.valueOf(timeSeriesProfileParser.getRecordDelimiter()), - timeSeriesProfileParser.getFieldDelimiter()!=null ? String.valueOf(timeSeriesProfileParser.getFieldDelimiter()) : null, timeSeriesProfileParser.getTimeField(), - timeSeriesProfileParser.getTimeStartColumn(), timeSeriesProfileParser.getTimeEndColumn(), timeSeriesProfileParser.getTimeFormat(), - timeSeriesProfileParser.getTimeZone(), getParameterInfoString(timeSeriesProfileParser), - timeSeriesProfileParser.getTimeInTwoFields()?"T":"F", - failIfExists?"T":"F", timeSeriesProfileParser.getFieldDelimiter()!=null?"T":"F", timeSeriesProfileParser.getLocationId().getOfficeId()) + CWMS_TS_PROFILE_PACKAGE.call_STORE_TS_PROFILE_PARSER(DSL.using(conn).configuration(), timeSeriesProfileParser.getLocationId().getName(), + timeSeriesProfileParser.getKeyParameter(), String.valueOf(timeSeriesProfileParser.getRecordDelimiter()), + String.valueOf(timeSeriesProfileParser.getFieldDelimiter()), timeSeriesProfileParser.getTimeField(), + null, null, timeSeriesProfileParser.getTimeFormat(), + timeSeriesProfileParser.getTimeZone(), getParameterInfoString(timeSeriesProfileParser), + timeSeriesProfileParser.getTimeInTwoFields()?"T":"F", + failIfExists?"T":"F", "T", timeSeriesProfileParser.getLocationId().getOfficeId()) + ); + } + public void storeTimeSeriesProfileParser(TimeSeriesProfileParserColumnar timeSeriesProfileParser, boolean failIfExists) + { + connection(dsl, conn -> + CWMS_TS_PROFILE_PACKAGE.call_STORE_TS_PROFILE_PARSER(DSL.using(conn).configuration(), timeSeriesProfileParser.getLocationId().getName(), + timeSeriesProfileParser.getKeyParameter(), String.valueOf(timeSeriesProfileParser.getRecordDelimiter()), + null, null, + timeSeriesProfileParser.getTimeStartColumn(), timeSeriesProfileParser.getTimeEndColumn(), timeSeriesProfileParser.getTimeFormat(), + timeSeriesProfileParser.getTimeZone(), getParameterInfoString(timeSeriesProfileParser), + timeSeriesProfileParser.getTimeInTwoFields()?"T":"F", + failIfExists?"T":"F", "F", timeSeriesProfileParser.getLocationId().getOfficeId()) ); } - public TimeSeriesProfileParser retrieveTimeSeriesProfileParser(String locationId, String parameterId, String officeId) { return connectionResult(dsl, conn -> { @@ -103,17 +103,28 @@ public List retrieveTimeSeriesProfileParsers(String loc String recordDelimiter = profileParser.get("RECORD_DELIMITER", String.class); String fieldDelimiter = profileParser.get("FIELD_DELIMITER", String.class); Short timeField = profileParser.get("TIME_FIELD", Short.class); - + Short timeStartCol = profileParser.get("TIME_START_COL", Short.class); + Short timeEndCol = profileParser.get("TIME_END_COL", Short.class); Result parameterInfoResult = profileParser.get("PARAMETER_INFO", Result.class); List parameterInfoList = new ArrayList<>(); for(Record recordParam : parameterInfoResult) { - parameterInfoList.add(new ParameterInfo.Builder() - .withParameter((String) recordParam.get("PARAMETER_ID")) - .withUnit((String) recordParam.get("UNIT")) - .withIndex( recordParam.get("FIELD_NUMBER", Short.class)) - .build()); + if(timeField!=null) { + parameterInfoList.add(new ParameterInfoIndexed.Builder() + .withIndex(recordParam.get("FIELD_NUMBER", Short.class)) + .withParameter((String) recordParam.get("PARAMETER_ID")) + .withUnit((String) recordParam.get("UNIT")) + .build()); + } + else { + parameterInfoList.add(new ParameterInfoColumnar.Builder() + .withStartColumn(recordParam.get("START_COL", Short.class)) + .withEndColumn(recordParam.get("END_COL", Short.class)) + .withParameter((String) recordParam.get("PARAMETER_ID")) + .withUnit((String) recordParam.get("UNIT")) + .build()); + } } @@ -121,17 +132,36 @@ public List retrieveTimeSeriesProfileParsers(String loc .withOfficeId((String) profileParser.get("OFFICE_ID")) .withName((String) profileParser.get("LOCATION_ID")) .build(); - TimeSeriesProfileParser timeSeriesProfileParser = new TimeSeriesProfileParser.Builder() + TimeSeriesProfileParser timeSeriesProfileParser ; + if(timeField!=null) + { + timeSeriesProfileParser = new TimeSeriesProfileParserIndexed.Builder() + .withFieldDelimiter(fieldDelimiter.toCharArray()[0]) + .withTimeField(timeField) .withLocationId(locationId) .withKeyParameter((String) profileParser.get("KEY_PARAMTER_ID")) .withTimeFormat((String) profileParser.get("TIME_FORMAT")) .withTimeZone((String) profileParser.get("TIME_ZONE")) .withRecordDelimiter(recordDelimiter.toCharArray()[0]) - .withFieldDelimiter(fieldDelimiter.toCharArray()[0]) - .withTimeField(timeField) .withParameterInfoList(parameterInfoList) .build(); - timeSeriesProfileParserList.add(timeSeriesProfileParser); + timeSeriesProfileParserList.add(timeSeriesProfileParser); + } + else if(timeStartCol!=null && timeEndCol!=null) + { + timeSeriesProfileParser = new TimeSeriesProfileParserColumnar.Builder() + .withTimeStartColumn(timeStartCol) + .withTimeEndColumn(timeEndCol) + .withLocationId(locationId) + .withKeyParameter((String) profileParser.get("KEY_PARAMTER_ID")) + .withTimeFormat((String) profileParser.get("TIME_FORMAT")) + .withTimeZone((String) profileParser.get("TIME_ZONE")) + .withRecordDelimiter(recordDelimiter.toCharArray()[0]) + .withParameterInfoList(parameterInfoList) + .build(); + timeSeriesProfileParserList.add(timeSeriesProfileParser); + } + } return timeSeriesProfileParserList; }); @@ -159,11 +189,11 @@ private TimeSeriesProfileParser map(RETRIEVE_TS_PROFILE_PARSER timeSeriesProfile CwmsId locationId = new CwmsId.Builder().withOfficeId(officeId).withName(locationName).build(); return new TimeSeriesProfileParser.Builder() .withLocationId(locationId) - .withTimeField(timeSeriesProfileParser.getP_TIME_FIELD()) +// .withTimeField(timeSeriesProfileParser.getP_TIME_FIELD()) .withTimeZone(timeSeriesProfileParser.getP_TIME_ZONE()) .withTimeFormat(timeSeriesProfileParser.getP_TIME_FORMAT()) .withKeyParameter(keyParameter) - .withFieldDelimiter(timeSeriesProfileParser.getP_FIELD_DELIMITER().toCharArray()[0]) +// .withFieldDelimiter(timeSeriesProfileParser.getP_FIELD_DELIMITER().toCharArray()[0]) .withRecordDelimiter(timeSeriesProfileParser.getP_RECORD_DELIMITER().toCharArray()[0]) .withTimeInTwoFields(false) .withParameterInfoList(parameterInfo) diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfo.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfo.java index 033b5a0e5..13bbdff4c 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfo.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfo.java @@ -1,32 +1,26 @@ package cwms.cda.data.dto.timeseriesprofile; -import java.util.Objects; - -import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.databind.PropertyNamingStrategies; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonNaming; import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; -import cwms.cda.api.errors.FieldException; import cwms.cda.data.dto.CwmsDTOBase; -@JsonDeserialize(builder = ParameterInfo.Builder.class) -@JsonInclude(JsonInclude.Include.NON_NULL) -@JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) -public final class ParameterInfo implements CwmsDTOBase { +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") +@JsonSubTypes({@JsonSubTypes.Type(value = ParameterInfoIndexed.class), + @JsonSubTypes.Type(value = ParameterInfoColumnar.class) +}) + +public abstract class ParameterInfo extends CwmsDTOBase { private final String parameter; private final String unit; - private final Integer index; - private final Integer startColumn; - private final Integer endColumn; ParameterInfo(ParameterInfo.Builder builder) { parameter = builder.parameter; unit = builder.unit; - index = builder.index; - startColumn = builder.startColumn; - endColumn = builder.endColumn; } + public abstract String parameterInfoString(); public String getParameter() { return parameter; @@ -36,86 +30,21 @@ public String getUnit() { return unit; } - public Integer getIndex() { - return index; - } - - public Integer getStartColumn(){ - return startColumn; - } - public Integer getEndColumn(){ - return endColumn; - } - @Override - public void validate() throws FieldException { - if(index==null && !(startColumn!=null && endColumn!=null)) - { - throw new FieldException("if index is null, startColumn and endColumn must be defined!"); - } - if(index!=null && (startColumn!=null || endColumn!=null)) - { - throw new FieldException("if index is defined, startColumn and endColumn must not be defined!"); - } - } - - @Override - public int hashCode() { - int result = Objects.hashCode(getParameter()); - result = 31 * result + Objects.hashCode(getUnit()); - result = 31 * result + Objects.hashCode(getIndex()); - return result; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - ParameterInfo that = (ParameterInfo) o; - return Objects.equals(getParameter(), that.getParameter()) - && Objects.equals(getUnit(), that.getUnit()) - && Objects.equals(getIndex(), that.getIndex()); - } - @JsonPOJOBuilder @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) - public static final class Builder { + public abstract static class Builder { private String parameter; private String unit; - private Integer index; - private Integer startColumn; - private Integer endColumn; - public ParameterInfo.Builder withParameter(String parameter) { + public Builder withParameter(String parameter) { this.parameter = parameter; return this; } - public ParameterInfo.Builder withUnit(String unit) { + public Builder withUnit(String unit) { this.unit = unit; return this; } - - public ParameterInfo.Builder withIndex(int index) { - this.index = index; - return this; - } - - public ParameterInfo.Builder withStartColumn(int startColumn){ - this.startColumn = startColumn; - return this; - } - public ParameterInfo.Builder withEndColumn(int endColumn){ - this.endColumn = endColumn; - return this; - } - public ParameterInfo build() { - return new ParameterInfo(this); - } - + public abstract ParameterInfo build(); } } \ No newline at end of file diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfoColumnar.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfoColumnar.java new file mode 100644 index 000000000..85a819c91 --- /dev/null +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfoColumnar.java @@ -0,0 +1,67 @@ +package cwms.cda.data.dto.timeseriesprofile; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.PropertyNamingStrategies; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; +import cwms.cda.data.dto.CwmsDTOValidator; + + +@JsonDeserialize(builder = ParameterInfoColumnar.Builder.class) +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) +public final class ParameterInfoColumnar extends ParameterInfo { + private final Integer startColumn; + private final Integer endColumn; + + ParameterInfoColumnar(ParameterInfoColumnar.Builder builder) { + super(builder); + startColumn = builder.startColumn; + endColumn = builder.endColumn; + } + + public Integer getStartColumn(){ + return startColumn; + } + public Integer getEndColumn(){ + return endColumn; + } + @Override + protected void validateInternal(CwmsDTOValidator validator) { + validator.required(startColumn, "startColumn"); + validator.required(endColumn, "endColumn"); + } + + public String parameterInfoString() + { + return getParameter() + + "," + + getUnit() + + "," + + "," + + getStartColumn() + + "," + + getEndColumn(); + } + + @JsonPOJOBuilder + @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) + public static final class Builder extends ParameterInfo.Builder{ + private Integer startColumn; + private Integer endColumn; + + public ParameterInfoColumnar.Builder withStartColumn(int startColumn){ + this.startColumn = startColumn; + return this; + } + public ParameterInfoColumnar.Builder withEndColumn(int endColumn){ + this.endColumn = endColumn; + return this; + } + public ParameterInfo build() { + return new ParameterInfoColumnar(this); + } + + } +} \ No newline at end of file diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfoIndexed.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfoIndexed.java new file mode 100644 index 000000000..f38e43e2a --- /dev/null +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfoIndexed.java @@ -0,0 +1,59 @@ +package cwms.cda.data.dto.timeseriesprofile; + + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.PropertyNamingStrategies; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; +import cwms.cda.data.dto.CwmsDTOValidator; + +@JsonDeserialize(builder = ParameterInfoIndexed.Builder.class) +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) +public final class ParameterInfoIndexed extends ParameterInfo { + private final Integer index; + + ParameterInfoIndexed(ParameterInfoIndexed.Builder builder) { + super(builder); + index = builder.index; + } + public Integer getIndex() { + return index; + } + + @Override + protected void validateInternal(CwmsDTOValidator validator) { + validator.required(getIndex(),"index"); + } + + @Override + public String parameterInfoString() + { + return getParameter() + + "," + + getUnit() + + "," + + getIndex() + + "," + + ","; + } + + + + + @JsonPOJOBuilder + @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) + public static final class Builder extends ParameterInfo.Builder{ + private Integer index; + + public ParameterInfoIndexed.Builder withIndex(int index) { + this.index = index; + return this; + } + public ParameterInfo build() { + return new ParameterInfoIndexed(this); + } + + } +} \ No newline at end of file diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ProfileTimeSeries.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ProfileTimeSeries.java index 1429ce765..703902162 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ProfileTimeSeries.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ProfileTimeSeries.java @@ -21,7 +21,7 @@ public final class ProfileTimeSeries { private final String timeZone; private final List values; - protected ProfileTimeSeries(Builder builder) + ProfileTimeSeries(Builder builder) { parameter = builder.parameter; unit = builder.unit; diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfile.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfile.java index 831b4e097..55a7140ea 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfile.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfile.java @@ -10,6 +10,7 @@ import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; import cwms.cda.api.errors.FieldException; import cwms.cda.data.dto.CwmsDTOBase; +import cwms.cda.data.dto.CwmsDTOValidator; import cwms.cda.data.dto.CwmsId; import cwms.cda.formatters.Formats; import cwms.cda.formatters.annotations.FormattableWith; @@ -20,7 +21,7 @@ @JsonDeserialize(builder = TimeSeriesProfile.Builder.class) @JsonInclude(JsonInclude.Include.NON_NULL) @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) -public final class TimeSeriesProfile implements CwmsDTOBase { +public final class TimeSeriesProfile extends CwmsDTOBase { @Schema(description = "Location ID") private final CwmsId locationId; @Schema(description = "Description") @@ -61,7 +62,9 @@ public CwmsId getReferenceTsId() { } @Override - public void validate() throws FieldException { + protected void validateInternal(CwmsDTOValidator validator){ + super.validateInternal(validator); + if (this.parameterList.isEmpty()) { throw new FieldException("Parameter list field must not be empty"); } diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstance.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstance.java index cfa480fd9..790da2801 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstance.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstance.java @@ -5,9 +5,9 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonNaming; import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; -import cwms.cda.api.errors.FieldException; import cwms.cda.api.errors.RequiredFieldException; import cwms.cda.data.dto.CwmsDTOBase; +import cwms.cda.data.dto.CwmsDTOValidator; import cwms.cda.formatters.Formats; import cwms.cda.formatters.annotations.FormattableWith; import cwms.cda.formatters.json.JsonV2; @@ -19,7 +19,7 @@ @JsonDeserialize(builder = TimeSeriesProfileInstance.Builder.class) @JsonInclude(JsonInclude.Include.NON_NULL) @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) -public final class TimeSeriesProfileInstance implements CwmsDTOBase { +public final class TimeSeriesProfileInstance extends CwmsDTOBase { private final TimeSeriesProfile timeSeriesProfile; private final List timeSeriesList; private final String version; @@ -62,7 +62,7 @@ public Instant getLastDate() return lastDate; } @Override - public void validate() throws FieldException { + protected void validateInternal(CwmsDTOValidator validator){ if(timeSeriesProfile==null) { throw new RequiredFieldException("timeSeriesProfile"); diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParser.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParser.java index 54030d346..06a0ff830 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParser.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParser.java @@ -1,86 +1,44 @@ package cwms.cda.data.dto.timeseriesprofile; -import java.math.BigInteger; import java.util.List; - -import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.databind.PropertyNamingStrategies; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonNaming; import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; -import cwms.cda.api.errors.FieldException; import cwms.cda.data.dto.CwmsDTOBase; +import cwms.cda.data.dto.CwmsDTOValidator; import cwms.cda.data.dto.CwmsId; -import cwms.cda.formatters.Formats; -import cwms.cda.formatters.annotations.FormattableWith; -import cwms.cda.formatters.json.JsonV2; - -@FormattableWith(contentType = Formats.JSONV2, formatter = JsonV2.class) -@JsonDeserialize(builder = TimeSeriesProfileParser.Builder.class) -@JsonInclude(JsonInclude.Include.NON_NULL) -@JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) -public final class TimeSeriesProfileParser implements CwmsDTOBase { + +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") +@JsonSubTypes({@JsonSubTypes.Type(value = TimeSeriesProfileParserIndexed.class), + @JsonSubTypes.Type(value = TimeSeriesProfileParserColumnar.class) +}) + +public class TimeSeriesProfileParser extends CwmsDTOBase { private final CwmsId locationId; private final String keyParameter; private final char recordDelimiter; - private final Character fieldDelimiter; private final String timeFormat; private final String timeZone; - private final Integer timeField; private final List parameterInfoList; private final boolean timeInTwoFields; - private final Integer timeStartColumn; - private final Integer timeEndColumn; - private TimeSeriesProfileParser(Builder builder) { + TimeSeriesProfileParser(Builder builder) { locationId = builder.locationId; keyParameter = builder.keyParameter; recordDelimiter = builder.recordDelimiter; - fieldDelimiter = builder.fieldDelimiter; timeFormat = builder.timeFormat; timeZone = builder.timeZone; - timeField = builder.timeField; parameterInfoList = builder.parameterInfoList; timeInTwoFields = builder.timeInTwoFields; - timeStartColumn = builder.timeStartColumn; - timeEndColumn = builder.timeEndColumn; } @Override - public void validate() throws FieldException { + protected void validateInternal(CwmsDTOValidator validator) { // there must be a key parameter - if (this.keyParameter == null) { - throw new FieldException("Key Parameter field can't be null"); - } - // if there is a field delimiter, and it is part of the time format, time in two fields must be true - // if we have a field delimiter and it is not contained in the timeformat, then timeInTwoField must be false - if(fieldDelimiter!=null && (-1==timeFormat.indexOf(fieldDelimiter) && timeInTwoFields)) - { - throw new FieldException("Field delimiter '"+fieldDelimiter+"' is not part of time format " - +timeFormat+". timeInTwoFields must be false."); - } - // if there is no field delimiter, time start column and time end column must be defined - if(fieldDelimiter==null && (timeStartColumn==null || timeEndColumn ==null)) - { - throw new FieldException("If Field delimiter is undefined, then timeStartColumn and timeEndColumn must be defined."); - } - // if there is no field delimiter, parameter info must provide a start and end column - if(fieldDelimiter==null) - { - for(ParameterInfo parameterInfo : parameterInfoList) - { - if(parameterInfo.getStartColumn()==null || parameterInfo.getEndColumn()==null) - { - throw new FieldException("If Field delimiter is undefined, then startColumn and endColumn must be defined for ParameterInfo."); - } - } - } - // if time field is undefined, it is columnar format and time start column and time end column must be defined - if(timeStartColumn!=null&&timeEndColumn!=null&&timeField!=null) - { - throw new FieldException("If time field is defined, then startColumn and endColumn must be undefined."); - } - } + validator.required(getKeyParameter(),"keyParameter"); + } public CwmsId getLocationId() { @@ -95,11 +53,7 @@ public char getRecordDelimiter() { return recordDelimiter; } - public Character getFieldDelimiter() { - return fieldDelimiter; - } - - public List getParameterInfoList() { + public List getParameterInfoList() { return parameterInfoList; } @@ -111,58 +65,28 @@ public String getTimeZone() { return timeZone; } - public BigInteger getTimeField() { - return timeField==null ? null : BigInteger.valueOf(timeField); - } - public boolean getTimeInTwoFields() { return timeInTwoFields; } - public BigInteger getTimeStartColumn() { - if (timeStartColumn != null) { - return BigInteger.valueOf(timeStartColumn); - } - return null; - } - public BigInteger getTimeEndColumn(){ - if (timeEndColumn != null) { - return BigInteger.valueOf(timeEndColumn); - } - return null; - } @JsonPOJOBuilder @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) - public static final class Builder { + public static class Builder { private List parameterInfoList; private String keyParameter; private char recordDelimiter; - private Character fieldDelimiter = null; private String timeFormat; private String timeZone; - private Integer timeField = null; private boolean timeInTwoFields; private CwmsId locationId; - private Integer timeStartColumn = null; - private Integer timeEndColumn = null; public TimeSeriesProfileParser.Builder withLocationId(CwmsId locationId) { this.locationId = locationId; return this; } - public TimeSeriesProfileParser.Builder withTimeStartColumn(int timeStartColumn) - { - this.timeStartColumn = timeStartColumn; - return this; - } - public TimeSeriesProfileParser.Builder withTimeEndColumn(int timeEndColumn) - { - this.timeEndColumn = timeEndColumn; - return this; - } - public TimeSeriesProfileParser.Builder withKeyParameter(String keyParameter) { + public TimeSeriesProfileParser.Builder withKeyParameter(String keyParameter) { this.keyParameter = keyParameter; return this; } @@ -172,10 +96,6 @@ public TimeSeriesProfileParser.Builder withRecordDelimiter(char delimiter) { return this; } - public TimeSeriesProfileParser.Builder withFieldDelimiter(char delimiter) { - this.fieldDelimiter = delimiter; - return this; - } public TimeSeriesProfileParser.Builder withTimeFormat(String timeFormat) { this.timeFormat = timeFormat; @@ -187,10 +107,6 @@ public TimeSeriesProfileParser.Builder withTimeZone(String timeZone) { return this; } - public TimeSeriesProfileParser.Builder withTimeField(int field) { - this.timeField = field; - return this; - } public TimeSeriesProfileParser.Builder withTimeInTwoFields(boolean timeInTwoFields) { this.timeInTwoFields = timeInTwoFields; diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserColumnar.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserColumnar.java new file mode 100644 index 000000000..75a8eef4a --- /dev/null +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserColumnar.java @@ -0,0 +1,70 @@ +package cwms.cda.data.dto.timeseriesprofile; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.PropertyNamingStrategies; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; +import cwms.cda.data.dto.CwmsDTOValidator; +import cwms.cda.formatters.Formats; +import cwms.cda.formatters.annotations.FormattableWith; +import cwms.cda.formatters.json.JsonV2; + +import java.math.BigInteger; + +@FormattableWith(contentType = Formats.JSONV2, formatter = JsonV2.class) +@JsonDeserialize(builder = TimeSeriesProfileParserColumnar.Builder.class) +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) +public final class TimeSeriesProfileParserColumnar extends TimeSeriesProfileParser { + private final Integer timeStartColumn; + private final Integer timeEndColumn; + + TimeSeriesProfileParserColumnar(Builder builder) { + super(builder); + timeStartColumn = builder.timeStartColumn; + timeEndColumn = builder.timeEndColumn; + } + + @Override + protected void validateInternal(CwmsDTOValidator validator) { + validator.required(getTimeStartColumn(),"timeStartColumn"); + validator.required(getTimeEndColumn(),"timeEndColumn"); + } + + public BigInteger getTimeStartColumn() { + if (timeStartColumn != null) { + return BigInteger.valueOf(timeStartColumn); + } + return null; + } + public BigInteger getTimeEndColumn(){ + if (timeEndColumn != null) { + return BigInteger.valueOf(timeEndColumn); + } + return null; + } + + @JsonPOJOBuilder + @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) + public static final class Builder extends TimeSeriesProfileParser.Builder{ + private Integer timeStartColumn = null; + private Integer timeEndColumn = null; + + public TimeSeriesProfileParserColumnar.Builder withTimeStartColumn(int timeStartColumn) + { + this.timeStartColumn = timeStartColumn; + return this; + } + public TimeSeriesProfileParserColumnar.Builder withTimeEndColumn(int timeEndColumn) + { + this.timeEndColumn = timeEndColumn; + return this; + } + @Override + public TimeSeriesProfileParserColumnar build() { + return new TimeSeriesProfileParserColumnar(this); + } + } + +} diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserIndexed.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserIndexed.java new file mode 100644 index 000000000..82a008491 --- /dev/null +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserIndexed.java @@ -0,0 +1,68 @@ +package cwms.cda.data.dto.timeseriesprofile; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.PropertyNamingStrategies; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; +import cwms.cda.data.dto.CwmsDTOValidator; +import cwms.cda.formatters.Formats; +import cwms.cda.formatters.annotations.FormattableWith; +import cwms.cda.formatters.json.JsonV2; + +import java.math.BigInteger; + +@FormattableWith(contentType = Formats.JSONV2, formatter = JsonV2.class) +@JsonDeserialize(builder = TimeSeriesProfileParserIndexed.Builder.class) +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) +public class TimeSeriesProfileParserIndexed extends TimeSeriesProfileParser { + private final Character fieldDelimiter; + private final Integer timeField; + + TimeSeriesProfileParserIndexed(Builder builder) { + super(builder); + fieldDelimiter = builder.fieldDelimiter; + timeField = builder.timeField; + } + + @Override + protected void validateInternal(CwmsDTOValidator validator) { + validator.required(getFieldDelimiter(),"fieldDelimiter"); + validator.required(getTimeField(),"timeField"); + } + + + public Character getFieldDelimiter() { + return fieldDelimiter; + } + + + public BigInteger getTimeField() { + return timeField==null ? null : BigInteger.valueOf(timeField); + } + + @JsonPOJOBuilder + @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) + public static class Builder extends TimeSeriesProfileParser.Builder{ + private Character fieldDelimiter = null; + private Integer timeField = null; + + + public TimeSeriesProfileParserIndexed.Builder withFieldDelimiter(char delimiter) { + this.fieldDelimiter = delimiter; + return this; + } + + + public TimeSeriesProfileParserIndexed.Builder withTimeField(int field) { + this.timeField = field; + return this; + } + @Override + public TimeSeriesProfileParserIndexed build() { + return new TimeSeriesProfileParserIndexed(this); + } + } + +} diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDaoIT.java b/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDaoIT.java index 00eb79b74..c4bbf1645 100644 --- a/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDaoIT.java +++ b/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDaoIT.java @@ -4,10 +4,13 @@ import cwms.cda.data.dao.StoreRule; import cwms.cda.data.dto.CwmsId; import cwms.cda.data.dto.timeseriesprofile.ParameterInfo; +import cwms.cda.data.dto.timeseriesprofile.ParameterInfoColumnar; +import cwms.cda.data.dto.timeseriesprofile.ParameterInfoIndexed; import cwms.cda.data.dto.timeseriesprofile.ProfileTimeSeries; import cwms.cda.data.dto.timeseriesprofile.TimeSeriesProfile; import cwms.cda.data.dto.timeseriesprofile.TimeSeriesProfileInstance; -import cwms.cda.data.dto.timeseriesprofile.TimeSeriesProfileParser; +import cwms.cda.data.dto.timeseriesprofile.TimeSeriesProfileParserColumnar; +import cwms.cda.data.dto.timeseriesprofile.TimeSeriesProfileParserIndexed; import cwms.cda.data.dto.timeseriesprofile.TimeValuePair; import fixtures.CwmsDataApiSetupCallback; import mil.army.usace.hec.test.database.CwmsDatabaseContainer; @@ -74,7 +77,7 @@ void testStoreTimeSeriesProfileInstanceWithDataBlock() throws SQLException { profileDao.storeTimeSeriesProfile(timeSeriesProfile, false); // store a time series parser - TimeSeriesProfileParser parser = buildTestTimeSeriesProfileParser(officeId, locationName, parameterArray, parameterIndexArray, parameterUnitArray, recordDelimiter, fieldDelimiter, + TimeSeriesProfileParserIndexed parser = buildTestTimeSeriesProfileParserIndexed(officeId, locationName, parameterArray, parameterIndexArray, parameterUnitArray, recordDelimiter, fieldDelimiter, timeFormat, timeZone, timeField); TimeSeriesProfileParserDao timeSeriesProfileParserDao = new TimeSeriesProfileParserDao(context); @@ -141,7 +144,7 @@ void testStoreTimeSeriesProfileInstanceWithDataBlockColumnar() throws SQLExcepti profileDao.storeTimeSeriesProfile(timeSeriesProfile, false); // store a time series parser - TimeSeriesProfileParser parser = buildTestTimeSeriesProfileParser(officeId, locationName, parameterArray, parameterStartEndArray, parameterUnitArray, recordDelimiter, + TimeSeriesProfileParserColumnar parser = buildTestTimeSeriesProfileParserColumnar(officeId, locationName, parameterArray, parameterStartEndArray, parameterUnitArray, recordDelimiter, timeFormat, timeZone, timeStartEnd); TimeSeriesProfileParserDao timeSeriesProfileParserDao = new TimeSeriesProfileParserDao(context); timeSeriesProfileParserDao.storeTimeSeriesProfileParser(parser, false); @@ -309,12 +312,11 @@ void testDeleteTimeSeriesProfileInstance() throws SQLException { firstDate, timeZone, overrideProtection, versionDate); // check if instance was deleted - timeSeriesProfileInstance = null; try { timeSeriesProfileInstance = retrieveTimeSeriesProfileInstance(officeId, locationName, keyParameter[0], version, unit, startTime, endTime, timeZone, startInclusive, endInclusive, previous, next, versionDate, maxVersion); } catch (SQLException e) { - e.printStackTrace(); + throw(new RuntimeException(e)); } // instance does not exist anymore assertNull(timeSeriesProfileInstance); @@ -369,7 +371,7 @@ void testStoreTimeSeriesProfileInstance() throws SQLException { profileDao.storeTimeSeriesProfile(timeSeriesProfile, false); // store a parser - TimeSeriesProfileParser parser = buildTestTimeSeriesProfileParser(officeId, locationName, parameterArray, parameterIndexArray, parameterUnitArray, recordDelimiter, fieldDelimiter, + TimeSeriesProfileParserIndexed parser = buildTestTimeSeriesProfileParserIndexed(officeId, locationName, parameterArray, parameterIndexArray, parameterUnitArray, recordDelimiter, fieldDelimiter, timeFormat, timeZone, timeField); TimeSeriesProfileParserDao timeSeriesProfileParserDao = new TimeSeriesProfileParserDao(context); timeSeriesProfileParserDao.storeTimeSeriesProfileParser(parser, false); @@ -381,8 +383,7 @@ void testStoreTimeSeriesProfileInstance() throws SQLException { dateTimeArray, valueArray, timeZone, versionDate); // test storeTImeSeriesProfileInstance method timeSeriesProfileInstanceDao.storeTimeSeriesProfileInstance(timeseriesProfileInstance, versionId, versionDate, storeRule, null); - timeSeriesProfileInstance = null; - // check is the timeseries profile instance can be retrieved + // check is the timeseries profile instance can be retrieved try { timeSeriesProfileInstance = retrieveTimeSeriesProfileInstance(officeId, locationName, keyParameter[0], versionId, unit, startTime, endTime, timeZone, startInclusive, endInclusive, previous, next, versionDate, maxVersion); @@ -500,55 +501,56 @@ static private TimeSeriesProfile buildTestTimeSeriesProfile(String officeId, Str .build(); } - private TimeSeriesProfileParser buildTestTimeSeriesProfileParser(String officeId, String location, String[] parameterArray, int[][] parameterStartEndArray, String[] parameterUnitArray, char recordDelimiter, String timeFormat, String timeZone, int[] timeStartEnd) { + private TimeSeriesProfileParserColumnar buildTestTimeSeriesProfileParserColumnar(String officeId, String location, String[] parameterArray, int[][] parameterStartEndArray, String[] parameterUnitArray, char recordDelimiter, String timeFormat, String timeZone, int[] timeStartEnd) { List parameterInfoList = new ArrayList<>(); for (int i = 0; i < parameterArray.length; i++) { - parameterInfoList.add(new ParameterInfo.Builder() - .withParameter(parameterArray[i]) + parameterInfoList.add(new ParameterInfoColumnar.Builder() .withStartColumn(parameterStartEndArray[i][0]) .withEndColumn(parameterStartEndArray[i][1]) .withUnit(parameterUnitArray[i]) + .withParameter(parameterArray[i]) .build()); } CwmsId locationId = new CwmsId.Builder().withOfficeId(officeId).withName(location).build(); - return + return (TimeSeriesProfileParserColumnar) - new TimeSeriesProfileParser.Builder() + new TimeSeriesProfileParserColumnar.Builder() + .withTimeStartColumn(timeStartEnd[0]) + .withTimeEndColumn(timeStartEnd[1]) .withLocationId(locationId) .withKeyParameter(parameterArray[0]) .withRecordDelimiter(recordDelimiter) .withTimeFormat(timeFormat) .withTimeZone(timeZone) - .withTimeStartColumn(timeStartEnd[0]) - .withTimeEndColumn(timeStartEnd[1]) + .withTimeInTwoFields(false) .withParameterInfoList(parameterInfoList) .build(); } - static private TimeSeriesProfileParser buildTestTimeSeriesProfileParser(String officeId, String location, String[] parameterArray, int[] parameterIndexArray, String[] parameterUnitArray, + static private TimeSeriesProfileParserIndexed buildTestTimeSeriesProfileParserIndexed(String officeId, String location, String[] parameterArray, int[] parameterIndexArray, String[] parameterUnitArray, char recordDelimiter, char fieldDelimiter, String timeFormat, String timeZone, int timeField) { List parameterInfoList = new ArrayList<>(); for (int i = 0; i < parameterArray.length; i++) { - parameterInfoList.add(new ParameterInfo.Builder() - .withParameter(parameterArray[i]) + parameterInfoList.add(new ParameterInfoIndexed.Builder() .withIndex(parameterIndexArray[i]) + .withParameter(parameterArray[i]) .withUnit(parameterUnitArray[i]) .build()); } CwmsId locationId = new CwmsId.Builder().withOfficeId(officeId).withName(location).build(); - return + return (TimeSeriesProfileParserIndexed) - new TimeSeriesProfileParser.Builder() + new TimeSeriesProfileParserIndexed.Builder() + .withFieldDelimiter(fieldDelimiter) + .withTimeField(timeField) .withLocationId(locationId) .withKeyParameter(parameterArray[0]) .withRecordDelimiter(recordDelimiter) - .withFieldDelimiter(fieldDelimiter) .withTimeFormat(timeFormat) .withTimeZone(timeZone) - .withTimeField(timeField) .withTimeInTwoFields(true) .withParameterInfoList(parameterInfoList) .build(); diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDaoIT.java b/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDaoIT.java index 4052620fd..f8dcd0e5f 100644 --- a/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDaoIT.java +++ b/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDaoIT.java @@ -8,8 +8,10 @@ import cwms.cda.api.DataApiTestIT; import cwms.cda.data.dto.CwmsId; import cwms.cda.data.dto.timeseriesprofile.ParameterInfo; +import cwms.cda.data.dto.timeseriesprofile.ParameterInfoIndexed; import cwms.cda.data.dto.timeseriesprofile.TimeSeriesProfile; import cwms.cda.data.dto.timeseriesprofile.TimeSeriesProfileParser; +import cwms.cda.data.dto.timeseriesprofile.TimeSeriesProfileParserIndexed; import fixtures.CwmsDataApiSetupCallback; import mil.army.usace.hec.test.database.CwmsDatabaseContainer; import org.jooq.DSLContext; @@ -43,7 +45,7 @@ void testStoreAndRetrieve() throws Exception { timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfile, false); TimeSeriesProfileParserDao timeSeriesProfileParserDao = new TimeSeriesProfileParserDao(context); - TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser(officeId, locationName, parameter[0]); + TimeSeriesProfileParserIndexed timeSeriesProfileParser = buildTestTimeSeriesProfileParserIndexed(officeId, locationName, parameter[0]); timeSeriesProfileParserDao.storeTimeSeriesProfileParser(timeSeriesProfileParser, false); TimeSeriesProfileParser retrieved = timeSeriesProfileParserDao.retrieveTimeSeriesProfileParser(timeSeriesProfileParser.getLocationId().getName(), @@ -76,8 +78,8 @@ void testStoreAndDelete() throws SQLException { timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfile, false); TimeSeriesProfileParserDao timeSeriesProfileParserDao = new TimeSeriesProfileParserDao(context); - TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser(officeId, locationName, parameter[0]); - timeSeriesProfileParserDao.storeTimeSeriesProfileParser(timeSeriesProfileParser, false); + TimeSeriesProfileParserIndexed timeSeriesProfileParser = buildTestTimeSeriesProfileParserIndexed(officeId, locationName, parameter[0]); + timeSeriesProfileParserDao.storeTimeSeriesProfileParser( timeSeriesProfileParser, false); timeSeriesProfileParserDao.deleteTimeSeriesProfileParser(timeSeriesProfileParser.getLocationId().getName(), timeSeriesProfileParser.getKeyParameter(), timeSeriesProfileParser.getLocationId().getOfficeId()); @@ -112,7 +114,7 @@ void testStoreAndRetrieveMultiple() throws SQLException { for(String parameter : parameters) { - TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser(officeId, locationName, parameter); + TimeSeriesProfileParserIndexed timeSeriesProfileParser = buildTestTimeSeriesProfileParserIndexed(officeId, locationName, parameter); timeSeriesProfileParserDao.storeTimeSeriesProfileParser(timeSeriesProfileParser, false); } @@ -149,8 +151,8 @@ void testStoreAndCopy() throws SQLException { timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfile, false); TimeSeriesProfileParserDao timeSeriesProfileParserDao = new TimeSeriesProfileParserDao(context); - TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser(officeId, locationName, parameter[0]); - timeSeriesProfileParserDao.storeTimeSeriesProfileParser(timeSeriesProfileParser, false); + TimeSeriesProfileParserIndexed timeSeriesProfileParser = buildTestTimeSeriesProfileParserIndexed(officeId, locationName, parameter[0]); + timeSeriesProfileParserDao.storeTimeSeriesProfileParser( timeSeriesProfileParser, false); TimeSeriesProfileParser retrieved = timeSeriesProfileParserDao.retrieveTimeSeriesProfileParser(timeSeriesProfileParser.getLocationId().getName(), timeSeriesProfileParser.getKeyParameter(), timeSeriesProfileParser.getLocationId().getOfficeId()); @@ -177,30 +179,30 @@ private static TimeSeriesProfile buildTestTimeSeriesProfile(String officeId, Str } - static private TimeSeriesProfileParser buildTestTimeSeriesProfileParser(String officeId, String location, String keyParameter) { + static private TimeSeriesProfileParserIndexed buildTestTimeSeriesProfileParserIndexed(String officeId, String location, String keyParameter) { List parameterInfoList = new ArrayList<>(); - parameterInfoList.add(new ParameterInfo.Builder() - .withParameter("Depth") + parameterInfoList.add(new ParameterInfoIndexed.Builder() .withIndex(6) + .withParameter("Depth") .withUnit("m") .build()); - parameterInfoList.add(new ParameterInfo.Builder() - .withParameter("Pres") + parameterInfoList.add(new ParameterInfoIndexed.Builder() .withIndex(5) + .withParameter("Pres") .withUnit("bar") .build()); CwmsId locationId = new CwmsId.Builder().withOfficeId(officeId).withName(location).build(); return - - new TimeSeriesProfileParser.Builder() + (TimeSeriesProfileParserIndexed) + new TimeSeriesProfileParserIndexed.Builder() + .withFieldDelimiter(',') + .withTimeField(1) .withLocationId(locationId) .withKeyParameter(keyParameter) .withRecordDelimiter((char) 10) - .withFieldDelimiter(',') - .withTimeFormat("MM/DD/YYYY,HH24:MI:SS") + .withTimeFormat("MM/DD/YYYY,HH24:MI:SS") .withTimeZone("UTC") - .withTimeField(1) - .withTimeInTwoFields(true) + .withTimeInTwoFields(true) .withParameterInfoList(parameterInfoList) .build(); } diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstanceTest.java b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstanceTest.java index 87e1ddd25..9231af8cd 100644 --- a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstanceTest.java +++ b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstanceTest.java @@ -20,7 +20,7 @@ public class TimeSeriesProfileInstanceTest { private static final Map PARAMETER_UNIT_MAP = new HashMap<>(); @BeforeAll - public static void setup() throws Exception { + public static void setup() { PARAMETER_UNIT_MAP.put("Depth", "ft"); PARAMETER_UNIT_MAP.put("Temp-Water", "F"); } diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserTest.java b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserTest.java index 104cf51dc..a052ce40a 100644 --- a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserTest.java +++ b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserTest.java @@ -16,96 +16,98 @@ final class TimeSeriesProfileParserTest { @Test - void testTimeSeriesProfileSerializationRoundTrip() { - TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser(); - ContentType contentType = Formats.parseHeader(Formats.JSONV2, TimeSeriesProfileParser.class); + void testTimeSeriesProfileColumnarSerializationRoundTrip() { + TimeSeriesProfileParserColumnar timeSeriesProfileParser = buildTestTimeSeriesProfileParserColumnar(); + ContentType contentType = Formats.parseHeader(Formats.JSONV2, TimeSeriesProfileParserColumnar.class); String serialized = Formats.format(contentType, timeSeriesProfileParser); - TimeSeriesProfileParser deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2, TimeSeriesProfileParser.class), serialized, TimeSeriesProfileParser.class); - testAssertEquals(timeSeriesProfileParser, deserialized, "Roundtrip serialization failed"); + TimeSeriesProfileParserColumnar deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2, TimeSeriesProfileParserColumnar.class), serialized, TimeSeriesProfileParserColumnar.class); + testAssertEquals(timeSeriesProfileParser, deserialized, "Roundtrip serialization failed"); } + @Test - void testTimeSeriesProfileColumnarSerializationRoundTrip() { - TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParserColumnar(); - ContentType contentType = Formats.parseHeader(Formats.JSONV2, TimeSeriesProfileParser.class); + void testTimeSeriesProfileIndexedSerializationRoundTrip() { + TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParserIndexed(); + ContentType contentType = Formats.parseHeader(Formats.JSONV2, TimeSeriesProfileParserColumnar.class); String serialized = Formats.format(contentType, timeSeriesProfileParser); - TimeSeriesProfileParser deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2, TimeSeriesProfileParser.class), serialized, TimeSeriesProfileParser.class); - testAssertEquals(timeSeriesProfileParser, deserialized, "Roundtrip serialization failed"); + TimeSeriesProfileParserIndexed deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2, TimeSeriesProfileParserIndexed.class), serialized, TimeSeriesProfileParserIndexed.class); + testAssertEquals((TimeSeriesProfileParserIndexed)timeSeriesProfileParser, deserialized, "Roundtrip serialization failed"); } @Test - void testTimeSeriesProfileSerializationRoundTripFromFile() throws Exception { - TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParser(); - InputStream resource = this.getClass().getResourceAsStream("/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileparser.json"); + void testTimeSeriesProfileSerializationRoundTripColumnarFromFile() throws Exception { + TimeSeriesProfileParserColumnar timeSeriesProfileParser = buildTestTimeSeriesProfileParserColumnar(); + InputStream resource = this.getClass().getResourceAsStream("/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileparsercolumnar.json"); assertNotNull(resource); String serialized = IOUtils.toString(resource, StandardCharsets.UTF_8); - TimeSeriesProfileParser deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2, TimeSeriesProfileParser.class), serialized, TimeSeriesProfileParser.class); - testAssertEquals(timeSeriesProfileParser, deserialized, "Roundtrip serialization from file failed"); + TimeSeriesProfileParserColumnar deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2, TimeSeriesProfileParserColumnar.class), serialized, TimeSeriesProfileParserColumnar.class); + testAssertEquals(timeSeriesProfileParser, deserialized, "Roundtrip serialization from file failed"); } + @Test - void testTimeSeriesProfileSerializationRoundTripColumnarFromFile() throws Exception { - TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParserColumnar(); - InputStream resource = this.getClass().getResourceAsStream("/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileparsercolumnar.json"); + void testTimeSeriesProfileSerializationRoundTripIndexedFromFile() throws Exception { + TimeSeriesProfileParser timeSeriesProfileParser = buildTestTimeSeriesProfileParserIndexed(); + InputStream resource = this.getClass().getResourceAsStream("/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileparserindexed.json"); assertNotNull(resource); String serialized = IOUtils.toString(resource, StandardCharsets.UTF_8); - TimeSeriesProfileParser deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2, TimeSeriesProfileParser.class), serialized, TimeSeriesProfileParser.class); - testAssertEquals(timeSeriesProfileParser, deserialized, "Roundtrip serialization from file failed"); + TimeSeriesProfileParserIndexed deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2, TimeSeriesProfileParserIndexed.class), serialized, TimeSeriesProfileParserIndexed.class); + testAssertEquals((TimeSeriesProfileParserIndexed) timeSeriesProfileParser, deserialized, "Roundtrip serialization from file failed"); } - private static TimeSeriesProfileParser buildTestTimeSeriesProfileParser() { + private static TimeSeriesProfileParserColumnar buildTestTimeSeriesProfileParserColumnar() { List parameterInfo = new ArrayList<>(); - parameterInfo.add(new ParameterInfo.Builder() + parameterInfo.add(new ParameterInfoColumnar.Builder() + .withStartColumn(11) + .withEndColumn(20) .withParameter("Depth") - .withIndex(3) .withUnit("m") - .build()); - parameterInfo.add(new ParameterInfo.Builder() + .build()); + parameterInfo.add(new ParameterInfoColumnar.Builder() + .withStartColumn(21) + .withEndColumn(30) .withParameter("Temp-Water") - .withIndex(5) .withUnit("F") - .build()); + .build()); CwmsId locationId = new CwmsId.Builder() .withOfficeId("SWT") .withName("location") .build(); - return - new TimeSeriesProfileParser.Builder() + return (TimeSeriesProfileParserColumnar) + new TimeSeriesProfileParserColumnar.Builder() + .withTimeStartColumn(1) + .withTimeEndColumn(10) .withLocationId(locationId) .withKeyParameter("Depth") .withRecordDelimiter((char) 10) - .withFieldDelimiter(',') .withTimeFormat("MM/DD/YYYY,HH24:MI:SS") .withTimeZone("UTC") - .withTimeField(1) .withTimeInTwoFields(false) .withParameterInfoList(parameterInfo) .build(); } - private static TimeSeriesProfileParser buildTestTimeSeriesProfileParserColumnar() { + private static TimeSeriesProfileParser buildTestTimeSeriesProfileParserIndexed() { List parameterInfo = new ArrayList<>(); - parameterInfo.add(new ParameterInfo.Builder() + parameterInfo.add(new ParameterInfoIndexed.Builder() + .withIndex(3) .withParameter("Depth") .withUnit("m") - .withStartColumn(11) - .withEndColumn(20) .build()); - parameterInfo.add(new ParameterInfo.Builder() + parameterInfo.add(new ParameterInfoIndexed.Builder() + .withIndex(5) .withParameter("Temp-Water") .withUnit("F") - .withStartColumn(21) - .withEndColumn(30) .build()); CwmsId locationId = new CwmsId.Builder() .withOfficeId("SWT") .withName("location") .build(); return - new TimeSeriesProfileParser.Builder() + new TimeSeriesProfileParserIndexed.Builder() + .withTimeField(1) + .withFieldDelimiter(',') .withLocationId(locationId) .withKeyParameter("Depth") .withRecordDelimiter((char) 10) - .withTimeStartColumn(1) - .withTimeEndColumn(10) .withTimeFormat("MM/DD/YYYY,HH24:MI:SS") .withTimeZone("UTC") .withTimeInTwoFields(false) @@ -113,14 +115,12 @@ private static TimeSeriesProfileParser buildTestTimeSeriesProfileParserColumnar( .build(); } - private void testAssertEquals(TimeSeriesProfileParser expected, TimeSeriesProfileParser actual, String message) { + private void testAssertEquals(TimeSeriesProfileParserColumnar expected, TimeSeriesProfileParserColumnar actual, String message) { assertEquals(expected.getLocationId().getName(), actual.getLocationId().getName(), message); assertEquals(expected.getLocationId().getOfficeId(), actual.getLocationId().getOfficeId(), message); - assertEquals(expected.getFieldDelimiter(), actual.getFieldDelimiter(), message); assertEquals(expected.getLocationId().getName(), actual.getLocationId().getName(), message); assertEquals(expected.getLocationId().getOfficeId(), actual.getLocationId().getOfficeId(), message); assertEquals(expected.getKeyParameter(), actual.getKeyParameter(), message); - assertEquals(expected.getTimeField(), actual.getTimeField(), message); assertEquals(expected.getTimeFormat(), actual.getTimeFormat(), message); testAssertEquals(expected.getParameterInfoList(), actual.getParameterInfoList(),message); assertEquals(expected.getRecordDelimiter(), actual.getRecordDelimiter(), message); @@ -129,16 +129,37 @@ private void testAssertEquals(TimeSeriesProfileParser expected, TimeSeriesProfil assertEquals(expected.getTimeEndColumn(), actual.getTimeEndColumn()); assertEquals(expected.getTimeStartColumn(), actual.getTimeStartColumn()); } - + private void testAssertEquals(TimeSeriesProfileParserIndexed expected, TimeSeriesProfileParserIndexed actual, String message) { + assertEquals(expected.getLocationId().getName(), actual.getLocationId().getName(), message); + assertEquals(expected.getLocationId().getOfficeId(), actual.getLocationId().getOfficeId(), message); + assertEquals(expected.getLocationId().getName(), actual.getLocationId().getName(), message); + assertEquals(expected.getLocationId().getOfficeId(), actual.getLocationId().getOfficeId(), message); + assertEquals(expected.getKeyParameter(), actual.getKeyParameter(), message); + assertEquals(expected.getTimeFormat(), actual.getTimeFormat(), message); + testAssertEquals(expected.getParameterInfoList(), actual.getParameterInfoList(),message); + assertEquals(expected.getRecordDelimiter(), actual.getRecordDelimiter(), message); + assertEquals(expected.getTimeZone(), actual.getTimeZone()); + assertEquals(expected.getTimeInTwoFields(), actual.getTimeInTwoFields()); + assertEquals(expected.getTimeField(), actual.getTimeField()); + assertEquals(expected.getFieldDelimiter(), actual.getFieldDelimiter()); + } private void testAssertEquals(List expected, List actual, String message) { assertEquals(expected.size(), actual.size()); for(int i=0;i Date: Wed, 31 Jul 2024 09:53:17 -0700 Subject: [PATCH 24/26] renamed the retrieve method for multiple DTOs to catalog... --- .../data/dao/timeseriesprofile/TimeSeriesProfileDao.java | 2 +- .../timeseriesprofile/TimeSeriesProfileInstanceDao.java | 2 +- .../dao/timeseriesprofile/TimeSeriesProfileParserDao.java | 2 +- .../dao/timeseriesprofile/TimeSeriesProfileDaoIT.java | 8 ++++---- .../timeseriesprofile/TimeSeriesProfileInstanceDaoIT.java | 2 +- .../timeseriesprofile/TimeSeriesProfileParserDaoIT.java | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileDao.java b/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileDao.java index 090987ecb..e379b194b 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileDao.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileDao.java @@ -61,7 +61,7 @@ public void copyTimeSeriesProfile(String locationId, String keyParameter, String officeId)); } - public List retrieveTimeSeriesProfiles(String locationIdMask, String parameterIdMask, String officeIdMask) { + public List catalogTimeSeriesProfiles(String locationIdMask, String parameterIdMask, String officeIdMask) { return connectionResult(dsl, conn -> { List timeSeriesProfileList = new ArrayList<>(); Result timeSeriesProfileResults = CWMS_TS_PROFILE_PACKAGE.call_CAT_TS_PROFILE( diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDao.java b/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDao.java index 29ddefaa1..7cbbaa98c 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDao.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDao.java @@ -145,7 +145,7 @@ void storeTimeSeriesProfileInstance(TimeSeriesProfileInstance timeseriesProfileI } ); } - List retrieveTimeSeriesProfileInstances( String officeIdMask, String locationMask, String parameterMask, String versionMask, + List catalogTimeSeriesProfileInstances( String officeIdMask, String locationMask, String parameterMask, String versionMask, Instant startTime, Instant endTime, String timeZone) { return connectionResult(dsl, conn -> { diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDao.java b/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDao.java index 5a995859b..6f4886501 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDao.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDao.java @@ -92,7 +92,7 @@ public TimeSeriesProfileParser retrieveTimeSeriesProfileParser(String locationId }); } - public List retrieveTimeSeriesProfileParsers(String locationIdMask, String parameterIdMask, String officeIdMask) + public List catalogTimeSeriesProfileParsers(String locationIdMask, String parameterIdMask, String officeIdMask) { return connectionResult(dsl, conn -> { Result tsProfileParserResult = CWMS_TS_PROFILE_PACKAGE.call_CAT_TS_PROFILE_PARSER(DSL.using(conn).configuration(), diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileDaoIT.java b/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileDaoIT.java index d89fe6257..83c21a868 100644 --- a/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileDaoIT.java +++ b/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileDaoIT.java @@ -80,13 +80,13 @@ void testRetrieveCatalog() throws Exception { List timeSeriesProfileListBefore = - timeSeriesProfileDao.retrieveTimeSeriesProfiles("*", "*", "*"); + timeSeriesProfileDao.catalogTimeSeriesProfiles("*", "*", "*"); for (TimeSeriesProfile timeSeriesProfile : timeSeriesProfileListBefore) { timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfile.getLocationId().getName(), timeSeriesProfile.getKeyParameter(), timeSeriesProfile.getLocationId().getOfficeId()); } - List timeSeriesProfileListAfter = timeSeriesProfileDao.retrieveTimeSeriesProfiles("*", "*", "*"); + List timeSeriesProfileListAfter = timeSeriesProfileDao.catalogTimeSeriesProfiles("*", "*", "*"); assertEquals(0, timeSeriesProfileListAfter.size()); assertEquals(2, timeSeriesProfileListBefore.size()); @@ -105,13 +105,13 @@ void testDeleteTimeSeriesProfile() throws Exception { timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfile, false); List timeSeriesProfileListBefore = - timeSeriesProfileDao.retrieveTimeSeriesProfiles("*", "*", "*"); + timeSeriesProfileDao.catalogTimeSeriesProfiles("*", "*", "*"); timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfile.getLocationId().getName(), timeSeriesProfile.getKeyParameter(), timeSeriesProfile.getLocationId().getOfficeId()); List timeSeriesProfileListAfter = - timeSeriesProfileDao.retrieveTimeSeriesProfiles("*", "*", "*"); + timeSeriesProfileDao.catalogTimeSeriesProfiles("*", "*", "*"); assertEquals(timeSeriesProfileListBefore.size() - 1, timeSeriesProfileListAfter.size()); diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDaoIT.java b/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDaoIT.java index c4bbf1645..4b6e68759 100644 --- a/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDaoIT.java +++ b/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDaoIT.java @@ -200,7 +200,7 @@ void testRetrieveTimeSeriesProfileInstances() throws SQLException { DSLContext context = getDslContext(c, databaseLink.getOfficeId()); TimeSeriesProfileInstanceDao timeSeriesProfileInstanceDao = new TimeSeriesProfileInstanceDao(context); // test retrieveTimeSeriesProfileInstances - List result = timeSeriesProfileInstanceDao.retrieveTimeSeriesProfileInstances(officeIdMask, locationMask, parameterMask, + List result = timeSeriesProfileInstanceDao.catalogTimeSeriesProfileInstances(officeIdMask, locationMask, parameterMask, versionMask, startDate, endDate, timeZone); // cleanup: delete the time series profile instances we created diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDaoIT.java b/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDaoIT.java index f8dcd0e5f..fe83ada8e 100644 --- a/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDaoIT.java +++ b/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDaoIT.java @@ -118,7 +118,7 @@ void testStoreAndRetrieveMultiple() throws SQLException { timeSeriesProfileParserDao.storeTimeSeriesProfileParser(timeSeriesProfileParser, false); } - List profileParserList = timeSeriesProfileParserDao.retrieveTimeSeriesProfileParsers("*", "*", "*"); + List profileParserList = timeSeriesProfileParserDao.catalogTimeSeriesProfileParsers("*", "*", "*"); for (TimeSeriesProfileParser profileParser : profileParserList) { timeSeriesProfileParserDao.deleteTimeSeriesProfileParser(profileParser.getLocationId().getName(), profileParser.getKeyParameter(), profileParser.getLocationId().getOfficeId()); } From 5e0714e0bb706b8fecfbc52b1674d462366f9bd1 Mon Sep 17 00:00:00 2001 From: Andreas Christmann Date: Mon, 5 Aug 2024 15:01:53 -0700 Subject: [PATCH 25/26] DTO changes from Peter's review --- .../TimeSeriesProfileParserDao.java | 4 +- .../dto/timeseriesprofile/ParameterInfo.java | 6 +- .../ParameterInfoColumnar.java | 9 ++- .../ParameterInfoIndexed.java | 35 ++++---- .../timeseriesprofile/TimeSeriesProfile.java | 19 +---- .../TimeSeriesProfileParser.java | 4 +- .../TimeSeriesProfileParserIndexed.java | 2 +- .../dto/timeseriesprofile/TimeValuePair.java | 20 ++++- .../timeseriesprofile/ParameterInfoTest.java | 81 +++++++++++++++++++ .../TimeSeriesProfileInstanceTest.java | 4 + .../TimeSeriesProfileTest.java | 1 + .../timeseriesprofile/TimeValuePairTest.java | 48 +++++++++++ .../parameterinfocolumnar.json | 7 ++ .../parameterinfoindexed.json | 6 ++ .../timeseriesprofileinstance.json | 16 ++-- .../timeseriesprofileparsercolumnar.json | 6 +- .../timeseriesprofileparserindexed.json | 28 +++---- .../dto/timeseriesprofile/timevaluepair.json | 5 ++ 18 files changed, 238 insertions(+), 63 deletions(-) create mode 100644 cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfoTest.java create mode 100644 cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeValuePairTest.java create mode 100644 cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/parameterinfocolumnar.json create mode 100644 cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/parameterinfoindexed.json create mode 100644 cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timevaluepair.json diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDao.java b/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDao.java index 6f4886501..71d1772e2 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDao.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDao.java @@ -49,12 +49,12 @@ private String getParameterInfoString(TimeSeriesProfileParser timeSeriesProfileP List parameterInfo = timeSeriesProfileParser.getParameterInfoList(); StringBuilder parameterInfoBuilder = new StringBuilder(); - parameterInfoBuilder.append(parameterInfo.get(0).parameterInfoString()); + parameterInfoBuilder.append(parameterInfo.get(0).getParameterInfoString()); for(int i = 1; i < parameterInfo.size(); i++) { parameterInfoBuilder.append(timeSeriesProfileParser.getRecordDelimiter()) - .append(parameterInfo.get(i).parameterInfoString()); + .append(parameterInfo.get(i).getParameterInfoString()); } return parameterInfoBuilder.toString(); } diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfo.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfo.java index 13bbdff4c..2d62cf29d 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfo.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfo.java @@ -8,8 +8,8 @@ import cwms.cda.data.dto.CwmsDTOBase; @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") -@JsonSubTypes({@JsonSubTypes.Type(value = ParameterInfoIndexed.class), - @JsonSubTypes.Type(value = ParameterInfoColumnar.class) +@JsonSubTypes({@JsonSubTypes.Type(value = ParameterInfoIndexed.class, name = "indexed-parameter-info"), + @JsonSubTypes.Type(value = ParameterInfoColumnar.class, name = "columnar-parameter-info") }) public abstract class ParameterInfo extends CwmsDTOBase { @@ -20,7 +20,7 @@ public abstract class ParameterInfo extends CwmsDTOBase { parameter = builder.parameter; unit = builder.unit; } - public abstract String parameterInfoString(); + public abstract String getParameterInfoString(); public String getParameter() { return parameter; diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfoColumnar.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfoColumnar.java index 85a819c91..844b282f3 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfoColumnar.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfoColumnar.java @@ -1,13 +1,18 @@ package cwms.cda.data.dto.timeseriesprofile; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.PropertyNamingStrategies; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonNaming; import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; import cwms.cda.data.dto.CwmsDTOValidator; +import cwms.cda.formatters.Formats; +import cwms.cda.formatters.annotations.FormattableWith; +import cwms.cda.formatters.json.JsonV2; +@FormattableWith(contentType = Formats.JSONV2, formatter = JsonV2.class) @JsonDeserialize(builder = ParameterInfoColumnar.Builder.class) @JsonInclude(JsonInclude.Include.NON_NULL) @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) @@ -33,7 +38,9 @@ protected void validateInternal(CwmsDTOValidator validator) { validator.required(endColumn, "endColumn"); } - public String parameterInfoString() + @JsonIgnore + @Override + public String getParameterInfoString() { return getParameter() + "," + diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfoIndexed.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfoIndexed.java index f38e43e2a..5c72bd0d2 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfoIndexed.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfoIndexed.java @@ -1,13 +1,18 @@ package cwms.cda.data.dto.timeseriesprofile; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.PropertyNamingStrategies; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonNaming; import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; import cwms.cda.data.dto.CwmsDTOValidator; +import cwms.cda.formatters.Formats; +import cwms.cda.formatters.annotations.FormattableWith; +import cwms.cda.formatters.json.JsonV2; +@FormattableWith(contentType = Formats.JSONV2, formatter = JsonV2.class) @JsonDeserialize(builder = ParameterInfoIndexed.Builder.class) @JsonInclude(JsonInclude.Include.NON_NULL) @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) @@ -18,39 +23,39 @@ public final class ParameterInfoIndexed extends ParameterInfo { super(builder); index = builder.index; } + public Integer getIndex() { return index; } - @Override + @Override protected void validateInternal(CwmsDTOValidator validator) { - validator.required(getIndex(),"index"); + validator.required(getIndex(), "index"); } + @JsonIgnore @Override - public String parameterInfoString() - { - return getParameter() + - "," + - getUnit() + - "," + - getIndex() + - "," + - ","; - } - - + public String getParameterInfoString() { + return getParameter() + + "," + + getUnit() + + "," + + getIndex() + + "," + + ","; + } @JsonPOJOBuilder @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) - public static final class Builder extends ParameterInfo.Builder{ + public static final class Builder extends ParameterInfo.Builder { private Integer index; public ParameterInfoIndexed.Builder withIndex(int index) { this.index = index; return this; } + public ParameterInfo build() { return new ParameterInfoIndexed(this); } diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfile.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfile.java index 55a7140ea..5dd954d57 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfile.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfile.java @@ -8,7 +8,6 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonNaming; import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; -import cwms.cda.api.errors.FieldException; import cwms.cda.data.dto.CwmsDTOBase; import cwms.cda.data.dto.CwmsDTOValidator; import cwms.cda.data.dto.CwmsId; @@ -62,21 +61,11 @@ public CwmsId getReferenceTsId() { } @Override - protected void validateInternal(CwmsDTOValidator validator){ + protected void validateInternal(CwmsDTOValidator validator) { super.validateInternal(validator); - - if (this.parameterList.isEmpty()) { - throw new FieldException("Parameter list field must not be empty"); - } - if (this.keyParameter == null) { - throw new FieldException("Key Parameter field can't be null"); - } - if (this.locationId == null) { - throw new FieldException("Location Id field can't be null"); - } - if (!parameterList.contains(keyParameter)) { - throw new FieldException("Key Parameter must be part of Parameter list"); - } + validator.required(getParameterList(), "parameterList"); + validator.required(getKeyParameter(), "keyParameter"); + validator.required(getLocationId(), "locationId"); } @JsonPOJOBuilder diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParser.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParser.java index 06a0ff830..0e21bde83 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParser.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParser.java @@ -11,8 +11,8 @@ import cwms.cda.data.dto.CwmsId; @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") -@JsonSubTypes({@JsonSubTypes.Type(value = TimeSeriesProfileParserIndexed.class), - @JsonSubTypes.Type(value = TimeSeriesProfileParserColumnar.class) +@JsonSubTypes({@JsonSubTypes.Type(value = TimeSeriesProfileParserIndexed.class, name = "indexed-timeseries-profile-parser"), + @JsonSubTypes.Type(value = TimeSeriesProfileParserColumnar.class, name = "columnar-timeseries-profile-parser") }) public class TimeSeriesProfileParser extends CwmsDTOBase { diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserIndexed.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserIndexed.java index 82a008491..1d49f7b7c 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserIndexed.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileParserIndexed.java @@ -39,7 +39,7 @@ public Character getFieldDelimiter() { public BigInteger getTimeField() { - return timeField==null ? null : BigInteger.valueOf(timeField); + return BigInteger.valueOf(timeField); } @JsonPOJOBuilder diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeValuePair.java b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeValuePair.java index 0d3eb5582..52253db5b 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeValuePair.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dto/timeseriesprofile/TimeValuePair.java @@ -5,20 +5,27 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonNaming; import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; +import cwms.cda.data.dto.CwmsDTOBase; +import cwms.cda.formatters.Formats; +import cwms.cda.formatters.annotations.FormattableWith; +import cwms.cda.formatters.json.JsonV2; import java.time.Instant; +@FormattableWith(contentType = Formats.JSONV2, formatter = JsonV2.class) @JsonDeserialize(builder = TimeValuePair.Builder.class) @JsonInclude(JsonInclude.Include.NON_NULL) @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) -public final class TimeValuePair { +public final class TimeValuePair extends CwmsDTOBase { private final Instant dateTime; private final double value; + private final int quality; private TimeValuePair(Builder builder) { dateTime = builder.dateTime; value = builder.value; + quality = builder.quality; } public Instant getDateTime() { @@ -28,11 +35,17 @@ public double getValue() { return value; } + public int getQuality() + { + return quality; + } + @JsonPOJOBuilder @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class) public static final class Builder { private Instant dateTime; private double value; + private int quality; public Builder withDateTime(Instant dateTime) { this.dateTime = dateTime; @@ -43,7 +56,10 @@ public Builder withValue(double value) { this.value = value; return this; } - + public Builder withQuality(int quality) { + this.quality = quality; + return this; + } public TimeValuePair build() { return new TimeValuePair(this); } diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfoTest.java b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfoTest.java new file mode 100644 index 000000000..7d16ce7e0 --- /dev/null +++ b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/ParameterInfoTest.java @@ -0,0 +1,81 @@ +package cwms.cda.data.dto.timeseriesprofile; + +import cwms.cda.formatters.ContentType; +import cwms.cda.formatters.Formats; +import org.apache.commons.io.IOUtils; +import org.junit.jupiter.api.Test; + +import java.io.InputStream; +import java.nio.charset.StandardCharsets; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +class ParameterInfoTest { + @Test + void testParameterInfoColumnarRoundTrip() { + ParameterInfo parameterInfo = buildParameterInfoColumnar(); + ContentType contentType = Formats.parseHeader(Formats.JSONV2, ParameterInfoColumnar.class); + String serialized = Formats.format(contentType, parameterInfo); + ParameterInfoColumnar deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2, ParameterInfoColumnar.class), serialized, ParameterInfoColumnar.class); + testAssertEquals((ParameterInfoColumnar)parameterInfo, deserialized, "Roundtrip serialization failed"); + } + @Test + void testParameterInfoIndexedRoundTrip() { + ParameterInfo parameterInfo = buildParameterInfoIndexed(); + ContentType contentType = Formats.parseHeader(Formats.JSONV2, ParameterInfoIndexed.class); + String serialized = Formats.format(contentType, parameterInfo); + ParameterInfoIndexed deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2, ParameterInfoIndexed.class), serialized, ParameterInfoIndexed.class); + testAssertEquals((ParameterInfoIndexed) parameterInfo, deserialized, "Roundtrip serialization failed"); + } + + @Test + void testParameterInfoColumnarRoundTripFromFile() throws Exception { + ParameterInfo parameterInfo = buildParameterInfoColumnar(); + InputStream resource = this.getClass().getResourceAsStream("/cwms/cda/data/dto/timeseriesprofile/parameterinfocolumnar.json"); + assertNotNull(resource); + String serialized = IOUtils.toString(resource, StandardCharsets.UTF_8); + ParameterInfoColumnar deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2, ParameterInfoColumnar.class), serialized, ParameterInfoColumnar.class); + testAssertEquals((ParameterInfoColumnar)parameterInfo, deserialized, "Roundtrip serialization from file failed"); + } + @Test + void testParameterInfoIndexedRoundTripFromFile() throws Exception { + ParameterInfo parameterInfo = buildParameterInfoIndexed(); + InputStream resource = this.getClass().getResourceAsStream("/cwms/cda/data/dto/timeseriesprofile/parameterinfoindexed.json"); + assertNotNull(resource); + String serialized = IOUtils.toString(resource, StandardCharsets.UTF_8); + ParameterInfoIndexed deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2, ParameterInfoIndexed.class), serialized, ParameterInfoIndexed.class); + testAssertEquals((ParameterInfoIndexed)parameterInfo, deserialized, "Roundtrip serialization from file failed"); + } + + static ParameterInfo buildParameterInfoColumnar() { + return new ParameterInfoColumnar.Builder() + .withEndColumn(20) + .withStartColumn(10) + .withParameter("Depth") + .withUnit("m") + .build(); + } + static ParameterInfo buildParameterInfoIndexed() { + return new ParameterInfoIndexed.Builder() + .withIndex(1) + .withParameter("Depth") + .withUnit("m") + .build(); + } + + static void testAssertEquals(ParameterInfoColumnar expected, ParameterInfoColumnar actual, String message) { + assertEquals(expected.getParameter(), actual.getParameter(), message); + assertEquals(expected.getParameterInfoString(), actual.getParameterInfoString(), message); + assertEquals(expected.getStartColumn(), actual.getStartColumn(), message); + assertEquals(expected.getEndColumn(), actual.getEndColumn(), message); + assertEquals(expected.getUnit(), actual.getUnit(), message); + } + static void testAssertEquals(ParameterInfoIndexed expected, ParameterInfoIndexed actual, String message) { + assertEquals(expected.getParameter(), actual.getParameter(), message); + assertEquals(expected.getParameterInfoString(), actual.getParameterInfoString(), message); + assertEquals(expected.getIndex(), actual.getIndex(), message); + assertEquals(expected.getUnit(), actual.getUnit(), message); + } + +} diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstanceTest.java b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstanceTest.java index 9231af8cd..9632fe73b 100644 --- a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstanceTest.java +++ b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileInstanceTest.java @@ -49,6 +49,8 @@ private TimeSeriesProfileInstance buildTestTimeSeriesProfileInstance() { return new TimeSeriesProfileInstance.Builder() .withTimeSeriesProfile(timeSeriesProfile) .withTimeSeriesList(timeSeriesList) + .withFirstDate(Instant.parse("2020-07-09T12:00:00.00Z")) + .withLastDate(Instant.parse("2025-07-09T12:00:00.00Z")) .build(); } @@ -77,6 +79,8 @@ private List buildTimeValueList() { private void testAssertEquals(TimeSeriesProfileInstance expected, TimeSeriesProfileInstance actual, String message) { TimeSeriesProfileTest.testAssertEquals(expected.getTimeSeriesProfile(), actual.getTimeSeriesProfile(), message); testAssertEquals(expected.getTimeSeriesList(), actual.getTimeSeriesList(), message); + assertEquals(expected.getFirstDate(), actual.getFirstDate()); + assertEquals(expected.getLastDate(), actual.getLastDate()); } private void testAssertEquals(List expected, List actual, String message) { diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileTest.java b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileTest.java index acbf89072..8a904779c 100644 --- a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileTest.java +++ b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeSeriesProfileTest.java @@ -3,6 +3,7 @@ import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.Arrays; +import java.util.Collections; import cwms.cda.data.dto.CwmsId; import cwms.cda.formatters.ContentType; diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeValuePairTest.java b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeValuePairTest.java new file mode 100644 index 000000000..174f9329b --- /dev/null +++ b/cwms-data-api/src/test/java/cwms/cda/data/dto/timeseriesprofile/TimeValuePairTest.java @@ -0,0 +1,48 @@ +package cwms.cda.data.dto.timeseriesprofile; + +import cwms.cda.formatters.ContentType; +import cwms.cda.formatters.Formats; +import org.apache.commons.io.IOUtils; +import org.junit.jupiter.api.Test; + +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.time.Instant; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +public class TimeValuePairTest { + @Test + void testTimeValuePairRoundTrip() { + TimeValuePair timeValuePair = buildTestTimeValuePair(); + ContentType contentType = Formats.parseHeader(Formats.JSONV2, TimeValuePair.class); + String serialized = Formats.format(contentType, timeValuePair); + TimeValuePair deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2, TimeValuePair.class), serialized, TimeValuePair.class); + testAssertEquals(timeValuePair, deserialized, "Roundtrip serialization failed"); + } + + @Test + void testTimeValuePairSerializationRoundTripFromFile() throws Exception { + TimeValuePair timeValuePair = buildTestTimeValuePair(); + InputStream resource = this.getClass().getResourceAsStream("/cwms/cda/data/dto/timeseriesprofile/timevaluepair.json"); + assertNotNull(resource); + String serialized = IOUtils.toString(resource, StandardCharsets.UTF_8); + TimeValuePair deserialized = Formats.parseContent(Formats.parseHeader(Formats.JSONV2, TimeValuePair.class), serialized, TimeValuePair.class); + testAssertEquals(timeValuePair, deserialized, "Roundtrip serialization from file failed"); + } + + static TimeValuePair buildTestTimeValuePair() { + return new TimeValuePair.Builder() + .withValue(1.0) + .withQuality(0) + .withDateTime(Instant.parse("2025-07-09T12:00:00.00Z")) + .build(); + } + + public static void testAssertEquals(TimeValuePair expected, TimeValuePair actual, String message) { + assertEquals(expected.getValue(), actual.getValue(), message); + assertEquals(expected.getDateTime(), actual.getDateTime(), message); + assertEquals(expected.getQuality(), actual.getQuality(), message); + } + +} diff --git a/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/parameterinfocolumnar.json b/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/parameterinfocolumnar.json new file mode 100644 index 000000000..cf686f8de --- /dev/null +++ b/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/parameterinfocolumnar.json @@ -0,0 +1,7 @@ +{ + "type": "columnar-parameter-info", + "parameter": "Depth", + "unit": "m", + "start-column": 10, + "end-column": 20 +} \ No newline at end of file diff --git a/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/parameterinfoindexed.json b/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/parameterinfoindexed.json new file mode 100644 index 000000000..aab556f95 --- /dev/null +++ b/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/parameterinfoindexed.json @@ -0,0 +1,6 @@ +{ + "type": "indexed-parameter-info", + "parameter": "Depth", + "unit": "m", + "index": 1 +} \ No newline at end of file diff --git a/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileinstance.json b/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileinstance.json index d4c82a026..4583e0432 100644 --- a/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileinstance.json +++ b/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileinstance.json @@ -23,11 +23,13 @@ "values": [ { "date-time": 1612869582120, - "value": 1.0 + "value": 1.0, + "quality": 0 }, { "date-time": 1612869582220, - "value": 3.0 + "value": 3.0, + "quality": 0 } ] }, @@ -38,13 +40,17 @@ "values": [ { "date-time": 1612869582120, - "value": 1.0 + "value": 1.0, + "quality": 0 }, { "date-time": 1612869582220, - "value": 3.0 + "value": 3.0, + "quality": 0 } ] } - ] + ], + "first-date": 1594296000000, + "last-date": 1752062400000 } \ No newline at end of file diff --git a/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileparsercolumnar.json b/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileparsercolumnar.json index 3b39d921f..727e9f4cc 100644 --- a/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileparsercolumnar.json +++ b/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileparsercolumnar.json @@ -1,5 +1,5 @@ { - "type":"TimeSeriesProfileParserColumnar", + "type": "columnar-timeseries-profile-parser", "location-id": { "office-id": "SWT", "name": "location" @@ -10,14 +10,14 @@ "time-zone": "UTC", "parameter-info-list": [ { - "type": "ParameterInfoColumnar", + "type": "columnar-parameter-info", "parameter": "Depth", "unit": "m", "start-column": 11, "end-column": 20 }, { - "type": "ParameterInfoColumnar", + "type": "columnar-parameter-info", "parameter": "Temp-Water", "unit": "F", "start-column": 21, diff --git a/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileparserindexed.json b/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileparserindexed.json index 5e7897001..864f73123 100644 --- a/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileparserindexed.json +++ b/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timeseriesprofileparserindexed.json @@ -1,28 +1,28 @@ { - "type": "TimeSeriesProfileParserIndexed", + "type": "indexed-timeseries-profile-parser", "location-id": { "office-id": "SWT", "name": "location" }, "key-parameter": "Depth", "record-delimiter": "\n", - "field-delimiter": ",", "time-format": "MM/DD/YYYY,HH24:MI:SS", "time-zone": "UTC", - "time-field": 1, - "time-in-two-fields": false, "parameter-info-list": [ { - "type": "ParameterInfoIndexed", - "parameter":"Depth", - "unit":"m", - "index":3 + "type": "indexed-parameter-info", + "parameter": "Depth", + "unit": "m", + "index": 3 }, { - "type": "ParameterInfoIndexed", - "parameter":"Temp-Water", - "unit":"F", - "index":5 + "type": "indexed-parameter-info", + "parameter": "Temp-Water", + "unit": "F", + "index": 5 } - ] -} + ], + "time-in-two-fields": false, + "field-delimiter": ",", + "time-field": 1 +} \ No newline at end of file diff --git a/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timevaluepair.json b/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timevaluepair.json new file mode 100644 index 000000000..eee23352e --- /dev/null +++ b/cwms-data-api/src/test/resources/cwms/cda/data/dto/timeseriesprofile/timevaluepair.json @@ -0,0 +1,5 @@ +{ + "date-time": 1752062400000, + "value": 1.0, + "quality": 0 +} \ No newline at end of file From 7fc5082edfc4a017b4763b4a474f4c0b227d90a0 Mon Sep 17 00:00:00 2001 From: Andreas Christmann Date: Fri, 9 Aug 2024 11:49:33 -0700 Subject: [PATCH 26/26] access View, bypass PL/SQL, prepare for pagination --- .../TimeSeriesProfileDao.java | 65 +-- .../TimeSeriesProfileInstanceDao.java | 103 ++--- .../TimeSeriesProfileParserDao.java | 430 +++++++++++------- .../TimeSeriesProfileInstanceDaoIT.java | 36 +- .../TimeSeriesProfileParserDaoIT.java | 41 ++ 5 files changed, 397 insertions(+), 278 deletions(-) diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileDao.java b/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileDao.java index e379b194b..b08ea9ad8 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileDao.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileDao.java @@ -1,11 +1,14 @@ package cwms.cda.data.dao.timeseriesprofile; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import cwms.cda.data.dao.JooqDao; import cwms.cda.data.dto.CwmsId; import cwms.cda.data.dto.timeseriesprofile.TimeSeriesProfile; +import org.jetbrains.annotations.NotNull; +import org.jooq.Condition; import org.jooq.DSLContext; import org.jooq.Record; import org.jooq.Result; @@ -15,6 +18,8 @@ import usace.cwms.db.jooq.codegen.udt.records.STR_TAB_T; import usace.cwms.db.jooq.codegen.udt.records.TS_PROFILE_T; +import static usace.cwms.db.jooq.codegen.tables.AV_TS_PROFILE.AV_TS_PROFILE; + public class TimeSeriesProfileDao extends JooqDao { public TimeSeriesProfileDao(DSLContext dsl) { super(dsl); @@ -60,36 +65,38 @@ public void copyTimeSeriesProfile(String locationId, String keyParameter, String destRefTsId, "F", "F", officeId)); } + public List catalogTimeSeriesProfiles(String locationIdMask, String parameterIdMask, String officeIdMask) { + List timeSeriesProfileList = new ArrayList<>(); - public List catalogTimeSeriesProfiles(String locationIdMask, String parameterIdMask, String officeIdMask) { - return connectionResult(dsl, conn -> { - List timeSeriesProfileList = new ArrayList<>(); - Result timeSeriesProfileResults = CWMS_TS_PROFILE_PACKAGE.call_CAT_TS_PROFILE( - DSL.using(conn).configuration(), locationIdMask, parameterIdMask, officeIdMask); - for (Record timeSeriesProfileResult : timeSeriesProfileResults) { - Result values = timeSeriesProfileResult.get("VALUE_PARAMETERS", Result.class); - List parameterList = new ArrayList<>(); - for (Record value : values) { - parameterList.add(value.get("PARMETER_ID", String.class)); - } - CwmsId locationId = new CwmsId.Builder() - .withName((String) timeSeriesProfileResult.get("LOCATION_ID")) - .withOfficeId((String) timeSeriesProfileResult.get("OFFICE_ID")) - .build(); - CwmsId referenceTsId = new CwmsId.Builder() - .withName((String) timeSeriesProfileResult.get("REF_TS_ID")) - .withOfficeId((String) timeSeriesProfileResult.get("OFFICE_ID")) - .build(); - timeSeriesProfileList.add(new TimeSeriesProfile.Builder() - .withDescription((String) timeSeriesProfileResult.get("DESCRIPTION")) - .withReferenceTsId(referenceTsId) - .withKeyParameter((String) timeSeriesProfileResult.get("KEY_PARAMETER_ID")) - .withLocationId(locationId) - .withParameterList(parameterList) - .build()); - } - return timeSeriesProfileList; - }); + Condition whereCondition = JooqDao.caseInsensitiveLikeRegexNullTrue(AV_TS_PROFILE.LOCATION_ID, locationIdMask); + whereCondition = whereCondition.and(JooqDao.caseInsensitiveLikeRegex(AV_TS_PROFILE.OFFICE_ID, officeIdMask)); + whereCondition = whereCondition.and(JooqDao.caseInsensitiveLikeRegex(AV_TS_PROFILE.KEY_PARAMETER_ID, parameterIdMask)); + + @NotNull Result timeSeriesProfileResults = dsl.select(DSL.asterisk()).from(AV_TS_PROFILE) + .where(whereCondition) + .fetch(); + for (Record timeSeriesProfileResult : timeSeriesProfileResults) { + String parameters = timeSeriesProfileResult.get("PARAMETERS", String.class); + String[] parameterArray = parameters.split(","); + List parameterList = Arrays.asList(parameterArray); + + CwmsId locationId = new CwmsId.Builder() + .withName((String) timeSeriesProfileResult.get("LOCATION_ID")) + .withOfficeId((String) timeSeriesProfileResult.get("OFFICE_ID")) + .build(); + CwmsId referenceTsId = new CwmsId.Builder() + .withName((String) timeSeriesProfileResult.get("ELEV_TS_ID")) + .withOfficeId((String) timeSeriesProfileResult.get("OFFICE_ID")) + .build(); + timeSeriesProfileList.add(new TimeSeriesProfile.Builder() + .withDescription((String) timeSeriesProfileResult.get("DESCRIPTION")) + .withReferenceTsId(referenceTsId) + .withKeyParameter((String) timeSeriesProfileResult.get("KEY_PARAMETER_ID")) + .withLocationId(locationId) + .withParameterList(parameterList) + .build()); + } + return timeSeriesProfileList; } private TimeSeriesProfile map(TS_PROFILE_T timeSeriesProfile, String locationName, String keyParameter, String officeId) { diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDao.java b/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDao.java index 7cbbaa98c..adaa24328 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDao.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDao.java @@ -7,6 +7,7 @@ import cwms.cda.data.dto.timeseriesprofile.TimeSeriesProfileInstance; import cwms.cda.data.dto.timeseriesprofile.TimeValuePair; import org.jetbrains.annotations.NotNull; +import org.jooq.Condition; import org.jooq.Configuration; import org.jooq.DSLContext; import org.jooq.Record; @@ -15,6 +16,7 @@ import usace.cwms.db.jooq.codegen.packages.CWMS_LOC_PACKAGE; import usace.cwms.db.jooq.codegen.packages.CWMS_TS_PROFILE_PACKAGE; import usace.cwms.db.jooq.codegen.packages.CWMS_UTIL_PACKAGE; +import usace.cwms.db.jooq.codegen.tables.AV_TS_PROFILE_INST; import usace.cwms.db.jooq.codegen.udt.records.PVQ_T; import usace.cwms.db.jooq.codegen.udt.records.PVQ_TAB_T; import usace.cwms.db.jooq.codegen.udt.records.STR_TAB_T; @@ -41,21 +43,15 @@ public TimeSeriesProfileInstanceDao(DSLContext dsl) void storeTimeSeriesProfileInstance(TimeSeriesProfile timeSeriesProfile, String profileData, Instant versionDate, String versionId, String storeRule, boolean overrideProtection) { - connection(dsl, conn -> { - try { - CWMS_TS_PROFILE_PACKAGE.call_STORE_TS_PROFILE_INSTANCE__2(DSL.using(conn).configuration(), - timeSeriesProfile.getLocationId().getName(), - timeSeriesProfile.getKeyParameter(), - profileData, - versionId, - storeRule, - overrideProtection?"T":"F", - versionDate!=null?Timestamp.from(versionDate):null, - timeSeriesProfile.getLocationId().getOfficeId()); - } catch (Exception ex) { - ex.printStackTrace(); - } - }); + connection(dsl, conn -> CWMS_TS_PROFILE_PACKAGE.call_STORE_TS_PROFILE_INSTANCE__2(DSL.using(conn).configuration(), + timeSeriesProfile.getLocationId().getName(), + timeSeriesProfile.getKeyParameter(), + profileData, + versionId, + storeRule, + overrideProtection?"T":"F", + versionDate!=null?Timestamp.from(versionDate):null, + timeSeriesProfile.getLocationId().getOfficeId())); } void storeTimeSeriesProfileInstance(TimeSeriesProfileInstance timeseriesProfileInstance, String versionId, Instant versionInstant, String storeRule,String overrideProtection) @@ -127,7 +123,6 @@ void storeTimeSeriesProfileInstance(TimeSeriesProfileInstance timeseriesProfileI Timestamp versionTimeStamp = Timestamp.from(versionInstant); - try { CWMS_TS_PROFILE_PACKAGE.call_STORE_TS_PROFILE_INSTANCE(DSL.using(conn).configuration(), @@ -137,44 +132,44 @@ void storeTimeSeriesProfileInstance(TimeSeriesProfileInstance timeseriesProfileI overrideProtection, versionTimeStamp, timeseriesProfileInstance.getTimeSeriesProfile().getLocationId().getOfficeId()); - } - catch(Exception ex) - { - ex.printStackTrace(); - } - } + } ); } - List catalogTimeSeriesProfileInstances( String officeIdMask, String locationMask, String parameterMask, String versionMask, - Instant startTime, Instant endTime, String timeZone) + + + List catalogTimeSeriesProfileInstances( String officeIdMask, String locationIdMask, String parameterIdMask, String versionMask) { - return connectionResult(dsl, conn -> { - List instanceList = new ArrayList<>(); - Result results = CWMS_TS_PROFILE_PACKAGE.call_CAT_TS_PROFILE_INSTANCE(DSL.using(conn).configuration(), - locationMask, parameterMask, versionMask, Timestamp.from(startTime), Timestamp.from(endTime), - timeZone, officeIdMask); - for (Record result : results) { + List timeSeriesProfileInstanceList = new ArrayList<>(); + + Condition whereCondition = JooqDao.caseInsensitiveLikeRegexNullTrue(AV_TS_PROFILE_INST.AV_TS_PROFILE_INST.LOCATION_ID, locationIdMask); + whereCondition = whereCondition.and(JooqDao.caseInsensitiveLikeRegex(AV_TS_PROFILE_INST.AV_TS_PROFILE_INST.OFFICE_ID, officeIdMask)); + whereCondition = whereCondition.and(JooqDao.caseInsensitiveLikeRegex(AV_TS_PROFILE_INST.AV_TS_PROFILE_INST.KEY_PARAMETER_ID, parameterIdMask)); + whereCondition = whereCondition.and(JooqDao.caseInsensitiveLikeRegex(AV_TS_PROFILE_INST.AV_TS_PROFILE_INST.VERSION_ID, versionMask)); + + @NotNull Result timeSeriesProfileInstanceResults = dsl.select(DSL.asterisk()).from(AV_TS_PROFILE_INST.AV_TS_PROFILE_INST) + .where(whereCondition) + .fetch(); + for (Record result : timeSeriesProfileInstanceResults) { CwmsId locationId = new CwmsId.Builder() - .withOfficeId((String) result.get(0)) - .withName((String) result.get(1)) + .withOfficeId(result.get("OFFICE_ID",String.class)) + .withName(result.get("LOCATION_ID", String.class)) .build(); - String parameterId = (String) result.get(2); + String parameterId = result.get("KEY_PARAMETER_ID", String.class); TimeSeriesProfile timeSeriesProfile = new TimeSeriesProfile.Builder() .withLocationId(locationId) .withKeyParameter(parameterId) .build(); TimeSeriesProfileInstance timeSeriesProfileInstance = new TimeSeriesProfileInstance.Builder() .withTimeSeriesProfile(timeSeriesProfile) - .withVersion(result.get(3, String.class)) - .withVersionDate(result.get(4, Instant.class)) - .withFirstDate(result.get(5, Instant.class)) - .withLastDate(result.get(6, Instant.class)) + .withVersion(result.get("VERSION_ID", String.class)) + .withVersionDate(result.get("VERSION_DATE", Instant.class)) + .withFirstDate(result.get("FIRST_DATE_TIME", Instant.class)) + .withLastDate(result.get("LAST_DATE_TIME", Instant.class)) .build(); - instanceList.add(timeSeriesProfileInstance); - } - return instanceList; - }); + timeSeriesProfileInstanceList.add(timeSeriesProfileInstance); + } + return timeSeriesProfileInstanceList; } TimeSeriesProfileInstance retrieveTimeSeriesProfileInstance(CwmsId location, String keyParameter, @@ -192,7 +187,6 @@ TimeSeriesProfileInstance retrieveTimeSeriesProfileInstance(CwmsId location, Str { return connectionResult(dsl, conn -> { TS_PROF_DATA_T timeSeriesProfileData; - try { timeSeriesProfileData = CWMS_TS_PROFILE_PACKAGE.call_RETRIEVE_TS_PROFILE_DATA( DSL.using(conn).configuration(), location.getName(), @@ -210,13 +204,8 @@ TimeSeriesProfileInstance retrieveTimeSeriesProfileInstance(CwmsId location, Str maxVersion, location.getOfficeId() ); - } - catch(Exception ex) - { - ex.printStackTrace(); - return null; - } - return map(DSL.using(conn).configuration(), location.getOfficeId(), timeSeriesProfileData); + + return map(DSL.using(conn).configuration(), location.getOfficeId(), timeSeriesProfileData, version, versionDate); }); } void deleteTimeSeriesProfileInstance(CwmsId location, String keyParameter, @@ -230,7 +219,6 @@ void deleteTimeSeriesProfileInstance(CwmsId location, String keyParameter, versionTimestamp = Timestamp.from(versionDate); } - try { CWMS_TS_PROFILE_PACKAGE.call_DELETE_TS_PROFILE_INSTANCE( DSL.using(conn).configuration(), location.getName(), @@ -242,16 +230,12 @@ void deleteTimeSeriesProfileInstance(CwmsId location, String keyParameter, versionTimestamp, location.getOfficeId() ); - } - catch (Exception ex) - { - ex.printStackTrace(); - } + }); } - private TimeSeriesProfileInstance map(@NotNull Configuration configuration, String officeId, TS_PROF_DATA_T timeSeriesProfileData) { + private TimeSeriesProfileInstance map(@NotNull Configuration configuration, String officeId, TS_PROF_DATA_T timeSeriesProfileData, String version, Instant versionDate) { String timeZone = timeSeriesProfileData.getTIME_ZONE(); STR_TAB_T units = timeSeriesProfileData.getUNITS(); TS_PROF_DATA_TAB_T records = timeSeriesProfileData.getRECORDS(); @@ -261,6 +245,7 @@ private TimeSeriesProfileInstance map(@NotNull Configuration configuration, Stri String keyParameter = CWMS_UTIL_PACKAGE.call_GET_PARAMETER_ID(configuration, keyParameterCode); List timeList = new ArrayList<>(); List> valuesList = new ArrayList<>(); + List> qualitiesList = new ArrayList<>(); List> parametersList = new ArrayList<>(); for(TS_PROF_DATA_REC_T dataRecord : records) { @@ -268,14 +253,17 @@ private TimeSeriesProfileInstance map(@NotNull Configuration configuration, Stri timeList.add(dateTime); PVQ_TAB_T parameters = dataRecord.getPARAMETERS(); List valueList = new ArrayList<>(); + List qualityList = new ArrayList<>(); List parameterList = new ArrayList<>(); for(PVQ_T parameter : parameters) { valueList.add(parameter.getVALUE()); + qualityList.add(parameter.getQUALITY_CODE().intValue()); parameterList.add(parameter.getPARAMETER_CODE()); } valuesList.add(valueList); parametersList.add(parameterList); + qualitiesList.add(qualityList); } List parameterList = new ArrayList<>(); List> timeValuePairList = new ArrayList<>(); @@ -293,6 +281,7 @@ private TimeSeriesProfileInstance map(@NotNull Configuration configuration, Stri TimeValuePair timeValuePair = new TimeValuePair.Builder() .withDateTime(timeList.get(i)) .withValue(valuesList.get(i).get(j)) + .withQuality(qualitiesList.get(i).get(j)) .build(); timeValuePairList.get(j).add(timeValuePair); } @@ -321,6 +310,8 @@ private TimeSeriesProfileInstance map(@NotNull Configuration configuration, Stri return new TimeSeriesProfileInstance.Builder() .withTimeSeriesProfile(timeSeriesProfile) .withTimeSeriesList(timeSeriesList) + .withVersion(version) + .withVersionDate(versionDate) .build(); } } \ No newline at end of file diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDao.java b/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDao.java index 71d1772e2..3bc04145d 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDao.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDao.java @@ -11,6 +11,8 @@ import cwms.cda.data.dto.timeseriesprofile.TimeSeriesProfileParser; import cwms.cda.data.dto.timeseriesprofile.TimeSeriesProfileParserColumnar; import cwms.cda.data.dto.timeseriesprofile.TimeSeriesProfileParserIndexed; +import org.jetbrains.annotations.NotNull; +import org.jooq.Condition; import org.jooq.DSLContext; import org.jooq.Record; import org.jooq.Result; @@ -18,185 +20,259 @@ import usace.cwms.db.jooq.codegen.packages.CWMS_TS_PROFILE_PACKAGE; import usace.cwms.db.jooq.codegen.packages.cwms_ts_profile.RETRIEVE_TS_PROFILE_PARSER; +import usace.cwms.db.jooq.codegen.tables.AV_TS_PROFILE_PARSER; +import usace.cwms.db.jooq.codegen.tables.AV_TS_PROFILE_PARSER_PARAM; -public class TimeSeriesProfileParserDao extends JooqDao -{ - public TimeSeriesProfileParserDao(DSLContext dsl) - { - super(dsl); - } - - private List getParameterInfoList(String info, String recordDelimiter, String fieldDelimiter) - { - List parameterInfoList = new ArrayList<>(); - String[] records = info.split(recordDelimiter); - for(String aRecord : records) - { - String[] fields = aRecord.split(fieldDelimiter); - int index = Integer.parseInt(fields[2]); - ParameterInfo parameterInfo = new ParameterInfoIndexed.Builder().withIndex(index) - .withParameter(fields[0]) - .withUnit(fields[1]) - .build(); - parameterInfoList.add(parameterInfo); - } - return parameterInfoList; - } - - private String getParameterInfoString(TimeSeriesProfileParser timeSeriesProfileParser) - { - List parameterInfo = timeSeriesProfileParser.getParameterInfoList(); - - StringBuilder parameterInfoBuilder = new StringBuilder(); - parameterInfoBuilder.append(parameterInfo.get(0).getParameterInfoString()); - - for(int i = 1; i < parameterInfo.size(); i++) - { - parameterInfoBuilder.append(timeSeriesProfileParser.getRecordDelimiter()) - .append(parameterInfo.get(i).getParameterInfoString()); - } - return parameterInfoBuilder.toString(); - } - - public void storeTimeSeriesProfileParser(TimeSeriesProfileParserIndexed timeSeriesProfileParser, boolean failIfExists) - { - connection(dsl, conn -> - CWMS_TS_PROFILE_PACKAGE.call_STORE_TS_PROFILE_PARSER(DSL.using(conn).configuration(), timeSeriesProfileParser.getLocationId().getName(), - timeSeriesProfileParser.getKeyParameter(), String.valueOf(timeSeriesProfileParser.getRecordDelimiter()), - String.valueOf(timeSeriesProfileParser.getFieldDelimiter()), timeSeriesProfileParser.getTimeField(), - null, null, timeSeriesProfileParser.getTimeFormat(), - timeSeriesProfileParser.getTimeZone(), getParameterInfoString(timeSeriesProfileParser), - timeSeriesProfileParser.getTimeInTwoFields()?"T":"F", - failIfExists?"T":"F", "T", timeSeriesProfileParser.getLocationId().getOfficeId()) - ); - } - public void storeTimeSeriesProfileParser(TimeSeriesProfileParserColumnar timeSeriesProfileParser, boolean failIfExists) - { - connection(dsl, conn -> - CWMS_TS_PROFILE_PACKAGE.call_STORE_TS_PROFILE_PARSER(DSL.using(conn).configuration(), timeSeriesProfileParser.getLocationId().getName(), - timeSeriesProfileParser.getKeyParameter(), String.valueOf(timeSeriesProfileParser.getRecordDelimiter()), - null, null, - timeSeriesProfileParser.getTimeStartColumn(), timeSeriesProfileParser.getTimeEndColumn(), timeSeriesProfileParser.getTimeFormat(), - timeSeriesProfileParser.getTimeZone(), getParameterInfoString(timeSeriesProfileParser), - timeSeriesProfileParser.getTimeInTwoFields()?"T":"F", - failIfExists?"T":"F", "F", timeSeriesProfileParser.getLocationId().getOfficeId()) - ); - } - public TimeSeriesProfileParser retrieveTimeSeriesProfileParser(String locationId, String parameterId, String officeId) - { - return connectionResult(dsl, conn -> { - RETRIEVE_TS_PROFILE_PARSER timeSeriesProfileParser = CWMS_TS_PROFILE_PACKAGE.call_RETRIEVE_TS_PROFILE_PARSER( - DSL.using(conn).configuration(), locationId, parameterId, officeId); - return map(timeSeriesProfileParser, locationId, parameterId, officeId); - }); - } - - public List catalogTimeSeriesProfileParsers(String locationIdMask, String parameterIdMask, String officeIdMask) - { - return connectionResult(dsl, conn -> { - Result tsProfileParserResult = CWMS_TS_PROFILE_PACKAGE.call_CAT_TS_PROFILE_PARSER(DSL.using(conn).configuration(), - locationIdMask, parameterIdMask, officeIdMask); - List timeSeriesProfileParserList = new ArrayList<>(); - for(Record profileParser : tsProfileParserResult) - { - String recordDelimiter = profileParser.get("RECORD_DELIMITER", String.class); - String fieldDelimiter = profileParser.get("FIELD_DELIMITER", String.class); - Short timeField = profileParser.get("TIME_FIELD", Short.class); - Short timeStartCol = profileParser.get("TIME_START_COL", Short.class); - Short timeEndCol = profileParser.get("TIME_END_COL", Short.class); - Result parameterInfoResult = profileParser.get("PARAMETER_INFO", Result.class); - - List parameterInfoList = new ArrayList<>(); - for(Record recordParam : parameterInfoResult) - { - if(timeField!=null) { - parameterInfoList.add(new ParameterInfoIndexed.Builder() - .withIndex(recordParam.get("FIELD_NUMBER", Short.class)) - .withParameter((String) recordParam.get("PARAMETER_ID")) - .withUnit((String) recordParam.get("UNIT")) - .build()); - } - else { - parameterInfoList.add(new ParameterInfoColumnar.Builder() - .withStartColumn(recordParam.get("START_COL", Short.class)) - .withEndColumn(recordParam.get("END_COL", Short.class)) - .withParameter((String) recordParam.get("PARAMETER_ID")) - .withUnit((String) recordParam.get("UNIT")) - .build()); - } - } - - - CwmsId locationId = new CwmsId.Builder() - .withOfficeId((String) profileParser.get("OFFICE_ID")) - .withName((String) profileParser.get("LOCATION_ID")) - .build(); - TimeSeriesProfileParser timeSeriesProfileParser ; - if(timeField!=null) - { - timeSeriesProfileParser = new TimeSeriesProfileParserIndexed.Builder() - .withFieldDelimiter(fieldDelimiter.toCharArray()[0]) - .withTimeField(timeField) - .withLocationId(locationId) - .withKeyParameter((String) profileParser.get("KEY_PARAMTER_ID")) - .withTimeFormat((String) profileParser.get("TIME_FORMAT")) - .withTimeZone((String) profileParser.get("TIME_ZONE")) - .withRecordDelimiter(recordDelimiter.toCharArray()[0]) - .withParameterInfoList(parameterInfoList) - .build(); - timeSeriesProfileParserList.add(timeSeriesProfileParser); - } - else if(timeStartCol!=null && timeEndCol!=null) - { - timeSeriesProfileParser = new TimeSeriesProfileParserColumnar.Builder() - .withTimeStartColumn(timeStartCol) - .withTimeEndColumn(timeEndCol) - .withLocationId(locationId) - .withKeyParameter((String) profileParser.get("KEY_PARAMTER_ID")) - .withTimeFormat((String) profileParser.get("TIME_FORMAT")) - .withTimeZone((String) profileParser.get("TIME_ZONE")) - .withRecordDelimiter(recordDelimiter.toCharArray()[0]) - .withParameterInfoList(parameterInfoList) - .build(); - timeSeriesProfileParserList.add(timeSeriesProfileParser); - } - - } - return timeSeriesProfileParserList; - }); - } - - - public void copyTimeSeriesProfileParser(String locationId, String parameterId, String officeId, String destinationLocation) - { - connection(dsl, conn -> - CWMS_TS_PROFILE_PACKAGE.call_COPY_TS_PROFILE_PARSER(DSL.using(conn).configuration(),locationId, parameterId, destinationLocation, - "F", officeId)); - } - public void deleteTimeSeriesProfileParser(String locationId, String parameterId, String officeId) - { - connection(dsl, conn -> - CWMS_TS_PROFILE_PACKAGE.call_DELETE_TS_PROFILE_PARSER(DSL.using(conn).configuration(), locationId, - parameterId, officeId) - ); - } - private TimeSeriesProfileParser map(RETRIEVE_TS_PROFILE_PARSER timeSeriesProfileParser, String locationName, String keyParameter, String officeId) - { - String info = timeSeriesProfileParser.getP_PARAMETER_INFO(); - List parameterInfo = getParameterInfoList(info, timeSeriesProfileParser.getP_RECORD_DELIMITER(), - timeSeriesProfileParser.getP_FIELD_DELIMITER()); - CwmsId locationId = new CwmsId.Builder().withOfficeId(officeId).withName(locationName).build(); - return new TimeSeriesProfileParser.Builder() - .withLocationId(locationId) +public class TimeSeriesProfileParserDao extends JooqDao { + private static final String PARAMETER_ID = "PARAMETER_ID"; + private static final String KEY_PARAMETER_ID = "KEY_PARAMTER_ID"; + private static final String TIME_FORMAT = "TIME_FORMAT"; + private static final String TIME_ZONE = "TIME_ZONE"; + public TimeSeriesProfileParserDao(DSLContext dsl) { + super(dsl); + } + + private List getParameterInfoList(String info, String recordDelimiter, String fieldDelimiter) { + List parameterInfoList = new ArrayList<>(); + String[] records = info.split(recordDelimiter); + for (String aRecord : records) { + String[] fields = aRecord.split(fieldDelimiter); + int index = Integer.parseInt(fields[2]); + ParameterInfo parameterInfo = new ParameterInfoIndexed.Builder().withIndex(index) + .withParameter(fields[0]) + .withUnit(fields[1]) + .build(); + parameterInfoList.add(parameterInfo); + } + return parameterInfoList; + } + + private String getParameterInfoString(TimeSeriesProfileParser timeSeriesProfileParser) { + List parameterInfo = timeSeriesProfileParser.getParameterInfoList(); + + StringBuilder parameterInfoBuilder = new StringBuilder(); + parameterInfoBuilder.append(parameterInfo.get(0).getParameterInfoString()); + + for (int i = 1; i < parameterInfo.size(); i++) { + parameterInfoBuilder.append(timeSeriesProfileParser.getRecordDelimiter()) + .append(parameterInfo.get(i).getParameterInfoString()); + } + return parameterInfoBuilder.toString(); + } + + public void storeTimeSeriesProfileParser(TimeSeriesProfileParserIndexed timeSeriesProfileParser, boolean failIfExists) { + connection(dsl, conn -> + CWMS_TS_PROFILE_PACKAGE.call_STORE_TS_PROFILE_PARSER(DSL.using(conn).configuration(), timeSeriesProfileParser.getLocationId().getName(), + timeSeriesProfileParser.getKeyParameter(), String.valueOf(timeSeriesProfileParser.getRecordDelimiter()), + String.valueOf(timeSeriesProfileParser.getFieldDelimiter()), timeSeriesProfileParser.getTimeField(), + null, null, timeSeriesProfileParser.getTimeFormat(), + timeSeriesProfileParser.getTimeZone(), getParameterInfoString(timeSeriesProfileParser), + timeSeriesProfileParser.getTimeInTwoFields() ? "T" : "F", + failIfExists ? "T" : "F", "T", timeSeriesProfileParser.getLocationId().getOfficeId()) + ); + } + + public void storeTimeSeriesProfileParser(TimeSeriesProfileParserColumnar timeSeriesProfileParser, boolean failIfExists) { + connection(dsl, conn -> + CWMS_TS_PROFILE_PACKAGE.call_STORE_TS_PROFILE_PARSER(DSL.using(conn).configuration(), timeSeriesProfileParser.getLocationId().getName(), + timeSeriesProfileParser.getKeyParameter(), String.valueOf(timeSeriesProfileParser.getRecordDelimiter()), + null, null, + timeSeriesProfileParser.getTimeStartColumn(), timeSeriesProfileParser.getTimeEndColumn(), timeSeriesProfileParser.getTimeFormat(), + timeSeriesProfileParser.getTimeZone(), getParameterInfoString(timeSeriesProfileParser), + timeSeriesProfileParser.getTimeInTwoFields() ? "T" : "F", + failIfExists ? "T" : "F", "F", timeSeriesProfileParser.getLocationId().getOfficeId()) + ); + } + + public TimeSeriesProfileParser retrieveTimeSeriesProfileParser(String locationId, String parameterId, String officeId) { + return connectionResult(dsl, conn -> { + RETRIEVE_TS_PROFILE_PARSER timeSeriesProfileParser = CWMS_TS_PROFILE_PACKAGE.call_RETRIEVE_TS_PROFILE_PARSER( + DSL.using(conn).configuration(), locationId, parameterId, officeId); + return map(timeSeriesProfileParser, locationId, parameterId, officeId); + }); + } + + public List retrieveParameterInfoList(String locationId, String parameterId, String officeId) { + List parameterInfoList = new ArrayList<>(); + Condition whereCondition = JooqDao.caseInsensitiveLikeRegexNullTrue(AV_TS_PROFILE_PARSER_PARAM.AV_TS_PROFILE_PARSER_PARAM.LOCATION_ID, locationId); + whereCondition = whereCondition.and(JooqDao.caseInsensitiveLikeRegex(AV_TS_PROFILE_PARSER_PARAM.AV_TS_PROFILE_PARSER_PARAM.OFFICE_ID, officeId)); + whereCondition = whereCondition.and(JooqDao.caseInsensitiveLikeRegex(AV_TS_PROFILE_PARSER_PARAM.AV_TS_PROFILE_PARSER_PARAM.KEY_PARAMETER_ID, parameterId)); + Result parameterInfoResults = dsl.select(DSL.asterisk()).from(AV_TS_PROFILE_PARSER_PARAM.AV_TS_PROFILE_PARSER_PARAM) + .where(whereCondition) + .fetch(); + for (Record recordParameterInfo : parameterInfoResults) { + Short parameterField = recordParameterInfo.get("PARAMETER_FIELD", Short.class); + if (parameterField != null) { + parameterInfoList.add(new ParameterInfoIndexed.Builder() + .withIndex(parameterField) + .withParameter((String) recordParameterInfo.get(PARAMETER_ID)) + .withUnit((String) recordParameterInfo.get("PARAMETER_UNIT")) + .build()); + } else { + parameterInfoList.add(new ParameterInfoColumnar.Builder() + .withStartColumn(recordParameterInfo.get("PARAMETER_COL_START", Short.class)) + .withEndColumn(recordParameterInfo.get("PARAMETER_COL_END", Short.class)) + .withParameter((String) recordParameterInfo.get(PARAMETER_ID)) + .withUnit((String) recordParameterInfo.get("PARAMETER_UNIT")) + .build()); + } + } + return parameterInfoList; + } + + public List catalogTimeSeriesProfileParsers(String locationIdMask, String parameterIdMask, String officeIdMask, boolean includeParameters) { + List timeSeriesProfileParserList = new ArrayList<>(); + + Condition whereCondition = JooqDao.caseInsensitiveLikeRegexNullTrue(AV_TS_PROFILE_PARSER.AV_TS_PROFILE_PARSER.LOCATION_ID, locationIdMask); + whereCondition = whereCondition.and(JooqDao.caseInsensitiveLikeRegex(AV_TS_PROFILE_PARSER.AV_TS_PROFILE_PARSER.OFFICE_ID, officeIdMask)); + whereCondition = whereCondition.and(JooqDao.caseInsensitiveLikeRegex(AV_TS_PROFILE_PARSER.AV_TS_PROFILE_PARSER.KEY_PARAMETER_ID, parameterIdMask)); + + @NotNull Result timeSeriesProfileParserResults = dsl.select(DSL.asterisk()).from(AV_TS_PROFILE_PARSER.AV_TS_PROFILE_PARSER) + .where(whereCondition) + .fetch(); + for (Record profileParser : timeSeriesProfileParserResults) { + String recordDelimiter = profileParser.get("RECORD_DELIMTER_VALUE", String.class); + String fieldDelimiter = profileParser.get("FIELD_DELIMIETER_VALUE", String.class); + Short timeField = profileParser.get("TIME_FIELD", Short.class); + Short timeStartCol = profileParser.get("TIME_COL_START", Short.class); + Short timeEndCol = profileParser.get("TIME_COL_END", Short.class); + CwmsId locationId = new CwmsId.Builder() + .withOfficeId((String) profileParser.get("OFFICE_ID")) + .withName((String) profileParser.get("LOCATION_ID")) + .build(); + String keyParameter = profileParser.get("KEY_PARAMETER_ID", String.class); + TimeSeriesProfileParser timeSeriesProfileParser; + List parameterInfoList = null; + if (includeParameters) { + parameterInfoList = retrieveParameterInfoList(locationId.getName(), keyParameter, locationId.getOfficeId()); + } + if (timeField != null) { + timeSeriesProfileParser = new TimeSeriesProfileParserIndexed.Builder() + .withFieldDelimiter(fieldDelimiter.toCharArray()[0]) + .withTimeField(timeField) + .withLocationId(locationId) + .withKeyParameter(keyParameter) + .withParameterInfoList(parameterInfoList) + .withTimeFormat((String) profileParser.get(TIME_FORMAT)) + .withTimeZone((String) profileParser.get("TIME_ZONE_ID")) + .withRecordDelimiter(recordDelimiter.toCharArray()[0]) + .build(); + timeSeriesProfileParserList.add(timeSeriesProfileParser); + } else if (timeStartCol != null && timeEndCol != null) { + timeSeriesProfileParser = new TimeSeriesProfileParserColumnar.Builder() + .withTimeStartColumn(timeStartCol) + .withTimeEndColumn(timeEndCol) + .withLocationId(locationId) + .withKeyParameter(keyParameter) + .withParameterInfoList(parameterInfoList) + .withTimeFormat((String) profileParser.get(TIME_FORMAT)) + .withTimeZone((String) profileParser.get("TIME_ZONE_ID")) + .withRecordDelimiter(recordDelimiter.toCharArray()[0]) + .build(); + timeSeriesProfileParserList.add(timeSeriesProfileParser); + } + } + return timeSeriesProfileParserList; + } + + public List catalogTimeSeriesProfileParsers(String locationIdMask, String parameterIdMask, String officeIdMask) { + return connectionResult(dsl, conn -> { + Result tsProfileParserResult = CWMS_TS_PROFILE_PACKAGE.call_CAT_TS_PROFILE_PARSER(DSL.using(conn).configuration(), + locationIdMask, parameterIdMask, officeIdMask); + List timeSeriesProfileParserList = new ArrayList<>(); + for (Record profileParser : tsProfileParserResult) { + String recordDelimiter = profileParser.get("RECORD_DELIMITER", String.class); + String fieldDelimiter = profileParser.get("FIELD_DELIMITER", String.class); + Short timeField = profileParser.get("TIME_FIELD", Short.class); + Short timeStartCol = profileParser.get("TIME_START_COL", Short.class); + Short timeEndCol = profileParser.get("TIME_END_COL", Short.class); + Result parameterInfoResult = profileParser.get("PARAMETER_INFO", Result.class); + + List parameterInfoList = new ArrayList<>(); + for (Record recordParam : parameterInfoResult) { + if (timeField != null) { + parameterInfoList.add(new ParameterInfoIndexed.Builder() + .withIndex(recordParam.get("FIELD_NUMBER", Short.class)) + .withParameter((String) recordParam.get(PARAMETER_ID)) + .withUnit((String) recordParam.get("UNIT")) + .build()); + } else { + parameterInfoList.add(new ParameterInfoColumnar.Builder() + .withStartColumn(recordParam.get("START_COL", Short.class)) + .withEndColumn(recordParam.get("END_COL", Short.class)) + .withParameter((String) recordParam.get(PARAMETER_ID)) + .withUnit((String) recordParam.get("UNIT")) + .build()); + } + } + + + CwmsId locationId = new CwmsId.Builder() + .withOfficeId((String) profileParser.get("OFFICE_ID")) + .withName((String) profileParser.get("LOCATION_ID")) + .build(); + TimeSeriesProfileParser timeSeriesProfileParser; + if (timeField != null) { + timeSeriesProfileParser = new TimeSeriesProfileParserIndexed.Builder() + .withFieldDelimiter(fieldDelimiter.toCharArray()[0]) + .withTimeField(timeField) + .withLocationId(locationId) + .withKeyParameter(profileParser.get(KEY_PARAMETER_ID, String.class)) + .withTimeFormat((String) profileParser.get(TIME_FORMAT)) + .withTimeZone((String) profileParser.get(TIME_ZONE)) + .withRecordDelimiter(recordDelimiter.toCharArray()[0]) + .withParameterInfoList(parameterInfoList) + .build(); + timeSeriesProfileParserList.add(timeSeriesProfileParser); + } else if (timeStartCol != null && timeEndCol != null) { + timeSeriesProfileParser = new TimeSeriesProfileParserColumnar.Builder() + .withTimeStartColumn(timeStartCol) + .withTimeEndColumn(timeEndCol) + .withLocationId(locationId) + .withKeyParameter((String) profileParser.get(KEY_PARAMETER_ID)) + .withTimeFormat((String) profileParser.get(TIME_FORMAT)) + .withTimeZone((String) profileParser.get(TIME_ZONE)) + .withRecordDelimiter(recordDelimiter.toCharArray()[0]) + .withParameterInfoList(parameterInfoList) + .build(); + timeSeriesProfileParserList.add(timeSeriesProfileParser); + } + + } + return timeSeriesProfileParserList; + }); + } + + + public void copyTimeSeriesProfileParser(String locationId, String parameterId, String officeId, String destinationLocation) { + connection(dsl, conn -> + CWMS_TS_PROFILE_PACKAGE.call_COPY_TS_PROFILE_PARSER(DSL.using(conn).configuration(), locationId, parameterId, destinationLocation, + "F", officeId)); + } + + public void deleteTimeSeriesProfileParser(String locationId, String parameterId, String officeId) { + connection(dsl, conn -> + CWMS_TS_PROFILE_PACKAGE.call_DELETE_TS_PROFILE_PARSER(DSL.using(conn).configuration(), locationId, + parameterId, officeId) + ); + } + + private TimeSeriesProfileParser map(RETRIEVE_TS_PROFILE_PARSER timeSeriesProfileParser, String locationName, String keyParameter, String officeId) { + String info = timeSeriesProfileParser.getP_PARAMETER_INFO(); + List parameterInfo = getParameterInfoList(info, timeSeriesProfileParser.getP_RECORD_DELIMITER(), + timeSeriesProfileParser.getP_FIELD_DELIMITER()); + CwmsId locationId = new CwmsId.Builder().withOfficeId(officeId).withName(locationName).build(); + return new TimeSeriesProfileParser.Builder() + .withLocationId(locationId) // .withTimeField(timeSeriesProfileParser.getP_TIME_FIELD()) - .withTimeZone(timeSeriesProfileParser.getP_TIME_ZONE()) - .withTimeFormat(timeSeriesProfileParser.getP_TIME_FORMAT()) - .withKeyParameter(keyParameter) + .withTimeZone(timeSeriesProfileParser.getP_TIME_ZONE()) + .withTimeFormat(timeSeriesProfileParser.getP_TIME_FORMAT()) + .withKeyParameter(keyParameter) // .withFieldDelimiter(timeSeriesProfileParser.getP_FIELD_DELIMITER().toCharArray()[0]) - .withRecordDelimiter(timeSeriesProfileParser.getP_RECORD_DELIMITER().toCharArray()[0]) - .withTimeInTwoFields(false) - .withParameterInfoList(parameterInfo) - .build(); - } + .withRecordDelimiter(timeSeriesProfileParser.getP_RECORD_DELIMITER().toCharArray()[0]) + .withTimeInTwoFields(false) + .withParameterInfoList(parameterInfo) + .build(); + } } diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDaoIT.java b/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDaoIT.java index 4b6e68759..795e69332 100644 --- a/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDaoIT.java +++ b/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileInstanceDaoIT.java @@ -172,7 +172,7 @@ void testStoreTimeSeriesProfileInstanceWithDataBlockColumnar() throws SQLExcepti @Test - void testRetrieveTimeSeriesProfileInstances() throws SQLException { + void testCatalogTimeSeriesProfileInstances() throws SQLException { Instant versionDate = Instant.parse("2024-07-09T12:00:00.00Z"); String officeId = "LRL"; String location = "Glensboro"; @@ -183,8 +183,6 @@ void testRetrieveTimeSeriesProfileInstances() throws SQLException { String locationMask = "*"; String parameterMask = "*"; String versionMask = "*"; - Instant startDate = Instant.parse("2020-07-09T12:00:00.00Z"); - Instant endDate = Instant.parse("2025-07-09T12:00:00.00Z"); String timeZone = "UTC"; Instant firstDate = Instant.parse("2024-07-09T19:00:11.00Z"); Instant[] dateTimeArray = {Instant.parse("2024-07-09T19:00:11.00Z"), Instant.parse("2024-07-09T20:00:22.00Z")}; @@ -201,7 +199,7 @@ void testRetrieveTimeSeriesProfileInstances() throws SQLException { TimeSeriesProfileInstanceDao timeSeriesProfileInstanceDao = new TimeSeriesProfileInstanceDao(context); // test retrieveTimeSeriesProfileInstances List result = timeSeriesProfileInstanceDao.catalogTimeSeriesProfileInstances(officeIdMask, locationMask, parameterMask, - versionMask, startDate, endDate, timeZone); + versionMask); // cleanup: delete the time series profile instances we created boolean overrideProtection = false; @@ -209,6 +207,7 @@ void testRetrieveTimeSeriesProfileInstances() throws SQLException { timeSeriesProfileInstanceDao.deleteTimeSeriesProfileInstance(timeSeriesProfileInstance.getTimeSeriesProfile().getLocationId(), timeSeriesProfileInstance.getTimeSeriesProfile().getKeyParameter(), timeSeriesProfileInstance.getVersion(), firstDate, timeZone, overrideProtection, timeSeriesProfileInstance.getVersionDate()); + break; } // check if we retrieve all the instances we stored assertEquals(versions.length, result.size(), CwmsDataApiSetupCallback.getWebUser()); @@ -223,7 +222,7 @@ void testRetrieveTimeSeriesProfileInstance() throws SQLException { String[] keyParameter = {"Depth", "m"}; String[] parameter1 = {"Pres", "psi"}; String unit = "bar,m"; - Instant startTime = Instant.parse("2023-07-09T19:00:11.00Z"); + Instant startTime = Instant.parse("2024-07-09T19:00:11.00Z"); Instant endTime = Instant.parse("2025-01-01T19:00:22.00Z"); String timeZone = "UTC"; String startInclusive = "T"; @@ -320,15 +319,15 @@ void testDeleteTimeSeriesProfileInstance() throws SQLException { } // instance does not exist anymore assertNull(timeSeriesProfileInstance); - - // cleanup the timeseries - try { - CwmsDbTs tsDao = CwmsDbServiceLookup.buildCwmsDb(CwmsDbTs.class, c); - tsDao.deleteAll(c, officeId, locationName + "." + keyParameter[0] + ".Inst.0.0." + version); - tsDao.deleteAll(c, officeId, locationName + "." + parameter1[0] + ".Inst.0.0." + version); - } catch (SQLException e) { - throw(new RuntimeException(e)); - } +// +// // cleanup the timeseries +// try { +// CwmsDbTs tsDao = CwmsDbServiceLookup.buildCwmsDb(CwmsDbTs.class, c); +// tsDao.deleteAll(c, officeId, locationName + "." + keyParameter[0] + ".Inst.0.0." + version); +// tsDao.deleteAll(c, officeId, locationName + "." + parameter1[0] + ".Inst.0.0." + version); +// } catch (SQLException e) { +// throw(new RuntimeException(e)); +// } }, CwmsDataApiSetupCallback.getWebUser()); } @@ -424,10 +423,15 @@ private TimeSeriesProfileInstance retrieveTimeSeriesProfileInstance(String offic .withOfficeId(officeId) .withName(locationName) .build(); - result[0] = timeSeriesProfileInstanceDao.retrieveTimeSeriesProfileInstance(location, keyParameter, version, + try { + result[0] = timeSeriesProfileInstanceDao.retrieveTimeSeriesProfileInstance(location, keyParameter, version, unit, startTime, endTime, timeZone, startInclusive ? "T" : "F", endInclusive ? "T" : "F", previous ? "T" : "F", next ? "T" : "F", versionDate, maxVersion ? "T" : "F"); - + } + catch(cwms.cda.api.errors.NotFoundException ex) + { + // return null for not found + } }, CwmsDataApiSetupCallback.getWebUser()); return result[0]; } diff --git a/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDaoIT.java b/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDaoIT.java index fe83ada8e..e77acc576 100644 --- a/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDaoIT.java +++ b/cwms-data-api/src/test/java/cwms/cda/data/dao/timeseriesprofile/TimeSeriesProfileParserDaoIT.java @@ -93,6 +93,47 @@ void testStoreAndDelete() throws SQLException { }, CwmsDataApiSetupCallback.getWebUser()); } + @Test + void testCatalogTimeSeriesProfileInclusive() throws SQLException { + CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink(); + String officeId = "LRL"; + String locationName = "Glensboro"; + String[] parameters = {"Depth", "Temp-Water"}; + databaseLink.connection(c -> { + DSLContext context = getDslContext(c, databaseLink.getOfficeId()); + + TimeSeriesProfileDao timeSeriesProfileDao = new TimeSeriesProfileDao(context); + + List timeSeriesProfileList = new ArrayList<>(); + for(String parameter : parameters) { + TimeSeriesProfile timeSeriesProfile = buildTestTimeSeriesProfile(officeId, locationName, parameter, parameters); + timeSeriesProfileDao.storeTimeSeriesProfile(timeSeriesProfile, false); + timeSeriesProfileList.add(timeSeriesProfile); + } + TimeSeriesProfileParserDao timeSeriesProfileParserDao = new TimeSeriesProfileParserDao(context); + + + for(String parameter : parameters) { + TimeSeriesProfileParserIndexed timeSeriesProfileParser = buildTestTimeSeriesProfileParserIndexed(officeId, locationName, parameter); + timeSeriesProfileParserDao.storeTimeSeriesProfileParser(timeSeriesProfileParser, false); + } + + List profileParserList = timeSeriesProfileParserDao.catalogTimeSeriesProfileParsers("*", "*", "*",true); + for (TimeSeriesProfileParser profileParser : profileParserList) { + timeSeriesProfileParserDao.deleteTimeSeriesProfileParser(profileParser.getLocationId().getName(), profileParser.getKeyParameter(), profileParser.getLocationId().getOfficeId()); + } + + for(TimeSeriesProfile timeSeriesProfile : timeSeriesProfileList) { + timeSeriesProfileDao.deleteTimeSeriesProfile(timeSeriesProfile.getLocationId().getName(), timeSeriesProfile.getKeyParameter(), + timeSeriesProfile.getLocationId().getOfficeId()); + } + + assertEquals(2, profileParserList.size()); + assertEquals(2, profileParserList.get(0).getParameterInfoList().size() ); + assertEquals(2, profileParserList.get(1).getParameterInfoList().size() ); + }, CwmsDataApiSetupCallback.getWebUser()); + + } @Test void testStoreAndRetrieveMultiple() throws SQLException { CwmsDatabaseContainer databaseLink = CwmsDataApiSetupCallback.getDatabaseLink();