Skip to content

Commit

Permalink
Updated based on Adam's feedback. Added serializer test on file, clea…
Browse files Browse the repository at this point in the history
…ned up DTO
  • Loading branch information
zack-rma committed Dec 19, 2024
1 parent 8a7c600 commit 9ce5604
Show file tree
Hide file tree
Showing 9 changed files with 124 additions and 118 deletions.
1 change: 1 addition & 0 deletions cwms-data-api/src/main/java/cwms/cda/api/Controllers.java
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ public final class Controllers {
public static final String UNIT_SYSTEM = "unit-system";

public static final String TIMESERIES_CATEGORY_LIKE = "timeseries-category-like";
public static final String INCLUDE_ENTRY_DATE = "include-entry-date";

public static final String LOCATION_CATEGORY_LIKE = "location-category-like";
public static final String LOCATION_GROUP_LIKE = "location-group-like";
Expand Down
52 changes: 11 additions & 41 deletions cwms-data-api/src/main/java/cwms/cda/api/TimeSeriesController.java
Original file line number Diff line number Diff line change
@@ -1,45 +1,7 @@
package cwms.cda.api;

import static com.codahale.metrics.MetricRegistry.name;
import static cwms.cda.api.Controllers.BEGIN;
import static cwms.cda.api.Controllers.CREATE;
import static cwms.cda.api.Controllers.CREATE_AS_LRTS;
import static cwms.cda.api.Controllers.CURSOR;
import static cwms.cda.api.Controllers.DATE_FORMAT;
import static cwms.cda.api.Controllers.DATUM;
import static cwms.cda.api.Controllers.DELETE;
import static cwms.cda.api.Controllers.END;
import static cwms.cda.api.Controllers.END_TIME_INCLUSIVE;
import static cwms.cda.api.Controllers.EXAMPLE_DATE;
import static cwms.cda.api.Controllers.FORMAT;
import static cwms.cda.api.Controllers.GET_ALL;
import static cwms.cda.api.Controllers.GET_ONE;
import static cwms.cda.api.Controllers.MAX_VERSION;
import static cwms.cda.api.Controllers.NAME;
import static cwms.cda.api.Controllers.NOT_SUPPORTED_YET;
import static cwms.cda.api.Controllers.OFFICE;
import static cwms.cda.api.Controllers.OVERRIDE_PROTECTION;
import static cwms.cda.api.Controllers.PAGE;
import static cwms.cda.api.Controllers.PAGE_SIZE;
import static cwms.cda.api.Controllers.RESULTS;
import static cwms.cda.api.Controllers.SIZE;
import static cwms.cda.api.Controllers.START_TIME_INCLUSIVE;
import static cwms.cda.api.Controllers.STATUS_200;
import static cwms.cda.api.Controllers.STATUS_400;
import static cwms.cda.api.Controllers.STATUS_404;
import static cwms.cda.api.Controllers.STATUS_501;
import static cwms.cda.api.Controllers.STORE_RULE;
import static cwms.cda.api.Controllers.TIMESERIES;
import static cwms.cda.api.Controllers.TIMEZONE;
import static cwms.cda.api.Controllers.UNIT;
import static cwms.cda.api.Controllers.UPDATE;
import static cwms.cda.api.Controllers.VERSION;
import static cwms.cda.api.Controllers.VERSION_DATE;
import static cwms.cda.api.Controllers.addDeprecatedContentTypeWarning;
import static cwms.cda.api.Controllers.queryParamAsClass;
import static cwms.cda.api.Controllers.queryParamAsZdt;
import static cwms.cda.api.Controllers.requiredParam;
import static cwms.cda.api.Controllers.requiredZdt;
import static cwms.cda.api.Controllers.*;

import com.codahale.metrics.Histogram;
import com.codahale.metrics.MetricRegistry;
Expand All @@ -53,6 +15,7 @@
import cwms.cda.data.dao.TimeSeriesDaoImpl;
import cwms.cda.data.dao.TimeSeriesDeleteOptions;
import cwms.cda.data.dto.TimeSeries;
import cwms.cda.data.dto.TimeSeriesWithDataEntryDate;
import cwms.cda.formatters.ContentType;
import cwms.cda.formatters.Formats;
import cwms.cda.helpers.DateUtils;
Expand Down Expand Up @@ -83,7 +46,6 @@

public class TimeSeriesController implements CrudHandler {
private static final Logger logger = Logger.getLogger(TimeSeriesController.class.getName());
private static final String INCLUDE_ENTRY_DATE = "include-entry-date";
public static final String TAG = "TimeSeries";
public static final String STORE_RULE_DESC = "The business rule to use "
+ "when merging the incoming with existing data\n"
Expand Down Expand Up @@ -201,6 +163,9 @@ public void create(@NotNull Context ctx) {

TimeSeriesDao dao = getTimeSeriesDao(dsl);
TimeSeries timeSeries = deserializeTimeSeries(ctx);
if (timeSeries instanceof TimeSeriesWithDataEntryDate) {
throw new IllegalArgumentException("Data Entry Date is not allowed in the request when storing data");
}
dao.create(timeSeries, createAsLrts, storeRule, overrideProtection);
ctx.status(HttpServletResponse.SC_OK);
} catch (DataAccessException ex) {
Expand Down Expand Up @@ -382,7 +347,9 @@ public void delete(@NotNull Context ctx, @NotNull String timeseries) {
+ "\n* `wml2` (only if name field is specified)"
+ "\n* `json` (default)"),
@OpenApiParam(name = INCLUDE_ENTRY_DATE, type = Boolean.class, description = "Specifies "
+ "whether to include the data entry date in the response. Default is false."),
+ "whether to include the data entry date of each value in the response. Including the data entry "
+ "date will increase the size of the array containing each data value from three to four."
+ " Default is false."),
@OpenApiParam(name = PAGE, description = "This end point can return large amounts "
+ "of data as a series of pages. This parameter is used to describes the "
+ "current location in the response stream. This is an opaque "
Expand Down Expand Up @@ -566,6 +533,9 @@ public void update(@NotNull Context ctx, @NotNull String id) {

TimeSeriesDao dao = getTimeSeriesDao(dsl);
TimeSeries timeSeries = deserializeTimeSeries(ctx);
if (timeSeries instanceof TimeSeriesWithDataEntryDate) {
throw new IllegalArgumentException("Data Entry Date is not allowed in the request when storing data");
}

boolean createAsLrts = ctx.queryParamAsClass(CREATE_AS_LRTS, Boolean.class)
.getOrDefault(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import cwms.cda.data.dto.RecentValue;
import cwms.cda.data.dto.TimeSeries;
import cwms.cda.data.dto.TimeSeriesExtents;
import cwms.cda.data.dto.TimeSeriesWithDate;
import cwms.cda.data.dto.TimeSeriesWithDataEntryDate;
import cwms.cda.data.dto.Tsv;
import cwms.cda.data.dto.TsvDqu;
import cwms.cda.data.dto.TsvId;
Expand Down Expand Up @@ -353,7 +353,7 @@ public TimeSeries getTimeseries(String page, int pageSize, String names, String
versionDate, finalDateVersionType
);
} else {
return new TimeSeriesWithDate(recordCursor, recordPageSize, tsMetadata.getValue("TOTAL",
return new TimeSeriesWithDataEntryDate(recordCursor, recordPageSize, tsMetadata.getValue("TOTAL",
Integer.class), tsMetadata.getValue("NAME", String.class),
tsMetadata.getValue("office_id", String.class),
beginTime, endTime, tsMetadata.getValue("units", String.class),
Expand All @@ -368,7 +368,7 @@ public TimeSeries getTimeseries(String page, int pageSize, String names, String
});

if (includeEntryDate) {
timeseries = new TimeSeriesWithDate(timeseries);
timeseries = new TimeSeriesWithDataEntryDate(timeseries);
}

// Now we're going to call the retrieve_ts_out_tab function to get the data and build an
Expand Down Expand Up @@ -460,7 +460,7 @@ public TimeSeries getTimeseries(String page, int pageSize, String names, String

if (includeEntryDate) {
logger.fine(() -> query2.getSQL(ParamType.INLINED));
final TimeSeriesWithDate timeSeries = new TimeSeriesWithDate(timeseries);
final TimeSeriesWithDataEntryDate timeSeries = new TimeSeriesWithDataEntryDate(timeseries);
query2.forEach(tsRecord -> timeSeries.addValue(
tsRecord.getValue(dateTimeCol),
tsRecord.getValue(valueCol),
Expand Down
12 changes: 10 additions & 2 deletions cwms-data-api/src/main/java/cwms/cda/data/dto/TimeSeries.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ public class TimeSeries extends CwmsDTOPaginated {

@ArraySchema(
schema = @Schema(
description = "List of retrieved time-series values",
description = "List of retrieved time-series values. Contains [dateTime, value, qualityCode]. "
+ "Refer to the value-columns property for more information.",
implementation = Record.class
)
)
Expand Down Expand Up @@ -192,7 +193,14 @@ public VersionType getDateVersionType() {
}

@JsonProperty(value = "value-columns")
@Schema(name = "value-columns", accessMode = AccessMode.READ_ONLY)
@Schema(name = "value-columns",
description = "The columns of the time-series data array returned, this property is used to describe "
+ "the data structure of the records array. Contains [name, ordinal, datatype]. "
+ "Name corresponds to the variable described by the data, "
+ "ordinal is the order of the column in the list returned (starting at index 1), "
+ "and datatype is the class name of the data type for the variable. Since the records array "
+ "can be of variable length, the column index value is used to identify the data in the array.",
accessMode = AccessMode.READ_ONLY)
public List<Column> getValueColumnsJSON() {
return getColumnDescriptor();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,70 +49,56 @@
@JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class)
@FormattableWith(contentType = Formats.JSONV2, formatter = JsonV2.class, aliases = {Formats.DEFAULT, Formats.JSON})
@FormattableWith(contentType = Formats.XMLV2, formatter = XMLv2.class, aliases = {Formats.XML})
public final class TimeSeriesWithDate extends TimeSeries {
public final class TimeSeriesWithDataEntryDate extends TimeSeries {

private List<TimeSeriesWithDate.Record> values;

// list of TimeSeriesWithDate.Record, uses raw to avoid typing errors
@Override
public List getValues() {
return values;
}

TimeSeriesWithDate() {
// Default constructor for Jackson Deserialization
public TimeSeriesWithDataEntryDate() {
super();
values = new ArrayList<>();
valuesWithEntryDate = new ArrayList<>();
}

public TimeSeriesWithDate(TimeSeries timeSeries) {
public TimeSeriesWithDataEntryDate(TimeSeries timeSeries) {
this(timeSeries.getPage(), timeSeries.getPageSize(), timeSeries.getTotal(), timeSeries.getName(),
timeSeries.getOfficeId(), timeSeries.getBegin(), timeSeries.getEnd(), timeSeries.getUnits(),
timeSeries.getInterval(), timeSeries.getVerticalDatumInfo(), timeSeries.getIntervalOffset(),
timeSeries.getTimeZone(), timeSeries.getVersionDate(), timeSeries.getDateVersionType());
values = new ArrayList<>();
}

public TimeSeriesWithDate(String page, int pageSize, Integer total, String name, String officeId,
ZonedDateTime begin, ZonedDateTime end, String units, Duration interval) {
this(page, pageSize, total, name, officeId, begin, end, units, interval, null, null,
null, null, null);
values = new ArrayList<>();
valuesWithEntryDate = new ArrayList<>();
}

public TimeSeriesWithDate(String page, int pageSize, Integer total, String name, String officeId, ZonedDateTime begin,
ZonedDateTime end, String units, Duration interval, VerticalDatumInfo info, ZonedDateTime versionDate,
VersionType dateVersionType) {
this(page, pageSize, total, name, officeId, begin, end, units, interval, info, null,
null, versionDate, dateVersionType);
values = new ArrayList<>();
}

public TimeSeriesWithDate(String page, int pageSize, Integer total, String name, String officeId, ZonedDateTime begin,
public TimeSeriesWithDataEntryDate(String page, int pageSize, Integer total, String name, String officeId, ZonedDateTime begin,
ZonedDateTime end, String units, Duration interval, VerticalDatumInfo info, Long intervalOffset,
String timeZone, ZonedDateTime versionDate, VersionType dateVersionType) {
super(page, pageSize, total, name, officeId, begin, end, units, interval, info, intervalOffset,
timeZone, versionDate, dateVersionType);
values = new ArrayList<>();
valuesWithEntryDate = new ArrayList<>();
}

@JsonProperty(value = "values")
private List<TimeSeriesWithDataEntryDate.Record> valuesWithEntryDate;

@Override
public List<TimeSeries.Record> getValues() {
return new ArrayList<>(valuesWithEntryDate);
}

public void addValue(Timestamp dateTime, Double value, int qualityCode, Timestamp dataEntryDate) {
// Set the current page, if not set
if ((page == null || page.isEmpty()) && (values == null || values.isEmpty())) {
if ((page == null || page.isEmpty()) && (valuesWithEntryDate == null || valuesWithEntryDate.isEmpty())) {
page = encodeCursor(String.format("%d", dateTime.getTime()), pageSize, total);
}
if (pageSize > 0 && values.size() == pageSize) {
if (pageSize > 0 && valuesWithEntryDate.size() == pageSize) {
nextPage = encodeCursor(String.format("%d", dateTime.toInstant().toEpochMilli()), pageSize, total);
} else {
values.add(new Record(dateTime, value, qualityCode, dataEntryDate));
valuesWithEntryDate.add(new Record(dateTime, value, qualityCode, dataEntryDate));
}
}

@Override
public List<Column> getValueColumnsJSON() {
return getColumnDescriptor();
return getColumnDescriptorWithEntryDate();
}

private List<Column> getColumnDescriptor() {
private List<Column> getColumnDescriptorWithEntryDate() {
List<Column> columns = new ArrayList<>();
for (Field f: TimeSeries.Record.class.getDeclaredFields()) {
JsonProperty field = f.getAnnotation(JsonProperty.class);
Expand All @@ -138,7 +124,7 @@ public static final class Record extends TimeSeries.Record {
@JsonProperty(value = "data-entry-date", index = 3)
@Schema(implementation = Long.class, description = "Milliseconds since 1970-01-01 (Unix Epoch), always UTC")
@JsonInclude(JsonInclude.Include.NON_DEFAULT)
Timestamp dataEntryDate;
private Timestamp dataEntryDate;

// Default constructor for Jackson Deserialization
public Record() {
Expand Down
Loading

0 comments on commit 9ce5604

Please sign in to comment.