-
Notifications
You must be signed in to change notification settings - Fork 17
Fixes #634 - Implemented data entry date option for TS data retrieval #927
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
cwms-data-api/src/main/java/cwms/cda/api/TimeSeriesController.java
Outdated
Show resolved
Hide resolved
@@ -248,6 +256,11 @@ public static class Record { | |||
@JsonProperty(value = "quality-code", index = 2) | |||
int qualityCode; | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might be better as a sub class. I know that adds some complex but eventually we may also want to include the version date and text notes that may be attached and that would be a lot of logic in this one class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to a subclass. I added a custom deserializer to handle the different classes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, so I said this, Adam said this, but after reading the code and our other discussions above timeseries does it make more sense to just make TimeSeries more generic?
e.g.
A builder where you manually add column names, index, and type, and and functions in the row builder to set such?
something like
withColumn(int index, String name, String description, Class<T> type) {
"logic"
}
... Record:
<T> setColumn(int index, T value, Class<T> type) {
"logic"
}
Or something like that, it would prevent the need in TimeSeriesDaoImpl have two different loops doing almost 90% the same work. just a check for "I have this column requested, let's also add it."
Basically instead of hard coding the columns at all (okay, maybe time... is a time series) , the user of the given TimeSeries object (after set by builder) can define them at run-time.
Sorry, I know you did a lot here, that just came to me now looking through the current PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't want Zach to do it in this PR, already been too long, but does anyone think the above idea is crazy?
@jbkolze what are your thoughts on this? At least how it's done. Some appears it may be a breaking change which we want to avoid. |
cwms-data-api/src/main/java/cwms/cda/data/dao/LocationLevelsDaoImpl.java
Outdated
Show resolved
Hide resolved
Conceptually, I don't personally have any qualms with it. You had mentioned in the typing discussion that you all were trying to leave flexibility for dynamically adjusting the time series values array, and this seems like a prime use case for that. That being said, I am a little concerned about the part you marked as a breaking change. I don't know the CDA source that well, but is this indicating that the response would include a fourth null value even if the include_entry_date is false? Because that definitely would not be ideal -- we've written a lot of CDA code already (and I think other districts have as well) that would have to be updated. Not as big of a deal if an API version were included in the path ( My understanding from previous conversations is that you'd get the normal 3-value array if this were set to false, but receive a 4-value array if include_entry_date is true. And the "value-columns" object would be updated to match. That'd be my "ideal" implementation. |
You are correct that setting the include_entry_date parameter to true would result in a four-value array, whereas setting it to false would return a three-value array. Your "ideal" implementation is what I was aiming for to retain backwards compatibility and avoid breaking any of the other endpoints that rely on the TimeSeries implementation. |
cwms-data-api/src/main/java/cwms/cda/formatters/json/adapters/TimeSeriesRecordDeserializer.java
Outdated
Show resolved
Hide resolved
cwms-data-api/src/main/java/cwms/cda/formatters/json/adapters/TimeSeriesRecordDeserializer.java
Outdated
Show resolved
Hide resolved
cwms-data-api/src/main/java/cwms/cda/formatters/json/adapters/TimeSeriesRecordDeserializer.java
Outdated
Show resolved
Hide resolved
cwms-data-api/src/main/java/cwms/cda/data/dao/LocationLevelsDaoImpl.java
Outdated
Show resolved
Hide resolved
That is correct for the location indicated, which is location levels backed by a time series. I don't know how much it would affect what you're currently using, but it's definitely not ideal. At the least it definitely shouldn't be null, may as well provide the data, but seems like a parameter should be added to match on the location level end point. But it sounds like your on the same page with Adam about the shape being already explicitly flexible so I'm okay with that section now; not "ideal", but what is, definitely something to better document though. |
}); | ||
logger.fine(() -> query2.getSQL(ParamType.INLINED)); | ||
final TimeSeriesWithDate timeSeries = new TimeSeriesWithDate(timeseries); | ||
query2.forEach(tsRecord -> timeSeries.addValue( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we don't need to solve this now, but definitely before we add requesting any text notes as well. There has to be a better way to handle this with the builders.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given the previous logic above, does this need a new or just a cast so you can get the desired methods?
if (pageSize != 0) { | ||
if (versionDate != null) { | ||
whereCond = whereCond.and(AV_TSV_DQU.AV_TSV_DQU.VERSION_DATE.eq(versionDate == null ? null : |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this logic handle max version? or will AV_TSV_DQU always return every version? or only the specifically requested version?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated logic to handle max version in line with previous implementation. If the version date is not specified, the max version will be set to true and the most recent version date will be used for retrieval. This does prevent retrieval of multiple versions in one call, so that could be a problem if that is a desired feature.
@@ -248,6 +256,11 @@ public static class Record { | |||
@JsonProperty(value = "quality-code", index = 2) | |||
int qualityCode; | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, so I said this, Adam said this, but after reading the code and our other discussions above timeseries does it make more sense to just make TimeSeries more generic?
e.g.
A builder where you manually add column names, index, and type, and and functions in the row builder to set such?
something like
withColumn(int index, String name, String description, Class<T> type) {
"logic"
}
... Record:
<T> setColumn(int index, T value, Class<T> type) {
"logic"
}
Or something like that, it would prevent the need in TimeSeriesDaoImpl have two different loops doing almost 90% the same work. just a check for "I have this column requested, let's also add it."
Basically instead of hard coding the columns at all (okay, maybe time... is a time series) , the user of the given TimeSeries object (after set by builder) can define them at run-time.
Sorry, I know you did a lot here, that just came to me now looking through the current PR.
Build errors appear to be unrelated to these changes |
cwms-data-api/src/main/java/cwms/cda/api/TimeSeriesController.java
Outdated
Show resolved
Hide resolved
cwms-data-api/src/main/java/cwms/cda/data/dto/TimeSeriesWithDate.java
Outdated
Show resolved
Hide resolved
cwms-data-api/src/main/java/cwms/cda/data/dto/TimeSeriesWithDate.java
Outdated
Show resolved
Hide resolved
@FormattableWith(contentType = Formats.XMLV2, formatter = XMLv2.class, aliases = {Formats.XML}) | ||
public final class TimeSeriesWithDate extends TimeSeries { | ||
|
||
private List<TimeSeriesWithDate.Record> values; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be able to reuse the parent's values since there is inheritance
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needed to add the local variables to get the typing correct. Removing it causes loss of type within the List, which drops the data entry date value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
then you shouldn't inherit from TimeSeries as the class structure then has two sets of data
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This lends itself to the other suggestion I made with the more generic structure. Though I think that would be too much for this PR.
The Time Series class Daniel created is already generic enough (in concept at least) to handle adding additional columns.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cleaned up the duplicate value list data from the subclass. Required adding custom deserializer back to properly handle the subtypes of TimeSeries.Record.
cwms-data-api/src/main/java/cwms/cda/data/dto/TimeSeriesWithDate.java
Outdated
Show resolved
Hide resolved
cwms-data-api/src/test/resources/cwms/cda/api/lrl/1day_offset_version_date.json
Outdated
Show resolved
Hide resolved
cwms-data-api/src/test/java/cwms/cda/data/dao/TimeSeriesDaoTest.java
Outdated
Show resolved
Hide resolved
cwms-data-api/src/test/java/cwms/cda/api/TimeseriesControllerTestIT.java
Show resolved
Hide resolved
cwms-data-api/src/main/java/cwms/cda/api/TimeSeriesController.java
Outdated
Show resolved
Hide resolved
cwms-data-api/src/test/resources/cwms/cda/api/lrl/1day_offset_version_date_roundtrip.json
Outdated
Show resolved
Hide resolved
Build will fail until database schema changes are merged and a new release is available. Changes can be found here: https://bitbucket.hecdev.net/projects/CWMS/repos/cwms_database/pull-requests/412/overview |
Tests are still failing, actions output is still showing schema of "latest-dev" |
7ff531a
to
67bcd17
Compare
what is status? |
The necessary changes to the database were just merged in, we'll need an updated schema to be available before this feature can be finalized. |
…on bug in progress
…dle custom output, adds data entry date support
…e values with data entry date
Added integration tests with data. Fixed unit parameter usage in integration tests
0ac074b
to
c0b2a47
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have some minor nitpicks on formatting.
}); | ||
|
||
if (includeEntryDate) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why are we doing this check if the above would already have returned a TimeSeriesWithDataEntryDate?
Alternatively why have the login within the lambda for data_entry_date if we're goign to change it here?
(I'm not seeing a difference other than the type after new.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remnant from before the above line, perhaps. I've removed it and tested that all works as intended without it.
}); | ||
logger.fine(() -> query2.getSQL(ParamType.INLINED)); | ||
final TimeSeriesWithDate timeSeries = new TimeSeriesWithDate(timeseries); | ||
query2.forEach(tsRecord -> timeSeries.addValue( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given the previous logic above, does this need a new or just a cast so you can get the desired methods?
} | ||
tsvArray.add(new ZTSV_TYPE(value.getDateTime(), dataValue, BigDecimal.valueOf(value.getQualityCode()))); | ||
} | ||
for(TimeSeries.Record value : values) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
incorrect curlies, but otherwise thank you for cleaning up the loop structures and formatting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed brackets
@@ -248,6 +256,11 @@ public static class Record { | |||
@JsonProperty(value = "quality-code", index = 2) | |||
int qualityCode; | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't want Zach to do it in this PR, already been too long, but does anyone think the above idea is crazy?
|
||
public Record(Timestamp dateTime, Double value, int qualityCode) { | ||
super(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... what super?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leftover from when I had created a shared parent class to resolve some serialization issues. Removed
* The data entry date is the date that the data was entered into the database. | ||
*/ | ||
@JsonDeserialize(using = JsonDeserializer.None.class) | ||
public final class TimeSeriesRecordWithDate extends TimeSeries.Record { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This confused me. Should be TimeSeriesRecordWithEntryDate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed as suggested
.header("Authorization",user.toHeaderValue()) | ||
.queryParam("office",officeId) | ||
.queryParam("units","cfs") | ||
.queryParam("unit","cfs") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would seem we should really start using the constants we've defined. (Not a ding, pretty sure we're all guilty of that.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replaced with Controllers constant where applicable
.accept(Formats.JSONV2) | ||
.header("Authorization", user.toHeaderValue()) | ||
.queryParam(Controllers.OFFICE, officeId) | ||
.queryParam(Controllers.UNIT, "CFS") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this is definitely the superior way to set those parameters.
cwms-data-api/src/test/java/cwms/cda/api/TimeseriesControllerTestIT.java
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thank you for updating the formatting within this file while you were at it.
…types of Record class
Fixes #634 - Implements data entry date as option for TimeSeries data retrieval - Serialization bug in progress