Skip to content

Commit da610d6

Browse files
authored
CWMSVUE-755 add "versioned" field to TimeSeriesCatalogEntry (#1679)
this will allow for on-demand loading of versioned rows within a catalog page partially addresses: #779
1 parent 3eaf8e9 commit da610d6

File tree

10 files changed

+192
-27
lines changed

10 files changed

+192
-27
lines changed

cwms-data-api/src/main/java/cwms/cda/api/CatalogController.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ public class CatalogController implements CrudHandler {
4242
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
4343
private static final String TAG = "Catalog";
4444
public static final boolean INCLUDE_EXTENTS_DEFAULT = true;
45+
public static final boolean INCLUDE_VERSIONS_DEFAULT = true;
4546
public static final boolean EXCLUDE_EMPTY_DEFAULT = true;
4647

4748
private final MetricRegistry metrics;
@@ -133,6 +134,13 @@ public void getAll(Context ctx) {
133134
+ "extents. Only valid for TIMESERIES. Note: This parameter is "
134135
+ "unsupported when dataset is Locations."
135136
+ "Default is " + INCLUDE_EXTENTS_DEFAULT + "."),
137+
@OpenApiParam(name = INCLUDE_VERSIONS, type = Boolean.class,
138+
description = "Whether the returned catalog entries should include timeseries "
139+
+ "versions in the extents block. "
140+
+ "Only used when include-extents is enabled, otherwise it is ignored. "
141+
+ "Only valid for TIMESERIES. Note: This parameter is "
142+
+ "unsupported when dataset is Locations."
143+
+ "Default is " + INCLUDE_VERSIONS_DEFAULT + "."),
136144
@OpenApiParam(name = EXCLUDE_EMPTY, type = Boolean.class,
137145
description = "Specifies "
138146
+ "whether Timeseries that have empty extents "
@@ -245,6 +253,8 @@ public void getOne(@NotNull Context ctx, @NotNull String dataSet) {
245253

246254
boolean includeExtents = ctx.queryParamAsClass(INCLUDE_EXTENTS, Boolean.class)
247255
.getOrDefault(INCLUDE_EXTENTS_DEFAULT);
256+
boolean includeVersions = ctx.queryParamAsClass(INCLUDE_VERSIONS, Boolean.class)
257+
.getOrDefault(INCLUDE_VERSIONS_DEFAULT);
248258
boolean excludeExtents = ctx.queryParamAsClass(EXCLUDE_EMPTY, Boolean.class)
249259
.getOrDefault(EXCLUDE_EMPTY_DEFAULT);
250260

@@ -257,6 +267,7 @@ public void getOne(@NotNull Context ctx, @NotNull String dataSet) {
257267
.withTsGroupLike(tsGroupLike)
258268
.withBoundingOfficeLike(boundingOfficeLike)
259269
.withIncludeExtents(includeExtents)
270+
.withIncludeVersions(includeVersions)
260271
.withExcludeEmpty(excludeExtents)
261272
.withLocationKind(locationKind)
262273
.withLocationType(locationType)
@@ -268,7 +279,7 @@ public void getOne(@NotNull Context ctx, @NotNull String dataSet) {
268279
} else if (LOCATIONS.equalsIgnoreCase(valDataSet)) {
269280

270281
warnAboutNotSupported(ctx, new String[]{TIMESERIES_CATEGORY_LIKE,
271-
TIMESERIES_GROUP_LIKE, EXCLUDE_EMPTY, INCLUDE_EXTENTS});
282+
TIMESERIES_GROUP_LIKE, EXCLUDE_EMPTY, INCLUDE_EXTENTS, INCLUDE_VERSIONS});
272283

273284
CatalogRequestParameters parameters = new CatalogRequestParameters.Builder()
274285
.withUnitSystem(unitSystem)

cwms-data-api/src/main/java/cwms/cda/api/Controllers.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ public final class Controllers {
217217
public static final String DESIGNATOR = "designator";
218218
public static final String DESIGNATOR_MASK = "designator-mask";
219219
public static final String INCLUDE_EXTENTS = "include-extents";
220+
public static final String INCLUDE_VERSIONS = "include-versions";
220221
public static final String EXCLUDE_EMPTY = "exclude-empty";
221222
public static final String DEFAULT_VALUE = "default-value";
222223
public static final String CATEGORY = "category";

cwms-data-api/src/main/java/cwms/cda/data/dao/CatalogRequestParameters.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public class CatalogRequestParameters {
1717
private final String tsGroupLike;
1818
private final String boundingOfficeLike;
1919
private final boolean includeExtents;
20+
private final boolean includeVersions;
2021
private final boolean excludeEmpty;
2122
private final String locationKind;
2223
private final String locationType;
@@ -34,6 +35,7 @@ private CatalogRequestParameters(Builder builder) {
3435
this.tsGroupLike = builder.tsGroupLike;
3536
this.boundingOfficeLike = builder.boundingOfficeLike;
3637
this.includeExtents = builder.includeExtents;
38+
this.includeVersions = builder.includeVersions;
3739
this.excludeEmpty = builder.excludeEmpty;
3840
this.locationKind = builder.locationKind;
3941
this.locationType = builder.locationType;
@@ -54,6 +56,10 @@ public boolean isIncludeExtents() {
5456
return includeExtents;
5557
}
5658

59+
public boolean isIncludeVersions() {
60+
return includeVersions;
61+
}
62+
5763
public String getLocCatLike() {
5864
return locCatLike;
5965
}
@@ -112,6 +118,7 @@ public static class Builder {
112118
String tsGroupLike;
113119
String boundingOfficeLike;
114120
boolean includeExtents = false;
121+
boolean includeVersions = false;
115122
private boolean excludeEmpty = true;
116123
String locationKind;
117124
String locationType;
@@ -168,6 +175,11 @@ public Builder withIncludeExtents(boolean includeExtents) {
168175
return this;
169176
}
170177

178+
public Builder withIncludeVersions(boolean includeVersions) {
179+
this.includeVersions = includeVersions;
180+
return this;
181+
}
182+
171183
public Builder withExcludeEmpty(boolean excludeExtents) {
172184
this.excludeEmpty = excludeExtents;
173185
return this;
@@ -210,6 +222,7 @@ public static Builder from(CatalogRequestParameters params) {
210222
.withTsGroupLike(params.tsGroupLike)
211223
.withBoundingOfficeLike(params.boundingOfficeLike)
212224
.withIncludeExtents(params.includeExtents)
225+
.withIncludeVersions(params.includeVersions)
213226
.withExcludeEmpty(params.excludeEmpty)
214227
.withLocationKind(params.locationKind)
215228
.withLocationType(params.locationType)

cwms-data-api/src/main/java/cwms/cda/data/dao/LocationsDaoImpl.java

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -241,19 +241,56 @@ public Location getLocation(String locationName, String unitSystem, String offic
241241

242242
Location retVal;
243243
if (includeAliases) {
244-
List<Record> locs = dslContext.select(asterisk())
245-
.from(AV_LOC2.AV_LOC2)
246-
.leftJoin(AV_LOC_ALIAS)
247-
.on(AV_LOC2.AV_LOC2.BASE_LOCATION_ID.eq(AV_LOC_ALIAS.BASE_LOCATION_ID).and(
248-
AV_LOC2.AV_LOC2.LOCATION_CODE.eq(AV_LOC_ALIAS.LOCATION_CODE.cast(Long.class))))
249-
.where(AV_LOC2.AV_LOC2.DB_OFFICE_ID.eq(officeId.toUpperCase())
250-
.and(AV_LOC2.AV_LOC2.UNIT_SYSTEM.equalIgnoreCase(unitSystem)
251-
.and(AV_LOC2.AV_LOC2.LOCATION_ID.equalIgnoreCase(locationName))))
252-
.fetch();
253-
if (locs.isEmpty()) {
254-
throw new NotFoundException("Location not found for office:" + officeId + " and unit "
255-
+ "system:" + unitSystem + " and id:" + locationName);
256-
}
244+
List<Record> locs = dslContext.select(
245+
AV_LOC2.AV_LOC2.LOCATION_CODE,
246+
AV_LOC2.AV_LOC2.BASE_LOCATION_CODE,
247+
AV_LOC2.AV_LOC2.DB_OFFICE_ID,
248+
AV_LOC2.AV_LOC2.BASE_LOCATION_ID,
249+
AV_LOC2.AV_LOC2.SUB_LOCATION_ID,
250+
AV_LOC2.AV_LOC2.LOCATION_ID,
251+
AV_LOC2.AV_LOC2.LOCATION_TYPE,
252+
AV_LOC2.AV_LOC2.UNIT_SYSTEM,
253+
AV_LOC2.AV_LOC2.ELEVATION,
254+
AV_LOC2.AV_LOC2.UNIT_ID,
255+
AV_LOC2.AV_LOC2.VERTICAL_DATUM,
256+
AV_LOC2.AV_LOC2.LONGITUDE,
257+
AV_LOC2.AV_LOC2.LATITUDE,
258+
AV_LOC2.AV_LOC2.HORIZONTAL_DATUM,
259+
AV_LOC2.AV_LOC2.TIME_ZONE_NAME,
260+
AV_LOC2.AV_LOC2.COUNTY_NAME,
261+
AV_LOC2.AV_LOC2.STATE_INITIAL,
262+
AV_LOC2.AV_LOC2.PUBLIC_NAME,
263+
AV_LOC2.AV_LOC2.LONG_NAME,
264+
AV_LOC2.AV_LOC2.DESCRIPTION,
265+
AV_LOC2.AV_LOC2.BASE_LOC_ACTIVE_FLAG,
266+
AV_LOC2.AV_LOC2.LOC_ACTIVE_FLAG,
267+
AV_LOC2.AV_LOC2.LOCATION_KIND_ID,
268+
AV_LOC2.AV_LOC2.MAP_LABEL,
269+
AV_LOC2.AV_LOC2.PUBLISHED_LATITUDE,
270+
AV_LOC2.AV_LOC2.PUBLISHED_LONGITUDE,
271+
AV_LOC2.AV_LOC2.BOUNDING_OFFICE_ID,
272+
AV_LOC2.AV_LOC2.NATION_ID,
273+
AV_LOC2.AV_LOC2.NEAREST_CITY,
274+
AV_LOC2.AV_LOC2.ACTIVE_FLAG,
275+
AV_LOC2.AV_LOC2.ALIASED_ITEM,
276+
AV_LOC2.AV_LOC2.LOC_ALIAS_CATEGORY,
277+
AV_LOC2.AV_LOC2.LOC_ALIAS_GROUP,
278+
AV_LOC2.AV_LOC2.DB_OFFICE_CODE,
279+
AV_LOC_ALIAS.CATEGORY_ID,
280+
AV_LOC_ALIAS.GROUP_ID,
281+
AV_LOC_ALIAS.ALIAS_ID)
282+
.from(AV_LOC2.AV_LOC2)
283+
.leftJoin(AV_LOC_ALIAS)
284+
.on(AV_LOC2.AV_LOC2.BASE_LOCATION_ID.eq(AV_LOC_ALIAS.BASE_LOCATION_ID).and(
285+
AV_LOC2.AV_LOC2.LOCATION_CODE.eq(AV_LOC_ALIAS.LOCATION_CODE.cast(Long.class))))
286+
.where(AV_LOC2.AV_LOC2.DB_OFFICE_ID.eq(officeId.toUpperCase())
287+
.and(AV_LOC2.AV_LOC2.UNIT_SYSTEM.equalIgnoreCase(unitSystem)
288+
.and(AV_LOC2.AV_LOC2.LOCATION_ID.equalIgnoreCase(locationName))))
289+
.fetch();
290+
if (locs.isEmpty()) {
291+
throw new NotFoundException("Location not found for office:" + officeId + " and unit "
292+
+ "system:" + unitSystem + " and id:" + locationName);
293+
}
257294
retVal = buildLocation(null, locs, true);
258295
} else {
259296
Record loc = dslContext.select(AV_LOC.asterisk())

cwms-data-api/src/main/java/cwms/cda/data/dao/TimeSeriesDaoImpl.java

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import static org.jooq.impl.DSL.select;
2222
import static org.jooq.impl.DSL.selectDistinct;
2323

24+
import org.jooq.SelectOnConditionStep;
2425
import usace.cwms.db.jooq.codegen.tables.AV_CWMS_TS_ID;
2526
import static org.jooq.impl.DSL.table;
2627
import static usace.cwms.db.jooq.codegen.tables.AV_CWMS_TS_ID2.AV_CWMS_TS_ID2;
@@ -676,6 +677,7 @@ public Catalog getTimeSeriesCatalog(String page, int pageSize, CatalogRequestPar
676677
.withTsGroupLike(catPage.getTsGroupLike())
677678
.withBoundingOfficeLike(catPage.getBoundingOfficeLike())
678679
.withIncludeExtents(catPage.isIncludeExtents())
680+
.withIncludeExtents(catPage.isIncludeVersions())
679681
.withExcludeEmpty(catPage.isExcludeEmpty())
680682
.build();
681683
}
@@ -690,7 +692,7 @@ public Catalog getTimeSeriesCatalog(String page, int pageSize, CatalogRequestPar
690692
List<Condition> pagingConditions = buildPagingConditions(cwmsTsIdFields, cursorOffice, cursorTsId);
691693
CommonTableExpression<?> limiter = buildWithClause(cwmsTsIdFields, params, whereConditions, pagingConditions, pageSize, false);
692694
Field<BigDecimal> limiterCode = limiter.field(cwmsTsIdFields.getTsCode());
693-
SelectJoinStep<?> tmpQuery = dsl.with(limiter)
695+
SelectOnConditionStep<?> tmpQuery = dsl.with(limiter)
694696
.select(pageEntryFields)
695697
.from(limiter)
696698
.join(table).on(limiterCode.eq(cwmsTsIdFields.getTsCode()));
@@ -700,9 +702,11 @@ public Catalog getTimeSeriesCatalog(String page, int pageSize, CatalogRequestPar
700702
tmpQuery = tmpQuery.leftOuterJoin(AV_TS_EXTENTS_UTC)
701703
.on(limiterCode
702704
.eq(AV_TS_EXTENTS_UTC.TS_CODE.coerce(limiterCode)));
705+
if(!params.isIncludeVersions()) {
706+
tmpQuery = tmpQuery.and(AV_TS_EXTENTS_UTC.VERSION_TIME.isNull());
707+
}
703708
}
704-
final SelectSeekStep2<?, String, String> overallQuery = tmpQuery
705-
.orderBy(cwmsTsIdFields.getDbOfficeId(),
709+
final SelectSeekStep2<?, String, String> overallQuery = tmpQuery.orderBy(cwmsTsIdFields.getDbOfficeId(),
706710
cwmsTsIdFields.getCwmsTsId());
707711
logger.atFine().log("%s", lazy(() -> overallQuery.getSQL(ParamType.INLINED)));
708712
Result<?> result = overallQuery.fetch();
@@ -721,7 +725,8 @@ public Catalog getTimeSeriesCatalog(String page, int pageSize, CatalogRequestPar
721725
.cwmsTsId(row.get(cwmsTsIdFields.getCwmsTsId()))
722726
.units(row.get(cwmsTsIdFields.getUnitId()))
723727
.interval(row.get(cwmsTsIdFields.getIntervalId()))
724-
.intervalOffset(row.get(cwmsTsIdFields.getIntervalUtcOffset()));
728+
.intervalOffset(row.get(cwmsTsIdFields.getIntervalUtcOffset()))
729+
.versioned(parseBool(row.get(cwmsTsIdFields.getVerionFlag())));
725730

726731
builder.timeZone(row.get("TIME_ZONE_ID", String.class));
727732

@@ -849,6 +854,7 @@ private void updateAliasMapping(Map<String, Set<TimeSeriesAlias>> tsCodeAliasMap
849854
retVal.add(cwmsTsIdFields.getIntervalId());
850855
retVal.add(cwmsTsIdFields.getIntervalUtcOffset());
851856
retVal.add(cwmsTsIdFields.getTimeZoneId());
857+
retVal.add(cwmsTsIdFields.getVerionFlag());
852858
if(cwmsTsIdFields.includesAliases()) {
853859
retVal.add(AV_CWMS_TS_ID2.ALIASED_ITEM);
854860
retVal.add(AV_CWMS_TS_ID2.TS_CODE);
@@ -985,7 +991,6 @@ private Collection<? extends Condition> buildExtentsConditions(CatalogRequestPar
985991
AV_TS_EXTENTS_UTC.LAST_UPDATE.isNotNull())
986992
);
987993
}
988-
989994
return retval;
990995
}
991996

@@ -1727,6 +1732,7 @@ private interface FieldMapping {
17271732
Field<String> getIntervalId();
17281733
Field<BigDecimal> getIntervalUtcOffset();
17291734
Field<String> getTimeZoneId();
1735+
Field<String> getVerionFlag();
17301736
boolean includesAliases();
17311737
}
17321738

@@ -1775,6 +1781,11 @@ public Field<String> getTimeZoneId() {
17751781
public boolean includesAliases() {
17761782
return false;
17771783
}
1784+
1785+
@Override
1786+
public Field<String> getVerionFlag() {
1787+
return AV_CWMS_TS_ID.AV_CWMS_TS_ID.VERSION_FLAG;
1788+
}
17781789
}
17791790

17801791
private static class CwmsTsId2FieldMapping implements FieldMapping {
@@ -1822,6 +1833,11 @@ public Field<String> getTimeZoneId() {
18221833
public boolean includesAliases() {
18231834
return true;
18241835
}
1836+
1837+
@Override
1838+
public Field<String> getVerionFlag() {
1839+
return AV_CWMS_TS_ID2.VERSION_FLAG;
1840+
}
18251841
}
18261842

18271843

cwms-data-api/src/main/java/cwms/cda/data/dto/Catalog.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,14 +76,15 @@ public static class CatalogPage {
7676
private final String tsGroupLike;
7777
private final String boundingOfficeLike;
7878
private final boolean includeExtents;
79+
private final boolean includeVersions;
7980
private final boolean excludeEmpty;
8081
private int total;
8182
private int pageSize;
8283

8384
public CatalogPage(String page) {
8485
String[] parts = CwmsDTOPaginated.decodeCursor(page, CwmsDTOPaginated.delimiter);
8586

86-
if (parts.length != 12) {
87+
if (parts.length != 13) {
8788
throw new IllegalArgumentException("Invalid Catalog Page Provided, please verify "
8889
+ "you are using a page variable from the catalog endpoint");
8990
}
@@ -98,9 +99,10 @@ public CatalogPage(String page) {
9899
tsGroupLike = nullOrVal(parts[6]);
99100
boundingOfficeLike = nullOrVal(parts[7]);
100101
includeExtents = Boolean.parseBoolean(parts[8]);
101-
excludeEmpty = Boolean.parseBoolean(parts[9]);
102-
total = Integer.parseInt(parts[10]);
103-
pageSize = Integer.parseInt(parts[11]);
102+
includeVersions = Boolean.parseBoolean(parts[9]);
103+
excludeEmpty = Boolean.parseBoolean(parts[10]);
104+
total = Integer.parseInt(parts[11]);
105+
pageSize = Integer.parseInt(parts[12]);
104106
}
105107

106108

@@ -118,6 +120,7 @@ public CatalogPage(String curElement, CatalogRequestParameters params) {
118120
this.tsGroupLike = params.getTsGroupLike();
119121
this.boundingOfficeLike = params.getBoundingOfficeLike();
120122
this.includeExtents = params.isIncludeExtents();
123+
this.includeVersions = params.isIncludeVersions();
121124
this.excludeEmpty = params.isExcludeEmpty();
122125
}
123126

@@ -177,6 +180,10 @@ public boolean isIncludeExtents() {
177180
return includeExtents;
178181
}
179182

183+
public boolean isIncludeVersions() {
184+
return includeVersions;
185+
}
186+
180187
public boolean isExcludeEmpty() {
181188
return excludeEmpty;
182189
}
@@ -193,6 +200,7 @@ public String toString() {
193200
+ CwmsDTOPaginated.delimiter + tsGroupLike
194201
+ CwmsDTOPaginated.delimiter + boundingOfficeLike
195202
+ CwmsDTOPaginated.delimiter + includeExtents
203+
+ CwmsDTOPaginated.delimiter + includeVersions
196204
+ CwmsDTOPaginated.delimiter + excludeEmpty
197205
;
198206
}

cwms-data-api/src/main/java/cwms/cda/data/dto/catalog/TimeseriesCatalogEntry.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ public class TimeseriesCatalogEntry extends CatalogEntry {
3434
@JacksonXmlProperty(localName = "alias")
3535
private Collection<TimeSeriesAlias> aliases;
3636

37+
private boolean versioned = false;
38+
3739
public String getName() {
3840
return this.name;
3941
}
@@ -60,6 +62,10 @@ public Collection<TimeSeriesAlias> getAliases() {
6062
return aliases;
6163
}
6264

65+
public boolean isVersioned() {
66+
return versioned;
67+
}
68+
6369
private TimeseriesCatalogEntry() {
6470
super(null);
6571
}
@@ -73,6 +79,7 @@ private TimeseriesCatalogEntry(Builder builder) {
7379
this.timeZone = builder.timeZone;
7480
this.extents = builder.extents;
7581
this.aliases = builder.aliases;
82+
this.versioned = builder.versioned;
7683
}
7784

7885
public String getUnits() {
@@ -100,6 +107,7 @@ public static class Builder {
100107
private ZonedDateTime latestTime;
101108
private List<TimeSeriesExtents> extents = null;
102109
private Collection<TimeSeriesAlias> aliases = null;
110+
private boolean versioned = false;
103111

104112
public Builder officeId(final String office) {
105113
this.office = office;
@@ -162,6 +170,11 @@ public Builder withAliases(final Collection<TimeSeriesAlias> aliases) {
162170
return this;
163171
}
164172

173+
public Builder versioned(boolean versioned) {
174+
this.versioned = versioned;
175+
return this;
176+
}
177+
165178
public TimeseriesCatalogEntry build() {
166179
return new TimeseriesCatalogEntry(this);
167180
}

0 commit comments

Comments
 (0)