Skip to content

Commit

Permalink
DateTimePredicate now requires ISO8601 datetime strings, also include…
Browse files Browse the repository at this point in the history
…s cleanup of several asset query classes
  • Loading branch information
richturner committed May 10, 2019
1 parent 125e05f commit e83dcbd
Show file tree
Hide file tree
Showing 7 changed files with 27 additions and 28 deletions.
Expand Up @@ -22,6 +22,8 @@
import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Envelope; import com.vividsolutions.jts.geom.Envelope;
import org.geotools.referencing.GeodeticCalculator; import org.geotools.referencing.GeodeticCalculator;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;
import org.openremote.container.timer.TimerService; import org.openremote.container.timer.TimerService;
import org.openremote.manager.asset.AssetStorageService; import org.openremote.manager.asset.AssetStorageService;
import org.openremote.model.attribute.Meta; import org.openremote.model.attribute.Meta;
Expand All @@ -34,14 +36,11 @@
import org.openremote.model.rules.AssetState; import org.openremote.model.rules.AssetState;
import org.openremote.model.rules.json.RuleCondition; import org.openremote.model.rules.json.RuleCondition;
import org.openremote.model.rules.json.RuleOperator; import org.openremote.model.rules.json.RuleOperator;
import org.openremote.model.rules.json.RuleTrigger;
import org.openremote.model.util.Pair; import org.openremote.model.util.Pair;
import org.openremote.model.util.TimeUtil; import org.openremote.model.util.TimeUtil;
import org.openremote.model.value.Value; import org.openremote.model.value.Value;
import org.openremote.model.value.Values; import org.openremote.model.value.Values;


import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*; import java.util.*;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.function.Supplier; import java.util.function.Supplier;
Expand All @@ -58,6 +57,7 @@ public class AssetQueryPredicate implements Predicate<AssetState> {
final protected NewAssetQuery query; final protected NewAssetQuery query;
final protected TimerService timerService; final protected TimerService timerService;
final protected AssetStorageService assetStorageService; final protected AssetStorageService assetStorageService;
static final protected DateTimeFormatter dateFormatter = ISODateTimeFormat.dateTimeNoMillis();


// TODO: Remove this ctor once asset queries merged // TODO: Remove this ctor once asset queries merged
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
Expand Down Expand Up @@ -498,17 +498,17 @@ public static Pair<Long, Long> asFromAndTo(long currentMillis, DateTimePredicate
if (TimeUtil.isTimeDuration(dateTimePredicate.value)) { if (TimeUtil.isTimeDuration(dateTimePredicate.value)) {
from = currentMillis + TimeUtil.parseTimeDuration(dateTimePredicate.value); from = currentMillis + TimeUtil.parseTimeDuration(dateTimePredicate.value);
} else { } else {
from = new SimpleDateFormat(dateTimePredicate.dateFormat).parse(dateTimePredicate.value).getTime(); from = dateFormatter.parseMillis(dateTimePredicate.value);
} }


if (dateTimePredicate.operator == BaseAssetQuery.Operator.BETWEEN) { if (dateTimePredicate.operator == BaseAssetQuery.Operator.BETWEEN) {
if (TimeUtil.isTimeDuration(dateTimePredicate.rangeValue)) { if (TimeUtil.isTimeDuration(dateTimePredicate.rangeValue)) {
to = currentMillis + TimeUtil.parseTimeDuration(dateTimePredicate.rangeValue); to = currentMillis + TimeUtil.parseTimeDuration(dateTimePredicate.rangeValue);
} else { } else {
to = new SimpleDateFormat(dateTimePredicate.dateFormat).parse(dateTimePredicate.rangeValue).getTime(); to = dateFormatter.parseMillis(dateTimePredicate.rangeValue);
} }
} }
} catch (ParseException e) { } catch (IllegalArgumentException e) {
from = null; from = null;
to = null; to = null;
} }
Expand Down
Expand Up @@ -348,6 +348,11 @@ public CHILD id(String id) {
return (CHILD) this; return (CHILD) this;
} }


public CHILD ids(String...ids) {
this.ids = ids != null ? Arrays.asList(ids) : null;
return (CHILD) this;
}

