ATEST-81:
- fixing serialisation - adding tests
This commit is contained in:
@@ -53,7 +53,7 @@ public class DaqRestController {
|
||||
* @throws IOException
|
||||
*/
|
||||
@RequestMapping(value = "/timerange")
|
||||
public void pulseRange(@RequestBody TimeRangeQuery query, HttpServletResponse res) throws IOException {
|
||||
public void timeRange(@RequestBody TimeRangeQuery query, HttpServletResponse res) throws IOException {
|
||||
|
||||
logger.debug("TimeRangeQuery received: {}", query);
|
||||
|
||||
|
||||
@@ -5,13 +5,17 @@ import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import ch.psi.daq.cassandra.reader.Ordering;
|
||||
import ch.psi.daq.hazelcast.query.Aggregation;
|
||||
import ch.psi.daq.hazelcast.query.AggregationType;
|
||||
import ch.psi.daq.hazelcast.query.Query;
|
||||
import ch.psi.daq.hazelcast.query.bin.BinIntervalCalculator;
|
||||
import ch.psi.daq.hazelcast.query.bin.BinningStrategy;
|
||||
import ch.psi.daq.hazelcast.query.bin.BinningStrategyFactory;
|
||||
import ch.psi.daq.hazelcast.query.range.QueryRange;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
@@ -34,7 +38,9 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||
@Type(value = TimeRangeQuery.class, name = "timerange"),
|
||||
})
|
||||
public abstract class AbstractQuery implements Query {
|
||||
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(AbstractQuery.class);
|
||||
|
||||
private List<String> channels;
|
||||
|
||||
private LinkedHashSet<String> fields;
|
||||
@@ -47,39 +53,67 @@ public abstract class AbstractQuery implements Query {
|
||||
|
||||
private Ordering ordering;
|
||||
|
||||
private BinningStrategy binningStrategy;
|
||||
|
||||
private BinningStrategyEnum binningStrategyEnum;
|
||||
|
||||
private QueryRange queryRange;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param isOrderDescending whether to add a 'orderBy' clause into the database query
|
||||
* @param channelIds all the channelIds (channel names) we want to query
|
||||
* @param ordering whether to add a 'orderBy' clause into the database query
|
||||
* @param channels all the channelIds (channel names) we want to query
|
||||
* @param fields the fields (who map to fields in the DB) we are interested in returning to the
|
||||
* client, needs to be in insertion order (hence the {@link LinkedHashSet} type)
|
||||
* @param queryRange TODO
|
||||
*/
|
||||
@JsonCreator
|
||||
public AbstractQuery(
|
||||
// note that those annotations are needed for the polymorphic
|
||||
// mapping to work correctly
|
||||
@JsonProperty(value = "ordering") Ordering ordering,
|
||||
@JsonProperty(value = "channels") List<String> channelIds,
|
||||
@JsonProperty(value = "channels") List<String> channels,
|
||||
@JsonProperty(value = "fields") LinkedHashSet<String> fields,
|
||||
@JsonProperty(value = "binningStrategy") BinningStrategyEnum binningStrategyEnum,
|
||||
@JsonProperty(value = "binDuration") long binDurationOrBinCount,
|
||||
@JsonProperty(value = "aggregateChannels") boolean aggregateChannels,
|
||||
@JsonProperty(value = "aggregationType") AggregationType aggregationType,
|
||||
@JsonProperty(value = "aggregations") List<Aggregation> aggregations) {
|
||||
@JsonProperty(value = "aggregations") List<Aggregation> aggregations,
|
||||
@JsonProperty(value = "queryRange") QueryRange queryRange) {
|
||||
|
||||
this.ordering = ordering;
|
||||
this.aggregateChannels = aggregateChannels;
|
||||
this.aggregationType = aggregationType;
|
||||
this.aggregations = aggregations;
|
||||
this.queryRange = queryRange;
|
||||
|
||||
if (channelIds == null || fields == null) {
|
||||
throw new IllegalArgumentException("sourceIds and/or fields cannot be null.");
|
||||
}
|
||||
Assert.notNull(channelIds, "channel name must not be null.");
|
||||
Assert.notNull(channels, "channel name must not be null.");
|
||||
Assert.notNull(fields, "field, i.e. property, names must not be null.");
|
||||
|
||||
this.channels = channelIds;
|
||||
this.channels = channels;
|
||||
this.fields = fields;
|
||||
this.aggregations = aggregations;
|
||||
|
||||
this.binningStrategyEnum = binningStrategyEnum; // can be null: default then will be BinCountBinningStrategy
|
||||
|
||||
|
||||
if (binningStrategyEnum != null) {
|
||||
switch (binningStrategyEnum) {
|
||||
case bincount:
|
||||
this.binningStrategy = BinningStrategyFactory.getBinningStrategy(getQueryRange(), (int) binDurationOrBinCount);
|
||||
break;
|
||||
case lengthpulse:
|
||||
case lengthtime:
|
||||
this.binningStrategy = BinningStrategyFactory.getBinningStrategy(getQueryRange(), binDurationOrBinCount);
|
||||
break;
|
||||
default:
|
||||
logger.warn("No binning strategy has been set. Selecting BinningStrategyBinCount.");
|
||||
this.binningStrategy = BinningStrategyFactory.getBinningStrategy(getQueryRange(), (int) binDurationOrBinCount);
|
||||
}
|
||||
} else {
|
||||
this.binningStrategy = BinningStrategyFactory.getBinningStrategy(getQueryRange(), (int) binDurationOrBinCount);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@@ -95,7 +129,7 @@ public abstract class AbstractQuery implements Query {
|
||||
public Ordering getOrdering() {
|
||||
return ordering;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@@ -103,17 +137,20 @@ public abstract class AbstractQuery implements Query {
|
||||
public AggregationType getAggregationType() {
|
||||
return aggregationType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BinIntervalCalculator getBinIntervalCalculator() {
|
||||
// TODO
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public boolean isAggregateChannels() {
|
||||
return aggregateChannels;
|
||||
}
|
||||
|
||||
public BinningStrategyEnum getBinningStrategyEnum() {
|
||||
return binningStrategyEnum;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BinningStrategy getBinningStrategy() {
|
||||
return binningStrategy;
|
||||
}
|
||||
|
||||
public LinkedHashSet<String> getFields() {
|
||||
return fields;
|
||||
@@ -123,6 +160,18 @@ public abstract class AbstractQuery implements Query {
|
||||
return aggregations;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public QueryRange getQueryRange() {
|
||||
return queryRange;
|
||||
}
|
||||
|
||||
public void setQueryRange(QueryRange queryRange) {
|
||||
this.queryRange = queryRange;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ReflectionToStringBuilder.reflectionToString(this);
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package ch.psi.daq.rest.queries;
|
||||
|
||||
import ch.psi.daq.hazelcast.query.bin.BinningStrategy;
|
||||
|
||||
/**
|
||||
* Defines the strategies that map to the similarly named {@link BinningStrategy} implementations.
|
||||
* <p>
|
||||
* This enum is used for type-safety and simplicity for the rest interface.
|
||||
*
|
||||
*/
|
||||
public enum BinningStrategyEnum {
|
||||
lengthpulse, lengthtime, bincount
|
||||
}
|
||||
@@ -18,9 +18,6 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
*/
|
||||
public class PulseRangeQuery extends AbstractQuery {
|
||||
|
||||
private long startPulseId;
|
||||
private long endPulseId;
|
||||
|
||||
@JsonCreator
|
||||
public PulseRangeQuery(
|
||||
// note that those annotations are needed for the polymorphic
|
||||
@@ -28,33 +25,16 @@ public class PulseRangeQuery extends AbstractQuery {
|
||||
@JsonProperty(value = "ordering") Ordering ordering,
|
||||
@JsonProperty(value = "channels") List<String> channels,
|
||||
@JsonProperty(value = "fields") LinkedHashSet<String> fields,
|
||||
@JsonProperty(value = "binningStrategy") BinningStrategyEnum binningStrategyEnum,
|
||||
@JsonProperty(value = "binDuration") long binDurationOrBinCount,
|
||||
@JsonProperty(value = "aggregateChannels") boolean aggregateChannels,
|
||||
@JsonProperty(value = "aggregationType") AggregationType aggregationType,
|
||||
@JsonProperty(value = "aggregations") List<Aggregation> aggregations,
|
||||
@JsonProperty(value = "startPulseId") long startPulseId,
|
||||
@JsonProperty(value = "endPulseId") long endPulseId)
|
||||
{
|
||||
@JsonProperty(value = "queryRange") QueryRange queryRange) {
|
||||
|
||||
super(ordering, channels, fields, aggregateChannels, aggregationType, aggregations);
|
||||
super(ordering, channels, fields, binningStrategyEnum, binDurationOrBinCount, aggregateChannels, aggregationType,
|
||||
aggregations, queryRange);
|
||||
|
||||
this.startPulseId = startPulseId;
|
||||
this.endPulseId = endPulseId;
|
||||
}
|
||||
|
||||
public long getStartPulseId() {
|
||||
return startPulseId;
|
||||
}
|
||||
|
||||
public void setStartPulseId(long startPulseId) {
|
||||
this.startPulseId = startPulseId;
|
||||
}
|
||||
|
||||
public long getEndPulseId() {
|
||||
return endPulseId;
|
||||
}
|
||||
|
||||
public void setEndPulseId(long endPulseId) {
|
||||
this.endPulseId = endPulseId;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,10 +45,4 @@ public class PulseRangeQuery extends AbstractQuery {
|
||||
return ToStringBuilder.reflectionToString(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryRange getQueryRange() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,8 +6,6 @@ import java.util.Date;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import org.apache.commons.lang.builder.ToStringBuilder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -23,31 +21,24 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
public class TimeRangeQuery extends AbstractQuery {
|
||||
|
||||
|
||||
private static final String DATE_FORMAT_STRING = "yyyy/MM/dd hh:mm:ss.SSS";
|
||||
public static final String DATE_FORMAT_STRING = "yyyy/MM/dd hh:mm:ss.SSS";
|
||||
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat(DATE_FORMAT_STRING);
|
||||
private static Logger logger = LoggerFactory.getLogger(TimeRangeQuery.class);
|
||||
|
||||
@NotNull
|
||||
private long start;
|
||||
@NotNull
|
||||
private long startNanoOffset;
|
||||
|
||||
@NotNull
|
||||
private long end;
|
||||
@NotNull
|
||||
private long endNanoOffset;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param ordering
|
||||
* @param ordering whether to add a 'orderBy' clause into the database query
|
||||
* @param channelIds all the sourceIds (channel names) we want to query
|
||||
* @param fields the fields (who map to fields in the DB) we are interested in returning to the
|
||||
* client, needs to be in insertion order (hence the {@link LinkedHashSet} type)
|
||||
* @param startMillis
|
||||
* @param startNanoOffset
|
||||
* @param endMillis
|
||||
* @param endNanoOffset
|
||||
* @param binningStrategyEnum
|
||||
* @param binDurationOrBinCount
|
||||
* @param aggregateChannels
|
||||
* @param aggregationType
|
||||
* @param aggregations
|
||||
* @param queryRange
|
||||
* @param startDateTime
|
||||
* @param endDateTime
|
||||
*/
|
||||
@JsonCreator
|
||||
public TimeRangeQuery(
|
||||
@@ -56,32 +47,24 @@ public class TimeRangeQuery extends AbstractQuery {
|
||||
@JsonProperty(value = "ordering") Ordering ordering,
|
||||
@JsonProperty(value = "channels") List<String> channels,
|
||||
@JsonProperty(value = "fields") LinkedHashSet<String> fields,
|
||||
@JsonProperty(value = "binningStrategy") BinningStrategyEnum binningStrategyEnum,
|
||||
@JsonProperty(value = "binDuration") long binDurationOrBinCount,
|
||||
@JsonProperty(value = "aggregateChannels") boolean aggregateChannels,
|
||||
@JsonProperty(value = "aggregationType") AggregationType aggregationType,
|
||||
@JsonProperty(value = "aggregations") List<Aggregation> aggregations,
|
||||
@JsonProperty(value = "start") long startMillis,
|
||||
@JsonProperty(value = "startNanoOffset") long startNanoOffset,
|
||||
@JsonProperty(value = "queryRange") QueryRange queryRange,
|
||||
@JsonProperty(value = "startDateTime") String startDateTime,
|
||||
@JsonProperty(value = "end") long endMillis,
|
||||
@JsonProperty(value = "endNanoOffset") long endNanoOffset,
|
||||
@JsonProperty(value = "endDateTime") String endDateTime) {
|
||||
|
||||
super(ordering, channels, fields, aggregateChannels, aggregationType, aggregations);
|
||||
|
||||
this.start = startMillis;
|
||||
this.startNanoOffset = startNanoOffset;
|
||||
this.end = endMillis;
|
||||
this.endNanoOffset = endNanoOffset;
|
||||
|
||||
|
||||
super(ordering, channels, fields, binningStrategyEnum, binDurationOrBinCount, aggregateChannels, aggregationType, aggregations, queryRange);
|
||||
|
||||
if (startDateTime != null && endDateTime != null) {
|
||||
logger.info("startDateTime and endDateTime specified. This takes precedence over the start / end fields.");
|
||||
try {
|
||||
Date startDate = DATE_FORMAT.parse(startDateTime);
|
||||
Date endDate = DATE_FORMAT.parse(endDateTime);
|
||||
|
||||
this.start = startDate.getTime();
|
||||
this.end = endDate.getTime();
|
||||
getQueryRange().setTimeRange(startDate.getTime(), queryRange.getStartNanos(), endDate.getTime(), queryRange.getEndNanos());
|
||||
} catch (ParseException e) {
|
||||
logger.error("Parsing the start- and/or endDate was unsuccessful. "
|
||||
+ "The format must be '" + DATE_FORMAT_STRING + "'", e);
|
||||
@@ -90,38 +73,6 @@ public class TimeRangeQuery extends AbstractQuery {
|
||||
|
||||
}
|
||||
|
||||
public long getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
public void setStart(long start) {
|
||||
this.start = start;
|
||||
}
|
||||
|
||||
public long getStartNanoOffset() {
|
||||
return startNanoOffset;
|
||||
}
|
||||
|
||||
public void setStartNanoOffset(long startNanoOffset) {
|
||||
this.startNanoOffset = startNanoOffset;
|
||||
}
|
||||
|
||||
public long getEnd() {
|
||||
return end;
|
||||
}
|
||||
|
||||
public void setEnd(long end) {
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
public long getEndNanoOffset() {
|
||||
return endNanoOffset;
|
||||
}
|
||||
|
||||
public void setEndNanoOffset(long endNanoOffset) {
|
||||
this.endNanoOffset = endNanoOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@@ -130,11 +81,4 @@ public class TimeRangeQuery extends AbstractQuery {
|
||||
return ToStringBuilder.reflectionToString(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryRange getQueryRange() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user