Fix pseudo-irregular time series direct reads#1781
Conversation
| String cursor = null; | ||
| Timestamp tsCursor = null; | ||
|
|
||
| if (forceOldLrtsFormatting) { |
There was a problem hiding this comment.
I'm not sure why this cares about the LRTS formatting. There is a function that just tells you:
use JOOQ to call (may already be a helper somewhere in CDA that caches the response.
Basic logic:
- Is LRTS -> build expected times and map it out
- Is not LRTS -> just return the data.
| } | ||
|
|
||
| private static String buildVersionedRowsSql(boolean includeEntryDate) { | ||
| return "select date_time," |
There was a problem hiding this comment.
you can build and return a JOOQ query. keeps the type safety.
NOTE: some of those elements will still need to be text.
NOTE2: since we have to do things in a loop anyways to build the output, it will likely be faster to do the normalization of the quality_code in Java. Moving between plsql and sql does cause a context switch which has some performance concerns.
NOTE3: av_tsv_dqu already handles the unit conversions (that's what the U stands for in dqu), you just put units_id = ... in the where clause. Additional conversions are no-ops, but force the context switch.
Signed-off-by: Charles Graham, SWT <charles.r.graham@usace.army.mil>
|
pseudo-irregular changes
tests
timingsFor this command localhost curl -sS -w '\nstatus=%{http_code} time=%{time_total}s bytes=%{size_download}\n' \
-H 'Accept: application/json;version=2' \
-H 'X-CWMS-LRTS-Formatting: true' \
'http://localhost:8081/cwms-data/timeseries?name=Baldhill_Dam.Flow-Out.Inst.~15Minutes.0.best&office=MVP&unit=cfs&begin=2025-05-01T00:00:00Z&end=2025-06-01T00:00:00Z&page-size=100000'national curl -sS -w '\nstatus=%{http_code} time=%{time_total}s bytes=%{size_download}\n' \
-H 'Accept: application/json;version=2' \
'https://cwms-data.usace.army.mil/cwms-data/timeseries?name=Baldhill_Dam.Flow-Out.Inst.~15Minutes.0.best&office=MVP&unit=cfs&begin=2025-05-01T00:00:00Z&end=2025-06-01T00:00:00Z&page-size=100000'(LRTS header not in Prod yet)
|
Signed-off-by: Charles Graham, SWT <charles.r.graham@usace.army.mil>
MikeNeilson
left a comment
There was a problem hiding this comment.
Note possible conflicts with #1780 depending on which gets merged in first.
| @@ -691,12 +683,12 @@ private TimeSeries getRequestedTimeSeriesDirect(String page, int pageSize, | |||
| private TimeSeries getRequestedTimeSeriesDirectWithOldLrtsFormatting(String page, int pageSize, | |||
There was a problem hiding this comment.
I'm still not sure why the "Old formatting/New Formatting" methods need to exist.
The method of formatting on output and input expectation is set at the session level and is purely visual. Regardless of visual style a time series is either: regular, irregular, psuedo regular (effective irregular for this purpose), or local regular.
That status of the time series determine the 2 modes of data retrieval, none of which has anything to do with with an LRTS timeseries is rendered as "1DayLocal" or "~1Day" for the interval. The database output of the TS time will render that correctly.
It reads like a giant red-herring that detracts from the actual requirement of the read which boils down to the following:
`Do I need to provided predictable time placeholders (regular, local regular) or just render the rows as stored in the database (irregular, psuedoregular).
|
TSV PR was merged in, conflicts need to be fixed. Also see my comments about LRTS methods and usage, feels like something is stuck down a rabbit hole of over thinking and needs to get dug out. Ask database if this TSID is LRTS or REGULAR interval |
Signed-off-by: Charles Graham, SWT <charles.r.graham@usace.army.mil>
3c4c715 to
f362ce4
Compare
Signed-off-by: Charles Graham, SWT <charles.r.graham@usace.army.mil>
Signed-off-by: Charles Graham, SWT <charles.r.graham@usace.army.mil>
f362ce4 to
cea2f38
Compare
Signed-off-by: Charles Graham, SWT <charles.r.graham@usace.army.mil>
MikeNeilson
left a comment
There was a problem hiding this comment.
Still some concerns with the overall logic, but some of that wasn't touched in this PR.
Actual concerns address in specific comments.
Otherwise, looks reasonable, and the tests show expected behavior correctly.
|
|
||
| Timestamp beginTimestamp = Timestamp.from(beginTime.toInstant()); | ||
| Timestamp endTimestamp = Timestamp.from(endTime.toInstant()); | ||
| String beginTimestampText = beginTimestamp.toLocalDateTime().format(ORACLE_DATE_FORMATTER); |
There was a problem hiding this comment.
why are we spending time formatting a timestamp that can be used as-is in the query?
| dateTimeField, DSL.val(beginTimestampText))) | ||
| .and(DSL.condition("{0} <= to_date({1}, 'yyyy-mm-dd\"T\"hh24:mi:ss')", | ||
| dateTimeField, DSL.val(endTimestampText))) | ||
| .and(view.START_DATE.isNull() |
There was a problem hiding this comment.
These (START_DATE and END_DATE) likely can be ignored, the query itself handles the situation better.
However, if they are to be used, their purpose is to bracket which physical at_tsv table is used.
it should be start >= "year of data-01-01" end <= "year+1-01-01", it doesn't need the hours, minutes, or seconds.
| return intervalMinutes != 0L || isLocalRegularInterval(intervalPart); | ||
| private boolean isRegularSeries(long intervalMinutes, long intervalOffset, String intervalPart, boolean isLrts) { | ||
| return intervalOffset != UTC_OFFSET_IRREGULAR | ||
| && (intervalMinutes != 0L || (isLrts && isLocalRegularInterval(intervalPart))); |
There was a problem hiding this comment.
(isLrts && isLocalRegularInterval(intervalPart)
By definition these are either both true, or both false. You've already asked the database if the time series is local regular. We should not be trying to duplicate the logic in CDA.
|
Spoke in CDA biweekly if RMA would also be able to review and ensure nothing was missed. |
Signed-off-by: Charles Graham, SWT <charles.r.graham@usace.army.mil>
Signed-off-by: Charles Graham, SWT <charles.r.graham@usace.army.mil>
Summary
Fixes the time-series direct-read path for pseudo-irregular old-style local-regular IDs such as
*.~15Minutes.*whenX-CWMS-LRTS-Formatting: trueis present.Root cause
The direct-read path could resolve pseudo-irregular old-style IDs through new LRTS formatting, producing local-regular metadata and returning no values. It also treated
~intervals as regular without first honoringinterval_utc_offset = UTC_OFFSET_IRREGULAR, which could incorrectly invoke gap-fill behavior for pseudo-irregular data.Changes
~IDs whose old-format metadata has irregular interval offset.~15Minutesseries and verifies the CDA response matchesretrieve_tsunder the LRTS formatting header.Validation
./gradlew.bat :cwms-data-api:compileJava :cwms-data-api:compileTestJava --no-daemon./gradlew.bat :cwms-data-api:integrationTests --tests "*TimeSeriesDirectReadParityIT.pseudoIrregularReadWithLrtsHeaderMatchesRetrieveTs" "-PCDA_POOL_INIT_SIZE=5" "-PCDA_POOL_MAX_ACTIVE=10" "-PCDA_POOL_MAX_IDLE=5" "-PCDA_POOL_MIN_IDLE=2" --no-daemon./gradlew.bat :cwms-data-api:checkstyleMain :cwms-data-api:checkstyleTest --no-daemonNote: broader
TimeSeriesDirectReadParityITruns were not clean in this local container due fixture/setup issues before the relevant endpoint path was exercised, including Oracle seed partition check failures and a default-data county error.Closes #1745