public CHILD ids(Collection<String> ids) { public CHILD ids(Collection<String> ids) {
this.ids = ids != null ? new ArrayList<>(ids) : null; this.ids = ids != null ? new ArrayList<>(ids) : null;
return (CHILD) this; return (CHILD) this;
Expand Down
Expand Up @@ -22,6 +22,7 @@
import org.openremote.model.value.ObjectValue; import org.openremote.model.value.ObjectValue;
import org.openremote.model.value.Values; import org.openremote.model.value.Values;


// TODO: Incorporate meta predicates here
public class AttributePredicate { public class AttributePredicate {


public StringPredicate name; public StringPredicate name;
Expand Down
Expand Up @@ -23,13 +23,17 @@
import org.openremote.model.value.ObjectValue; import org.openremote.model.value.ObjectValue;
import org.openremote.model.value.Values; import org.openremote.model.value.Values;


/**
* Predicate for date time values; provided values should be valid ISO 8601 datetime strings (e.g. yyyy-MM-dd'T'HH:mm:ssZ
* or yyyy-MM-dd'T'HH:mm:ss\u00b1HH:mm), it is recommended to include time zone information to avoid any issues working
* across timezones.
*/
public class DateTimePredicate implements ValuePredicate { public class DateTimePredicate implements ValuePredicate {


public static final String name = "datetime"; public static final String name = "datetime";
public String value; // Sliding window value e.g. 1h or fixed date time public String value; // Sliding window value e.g. 1h or fixed date time
public String rangeValue; // Sliding window value e.g. 1h or fixed date time (used as upper bound when Operator.BETWEEN) public String rangeValue; // Sliding window value e.g. 1h or fixed date time (used as upper bound when Operator.BETWEEN)
public BaseAssetQuery.Operator operator = BaseAssetQuery.Operator.EQUALS; public BaseAssetQuery.Operator operator = BaseAssetQuery.Operator.EQUALS;
public String dateFormat = "yyyy-MM-dd HH:mm:ss"; // SimpleDateFormat


public DateTimePredicate() { public DateTimePredicate() {
} }
Expand All @@ -48,9 +52,6 @@ public DateTimePredicate(String rangeStart, String rangeEnd) {
public static DateTimePredicate fromObjectValue(ObjectValue objectValue) { public static DateTimePredicate fromObjectValue(ObjectValue objectValue) {
DateTimePredicate dateTimePredicate = new DateTimePredicate(); DateTimePredicate dateTimePredicate = new DateTimePredicate();


objectValue.getString("dateFormat").ifPresent(format -> {
dateTimePredicate.dateFormat = format;
});
objectValue.getString("value").ifPresent(value -> { objectValue.getString("value").ifPresent(value -> {
dateTimePredicate.value = value; dateTimePredicate.value = value;
}); });
Expand All @@ -68,11 +69,6 @@ public DateTimePredicate operator(BaseAssetQuery.Operator dateMatch) {
return this; return this;
} }


public DateTimePredicate dateFormat(String dateFormat) {
this.dateFormat = dateFormat;
return this;
}

public DateTimePredicate value(String value) { public DateTimePredicate value(String value) {
this.value = value; this.value = value;
return this; return this;
Expand All @@ -87,7 +83,6 @@ public DateTimePredicate rangeValue(String rangeEnd) {
public ObjectValue toModelValue() { public ObjectValue toModelValue() {
ObjectValue objectValue = Values.createObject(); ObjectValue objectValue = Values.createObject();
objectValue.put("predicateType", name); objectValue.put("predicateType", name);
objectValue.put("dateFormat", Values.create(dateFormat));
objectValue.put("value", Values.create(value)); objectValue.put("value", Values.create(value));
objectValue.put("rangeValue", Values.create(rangeValue)); objectValue.put("rangeValue", Values.create(rangeValue));
objectValue.put("operator", Values.create(operator.toString())); objectValue.put("operator", Values.create(operator.toString()));
Expand All @@ -100,7 +95,6 @@ public String toString() {
"value='" + value + '\'' + "value='" + value + '\'' +
", rangeValue='" + rangeValue + '\'' + ", rangeValue='" + rangeValue + '\'' +
", operator =" + operator + ", operator =" + operator +
", dateFormat='" + dateFormat + '\'' +
'}'; '}';
} }
} }
Expand Up @@ -19,6 +19,8 @@
*/ */
package org.openremote.model.query.filter; package org.openremote.model.query.filter;


import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.openremote.model.value.ObjectValue; import org.openremote.model.value.ObjectValue;
import org.openremote.model.value.Values; import org.openremote.model.value.Values;


Expand All @@ -32,7 +34,8 @@ public ObjectValueKeyPredicate(String hasKey) {
key = hasKey; key = hasKey;
} }


public ObjectValueKeyPredicate(String hasKey, boolean negate) { @JsonCreator
public ObjectValueKeyPredicate(@JsonProperty("key") String hasKey, @JsonProperty("negated") boolean negate) {
key = hasKey; key = hasKey;
negated = negate; negated = negate;
} }
Expand Down
Expand Up @@ -19,7 +19,7 @@
*/ */
package org.openremote.model.rules.json; package org.openremote.model.rules.json;


import org.openremote.model.query.AssetQuery; import org.openremote.model.query.NewAssetQuery;
import org.openremote.model.query.UserQuery; import org.openremote.model.query.UserQuery;


/** /**
Expand All @@ -32,6 +32,6 @@
*/ */
public class RuleActionTarget { public class RuleActionTarget {
public String ruleTriggerTag; public String ruleTriggerTag;
public AssetQuery assets; public NewAssetQuery assets;
public UserQuery users; public UserQuery users;
} }
Expand Up @@ -870,8 +870,7 @@ class AssetQueryTest extends Specification implements ManagerContainerTrait {
.attributeValue( .attributeValue(
"openingDate", "openingDate",
new DateTimePredicate(rangeStart.format(ISO_LOCAL_DATE_TIME), rangeEnd.format(ISO_LOCAL_DATE_TIME)) new DateTimePredicate(rangeStart.format(ISO_LOCAL_DATE_TIME), rangeEnd.format(ISO_LOCAL_DATE_TIME))
.operator(Operator.BETWEEN) .operator(Operator.BETWEEN))
.dateFormat("yyyy-MM-dd'T'HH:mm:ss"))
) )




Expand All @@ -885,8 +884,7 @@ class AssetQueryTest extends Specification implements ManagerContainerTrait {
.tenant(new TenantPredicate(keycloakDemoSetup.masterTenant.realm)) .tenant(new TenantPredicate(keycloakDemoSetup.masterTenant.realm))
.attributeValue( .attributeValue(
"openingDate", "openingDate",
new DateTimePredicate(Operator.GREATER_THAN, rangeStart.format(ISO_LOCAL_DATE_TIME)) new DateTimePredicate(Operator.GREATER_THAN, rangeStart.format(ISO_LOCAL_DATE_TIME)))
.dateFormat("yyyy-MM-dd'T'HH:mm:ss"))
) )




Expand All @@ -900,8 +898,7 @@ class AssetQueryTest extends Specification implements ManagerContainerTrait {
.tenant(new TenantPredicate(keycloakDemoSetup.masterTenant.realm)) .tenant(new TenantPredicate(keycloakDemoSetup.masterTenant.realm))
.attributeValue( .attributeValue(
"openingDate", "openingDate",
new DateTimePredicate(Operator.LESS_THAN, rangeEnd.format(ISO_LOCAL_DATE_TIME)) new DateTimePredicate(Operator.LESS_THAN, rangeEnd.format(ISO_LOCAL_DATE_TIME)))
.dateFormat("yyyy-MM-dd'T'HH:mm:ss"))
) )




Expand All @@ -917,8 +914,7 @@ class AssetQueryTest extends Specification implements ManagerContainerTrait {
.tenant(new TenantPredicate(keycloakDemoSetup.masterTenant.realm)) .tenant(new TenantPredicate(keycloakDemoSetup.masterTenant.realm))
.attributeValue( .attributeValue(
"openingDate", "openingDate",
new DateTimePredicate(Operator.EQUALS, rangeStart.format(ISO_LOCAL_DATE_TIME)) new DateTimePredicate(Operator.EQUALS, rangeStart.format(ISO_LOCAL_DATE_TIME)))
.dateFormat("yyyy-MM-dd'T'HH:mm:ss"))
) )




Expand Down

0 comments on commit e83dcbd

Please sign in to comment.