Browse Source

Merge branch 'master' into feature/assetProfile

pull/7342/head
Igor Kulikov 4 years ago
parent
commit
afa69f6f78
  1. 8
      application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbEntityDataSubscriptionService.java
  2. 7
      common/data/src/main/java/org/thingsboard/server/common/data/EntityFieldsData.java
  3. 9
      common/data/src/main/java/org/thingsboard/server/common/data/kv/ReadTsKvQueryResult.java
  4. 11
      common/data/src/main/java/org/thingsboard/server/common/data/query/EntityData.java
  5. 2
      rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbNode.java
  6. 3
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbAbstractCustomerActionNode.java
  7. 3
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbAbstractRelationActionNode.java
  8. 3
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCopyAttributesToEntityViewNode.java
  9. 3
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbMsgCountNode.java
  10. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/AbstractTbMsgPushNode.java
  11. 3
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbCheckAlarmStatusNode.java
  12. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbCheckMessageNode.java
  13. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbCheckRelationNode.java
  14. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbMsgTypeFilterNode.java
  15. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbMsgTypeSwitchNode.java
  16. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbOriginatorTypeFilterNode.java
  17. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbOriginatorTypeSwitchNode.java
  18. 3
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/flow/TbAckNode.java
  19. 3
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/flow/TbCheckpointNode.java
  20. 3
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/flow/TbRuleChainInputNode.java
  21. 3
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/flow/TbRuleChainOutputNode.java
  22. 5
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/AbstractGeofencingNode.java
  23. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mail/TbMsgToEmailNode.java
  24. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mail/TbSendEmailNode.java
  25. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetAttributesNode.java
  26. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDetailsNode.java
  27. 5
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbEntityGetAttrNode.java
  28. 2
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsConfiguration.java
  29. 8
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNode.java
  30. 85
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTelemetryNode.java
  31. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rpc/TbSendRPCReplyNode.java
  32. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rpc/TbSendRPCRequestNode.java
  33. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java
  34. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transaction/TbSynchronizationBeginNode.java
  35. 3
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transaction/TbSynchronizationEndNode.java
  36. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbChangeOriginatorNode.java
  37. 17
      rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTelemetryNodeTest.java
  38. 6
      ui-ngx/src/app/core/api/entity-data-subscription.ts
  39. 38
      ui-ngx/src/app/shared/models/rule-node.models.ts

8
application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbEntityDataSubscriptionService.java

@ -314,9 +314,9 @@ public class DefaultTbEntityDataSubscriptionService implements TbEntityDataSubsc
ReadTsKvQueryInfo queryInfo = queries.get(queryResult.getQueryId());
ComparisonTsValue comparisonTsValue = entityData.getAggLatest().computeIfAbsent(queryInfo.getKey().getId(), agg -> new ComparisonTsValue());
if (queryInfo.isPrevious()) {
comparisonTsValue.setPrevious(queryResult.toTsValue());
comparisonTsValue.setPrevious(queryResult.toTsValue(queryInfo.getQuery()));
} else {
comparisonTsValue.setCurrent(queryResult.toTsValue());
comparisonTsValue.setCurrent(queryResult.toTsValue(queryInfo.getQuery()));
lastTsMap.put(queryInfo.getQuery().getKey(), queryResult.getLastEntryTs());
}
}
@ -343,7 +343,7 @@ public class DefaultTbEntityDataSubscriptionService implements TbEntityDataSubsc
ctx.createTimeSeriesSubscriptions(lastTsEntityMap, startTs, endTs, true);
}
ctx.sendWsMsg(update);
entityDataList.forEach(ed -> ed.getTimeseries().clear());
entityDataList.forEach(EntityData::clearTsAndAggData);
} finally {
ctx.getWsLock().unlock();
}
@ -594,7 +594,7 @@ public class DefaultTbEntityDataSubscriptionService implements TbEntityDataSubsc
ctx.createTimeSeriesSubscriptions(lastTsEntityMap, cmd.getStartTs(), cmd.getEndTs());
}
ctx.sendWsMsg(update);
entityDataList.forEach(ed -> ed.getTimeseries().clear());
entityDataList.forEach(EntityData::clearTsAndAggData);
} finally {
ctx.getWsLock().unlock();
}

7
common/data/src/main/java/org/thingsboard/server/common/data/EntityFieldsData.java

@ -50,6 +50,10 @@ public class EntityFieldsData {
}
public String getFieldValue(String field) {
return getFieldValue(field, false);
}
public String getFieldValue(String field, boolean ignoreNullStrings) {
String[] fieldsTree = field.split("\\.");
JsonNode current = fieldsData;
for (String key : fieldsTree) {
@ -61,6 +65,9 @@ public class EntityFieldsData {
}
}
if (current != null) {
if(current.isNull() && ignoreNullStrings){
return null;
}
if (current.isValueNode()) {
return current.asText();
} else {

9
common/data/src/main/java/org/thingsboard/server/common/data/kv/ReadTsKvQueryResult.java

@ -42,9 +42,14 @@ public class ReadTsKvQueryResult {
}
}
public TsValue toTsValue() {
public TsValue toTsValue(ReadTsKvQuery query) {
if (data == null || data.isEmpty()) {
return TsValue.EMPTY;
if (Aggregation.SUM.equals(query.getAggregation()) || Aggregation.COUNT.equals(query.getAggregation())) {
long ts = query.getStartTs() + (query.getEndTs() - query.getStartTs()) / 2;
return new TsValue(ts, "0");
} else {
return TsValue.EMPTY;
}
}
if (data.size() > 1) {
throw new RuntimeException("Query Result has multiple data points!");

11
common/data/src/main/java/org/thingsboard/server/common/data/query/EntityData.java

@ -15,6 +15,7 @@
*/
package org.thingsboard.server.common.data.query;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.thingsboard.server.common.data.id.EntityId;
@ -33,4 +34,14 @@ public class EntityData {
public EntityData(EntityId entityId, Map<EntityKeyType, Map<String, TsValue>> latest, Map<String, TsValue[]> timeseries) {
this(entityId, latest, timeseries, null);
}
@JsonIgnore
public void clearTsAndAggData() {
if (timeseries != null) {
timeseries.clear();
}
if (aggLatest != null) {
aggLatest.clear();
}
}
}

2
rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbNode.java

@ -29,7 +29,7 @@ public interface TbNode {
void onMsg(TbContext ctx, TbMsg msg) throws ExecutionException, InterruptedException, TbNodeException;
void destroy();
default void destroy() {}
default void onPartitionChangeMsg(TbContext ctx, PartitionChangeMsg msg) {}

3
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbAbstractCustomerActionNode.java

@ -92,6 +92,9 @@ public abstract class TbAbstractCustomerActionNode<C extends TbAbstractCustomerA
@Override
public void destroy() {
if (customerIdCache != null) {
customerIdCache.invalidateAll();
}
}
@Data

3
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbAbstractRelationActionNode.java

@ -88,6 +88,9 @@ public abstract class TbAbstractRelationActionNode<C extends TbAbstractRelationA
@Override
public void destroy() {
if (entityIdCache != null) {
entityIdCache.invalidateAll();
}
}
protected ListenableFuture<RelationContainer> processEntityRelationAction(TbContext ctx, TbMsg msg, String relationType) {

3
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCopyAttributesToEntityViewNode.java

@ -158,7 +158,4 @@ public class TbCopyAttributesToEntityViewNode implements TbNode {
return CollectionsUtil.contains(keys, attrKey);
}
@Override
public void destroy() {
}
}

3
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbMsgCountNode.java

@ -98,7 +98,4 @@ public class TbMsgCountNode implements TbNode {
ctx.tellSelf(tickMsg, curDelay);
}
@Override
public void destroy() {
}
}

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/AbstractTbMsgPushNode.java

@ -71,10 +71,6 @@ public abstract class AbstractTbMsgPushNode<T extends BaseTbMsgPushNodeConfigura
}
}
@Override
public void destroy() {
}
protected S buildEvent(TbMsg msg, TbContext ctx) {
String msgType = msg.getType();
if (DataConstants.ALARM.equals(msgType)) {

3
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbCheckAlarmStatusNode.java

@ -93,7 +93,4 @@ public class TbCheckAlarmStatusNode implements TbNode {
}
}
@Override
public void destroy() {
}
}

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbCheckMessageNode.java

@ -68,10 +68,6 @@ public class TbCheckMessageNode implements TbNode {
}
}
@Override
public void destroy() {
}
private boolean allKeysData(TbMsg msg) {
if (!messageNamesList.isEmpty()) {
Map<String, String> dataMap = dataToMap(msg);

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbCheckRelationNode.java

@ -103,8 +103,4 @@ public class TbCheckRelationNode implements TbNode {
}
}
@Override
public void destroy() {
}
}

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbMsgTypeFilterNode.java

@ -52,8 +52,4 @@ public class TbMsgTypeFilterNode implements TbNode {
ctx.tellNext(msg, config.getMessageTypes().contains(msg.getType()) ? "True" : "False");
}
@Override
public void destroy() {
}
}

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbMsgTypeSwitchNode.java

@ -117,8 +117,4 @@ public class TbMsgTypeSwitchNode implements TbNode {
ctx.tellNext(msg, relationType);
}
@Override
public void destroy() {
}
}

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbOriginatorTypeFilterNode.java

@ -51,8 +51,4 @@ public class TbOriginatorTypeFilterNode implements TbNode {
ctx.tellNext(msg, config.getOriginatorTypes().contains(originatorType) ? "True" : "False");
}
@Override
public void destroy() {
}
}

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbOriginatorTypeSwitchNode.java

@ -90,8 +90,4 @@ public class TbOriginatorTypeSwitchNode implements TbNode {
ctx.tellNext(msg, relationType);
}
@Override
public void destroy() {
}
}

3
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/flow/TbAckNode.java

@ -51,7 +51,4 @@ public class TbAckNode implements TbNode {
ctx.tellSuccess(msg);
}
@Override
public void destroy() {
}
}

3
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/flow/TbCheckpointNode.java

@ -54,7 +54,4 @@ public class TbCheckpointNode implements TbNode {
ctx.enqueueForTellNext(msg, queueName, TbRelationTypes.SUCCESS, () -> ctx.ack(msg), error -> ctx.tellFailure(msg, error));
}
@Override
public void destroy() {
}
}

3
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/flow/TbRuleChainInputNode.java

@ -63,7 +63,4 @@ public class TbRuleChainInputNode implements TbNode {
ctx.input(msg, ruleChainId);
}
@Override
public void destroy() {
}
}

3
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/flow/TbRuleChainOutputNode.java

@ -51,7 +51,4 @@ public class TbRuleChainOutputNode implements TbNode {
ctx.output(msg, ctx.getSelf().getName());
}
@Override
public void destroy() {
}
}

5
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/AbstractGeofencingNode.java

@ -148,9 +148,4 @@ public abstract class AbstractGeofencingNode<T extends TbGpsGeofencingFilterNode
return value;
}
@Override
public void destroy() {
}
}

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mail/TbMsgToEmailNode.java

@ -110,8 +110,4 @@ public class TbMsgToEmailNode implements TbNode {
}
}
@Override
public void destroy() {
}
}

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mail/TbSendEmailNode.java

@ -107,10 +107,6 @@ public class TbSendEmailNode implements TbNode {
}
}
@Override
public void destroy() {
}
private JavaMailSenderImpl createMailSender() {
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
mailSender.setHost(this.config.getSmtpHost());

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetAttributesNode.java

@ -79,10 +79,6 @@ public abstract class TbAbstractGetAttributesNode<C extends TbGetAttributesNodeC
}
}
@Override
public void destroy() {
}
protected abstract ListenableFuture<T> findEntityIdAsync(TbContext ctx, TbMsg msg);
private void safePutAttributes(TbContext ctx, TbMsg msg, T entityId) {

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDetailsNode.java

@ -63,10 +63,6 @@ public abstract class TbAbstractGetEntityDetailsNode<C extends TbAbstractGetEnti
t -> ctx.tellFailure(msg, t), ctx.getDbCallbackExecutor());
}
@Override
public void destroy() {
}
protected abstract C loadGetEntityDetailsNodeConfiguration(TbNodeConfiguration configuration) throws TbNodeException;
protected abstract ListenableFuture<TbMsg> getDetails(TbContext ctx, TbMsg msg);

5
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbEntityGetAttrNode.java

@ -100,11 +100,6 @@ public abstract class TbEntityGetAttrNode<T extends EntityId> implements TbNode
ctx.tellSuccess(msg);
}
@Override
public void destroy() {
}
protected abstract ListenableFuture<T> findEntityAsync(TbContext ctx, EntityId originator);
public void setConfig(TbGetEntityAttrNodeConfiguration config) {

2
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsConfiguration.java

@ -25,6 +25,7 @@ import java.util.Map;
public class TbGetOriginatorFieldsConfiguration implements NodeConfiguration<TbGetOriginatorFieldsConfiguration> {
private Map<String, String> fieldsMapping;
private boolean ignoreNullStrings;
@Override
public TbGetOriginatorFieldsConfiguration defaultConfiguration() {
@ -33,6 +34,7 @@ public class TbGetOriginatorFieldsConfiguration implements NodeConfiguration<TbG
fieldsMapping.put("name", "originatorName");
fieldsMapping.put("type", "originatorType");
configuration.setFieldsMapping(fieldsMapping);
configuration.setIgnoreNullStrings(false);
return configuration;
}
}

8
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNode.java

@ -46,10 +46,12 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback;
public class TbGetOriginatorFieldsNode implements TbNode {
private TbGetOriginatorFieldsConfiguration config;
private boolean ignoreNullStrings;
@Override
public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException {
config = TbNodeUtils.convert(configuration, TbGetOriginatorFieldsConfiguration.class);
ignoreNullStrings = config.isIgnoreNullStrings();
}
@Override
@ -69,7 +71,7 @@ public class TbGetOriginatorFieldsNode implements TbNode {
return Futures.transform(EntitiesFieldsAsyncLoader.findAsync(ctx, entityId),
data -> {
config.getFieldsMapping().forEach((field, metaKey) -> {
String val = data.getFieldValue(field);
String val = data.getFieldValue(field, ignoreNullStrings);
if (val != null) {
msg.getMetaData().putValue(metaKey, val);
}
@ -80,8 +82,4 @@ public class TbGetOriginatorFieldsNode implements TbNode {
}
}
@Override
public void destroy() {
}
}

85
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTelemetryNode.java

@ -98,7 +98,7 @@ public class TbGetTelemetryNode implements TbNode {
}
Aggregation parseAggregationConfig(String aggName) {
if (StringUtils.isEmpty(aggName)) {
if (StringUtils.isEmpty(aggName) || !fetchMode.equals(FETCH_MODE_ALL)) {
return Aggregation.NONE;
}
return Aggregation.valueOf(aggName);
@ -110,11 +110,9 @@ public class TbGetTelemetryNode implements TbNode {
ctx.tellFailure(msg, new IllegalStateException("Telemetry is not selected!"));
} else {
try {
if (config.isUseMetadataIntervalPatterns()) {
checkMetadataKeyPatterns(msg);
}
Interval interval = getInterval(msg);
List<String> keys = TbNodeUtils.processPatterns(tsKeyNames, msg);
ListenableFuture<List<TsKvEntry>> list = ctx.getTimeseriesService().findAll(ctx.getTenantId(), msg.getOriginator(), buildQueries(msg, keys));
ListenableFuture<List<TsKvEntry>> list = ctx.getTimeseriesService().findAll(ctx.getTenantId(), msg.getOriginator(), buildQueries(interval, keys));
DonAsynchron.withCallback(list, data -> {
process(data, msg, keys);
ctx.tellSuccess(ctx.transformMsg(msg, msg.getType(), msg.getOriginator(), msg.getMetaData(), msg.getData()));
@ -125,12 +123,7 @@ public class TbGetTelemetryNode implements TbNode {
}
}
@Override
public void destroy() {
}
private List<ReadTsKvQuery> buildQueries(TbMsg msg, List<String> keys) {
final Interval interval = getInterval(msg);
private List<ReadTsKvQuery> buildQueries(Interval interval, List<String> keys) {
final long aggIntervalStep = Aggregation.NONE.equals(aggregation) ? 1 :
// exact how it validates on BaseTimeseriesService.validate()
// see CassandraBaseTimeseriesDao.findAllAsync()
@ -210,71 +203,45 @@ public class TbGetTelemetryNode implements TbNode {
}
private Interval getInterval(TbMsg msg) {
Interval interval = new Interval();
if (config.isUseMetadataIntervalPatterns()) {
if (isParsable(msg, config.getStartIntervalPattern())) {
interval.setStartTs(Long.parseLong(TbNodeUtils.processPattern(config.getStartIntervalPattern(), msg)));
}
if (isParsable(msg, config.getEndIntervalPattern())) {
interval.setEndTs(Long.parseLong(TbNodeUtils.processPattern(config.getEndIntervalPattern(), msg)));
}
return getIntervalFromPatterns(msg);
} else {
Interval interval = new Interval();
long ts = System.currentTimeMillis();
interval.setStartTs(ts - TimeUnit.valueOf(config.getStartIntervalTimeUnit()).toMillis(config.getStartInterval()));
interval.setEndTs(ts - TimeUnit.valueOf(config.getEndIntervalTimeUnit()).toMillis(config.getEndInterval()));
return interval;
}
return interval;
}
private boolean isParsable(TbMsg msg, String pattern) {
return NumberUtils.isParsable(TbNodeUtils.processPattern(pattern, msg));
}
private void checkMetadataKeyPatterns(TbMsg msg) {
isUndefined(msg, config.getStartIntervalPattern(), config.getEndIntervalPattern());
isInvalid(msg, config.getStartIntervalPattern(), config.getEndIntervalPattern());
private Interval getIntervalFromPatterns(TbMsg msg) {
Interval interval = new Interval();
interval.setStartTs(checkPattern(msg, config.getStartIntervalPattern()));
interval.setEndTs(checkPattern(msg, config.getEndIntervalPattern()));
return interval;
}
private void isUndefined(TbMsg msg, String startIntervalPattern, String endIntervalPattern) {
if (getMetadataValue(msg, startIntervalPattern) == null && getMetadataValue(msg, endIntervalPattern) == null) {
throw new IllegalArgumentException("Message metadata values: '" +
replaceRegex(startIntervalPattern) + "' and '" +
replaceRegex(endIntervalPattern) + "' are undefined");
} else {
if (getMetadataValue(msg, startIntervalPattern) == null) {
throw new IllegalArgumentException("Message metadata value: '" +
replaceRegex(startIntervalPattern) + "' is undefined");
}
if (getMetadataValue(msg, endIntervalPattern) == null) {
throw new IllegalArgumentException("Message metadata value: '" +
replaceRegex(endIntervalPattern) + "' is undefined");
}
private long checkPattern(TbMsg msg, String pattern) {
String value = getValuePattern(msg, pattern);
if (value == null) {
throw new IllegalArgumentException("Message value: '" +
replaceRegex(pattern) + "' is undefined");
}
}
private void isInvalid(TbMsg msg, String startIntervalPattern, String endIntervalPattern) {
if (getInterval(msg).getStartTs() == null && getInterval(msg).getEndTs() == null) {
throw new IllegalArgumentException("Message metadata values: '" +
replaceRegex(startIntervalPattern) + "' and '" +
replaceRegex(endIntervalPattern) + "' have invalid format");
} else {
if (getInterval(msg).getStartTs() == null) {
throw new IllegalArgumentException("Message metadata value: '" +
replaceRegex(startIntervalPattern) + "' has invalid format");
}
if (getInterval(msg).getEndTs() == null) {
throw new IllegalArgumentException("Message metadata value: '" +
replaceRegex(endIntervalPattern) + "' has invalid format");
}
boolean parsable = NumberUtils.isParsable(value);
if (!parsable) {
throw new IllegalArgumentException("Message value: '" +
replaceRegex(pattern) + "' has invalid format");
}
return Long.parseLong(value);
}
private String getMetadataValue(TbMsg msg, String pattern) {
return msg.getMetaData().getValue(replaceRegex(pattern));
private String getValuePattern(TbMsg msg, String pattern) {
String value = TbNodeUtils.processPattern(pattern, msg);
return value.equals(pattern) ? null : value;
}
private String replaceRegex(String pattern) {
return pattern.replaceAll("[${}]", "");
return pattern.replaceAll("[$\\[{}\\]]", "");
}
private int validateLimit(int limit) {

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rpc/TbSendRPCReplyNode.java

@ -70,8 +70,4 @@ public class TbSendRPCReplyNode implements TbNode {
}
}
@Override
public void destroy() {
}
}

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rpc/TbSendRPCRequestNode.java

@ -127,10 +127,6 @@ public class TbSendRPCRequestNode implements TbNode {
}
}
@Override
public void destroy() {
}
private String wrap(String name, String body) {
JsonObject json = new JsonObject();
json.addProperty(name, body);

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java

@ -75,8 +75,4 @@ public class TbMsgAttributesNode implements TbNode {
);
}
@Override
public void destroy() {
}
}

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transaction/TbSynchronizationBeginNode.java

@ -49,8 +49,4 @@ public class TbSynchronizationBeginNode implements TbNode {
ctx.tellSuccess(msg);
}
@Override
public void destroy() {
}
}

3
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transaction/TbSynchronizationEndNode.java

@ -48,7 +48,4 @@ public class TbSynchronizationEndNode implements TbNode {
ctx.tellSuccess(msg);
}
@Override
public void destroy() {
}
}

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbChangeOriginatorNode.java

@ -108,8 +108,4 @@ public class TbChangeOriginatorNode extends TbAbstractTransformNode {
}
@Override
public void destroy() {
}
}

17
rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTelemetryNodeTest.java

@ -15,8 +15,12 @@
*/
package org.thingsboard.rule.engine.metadata;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Before;
import org.junit.Test;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.rule.engine.api.TbContext;
import org.thingsboard.rule.engine.api.TbNodeConfiguration;
import org.thingsboard.server.common.data.kv.Aggregation;
import static org.hamcrest.CoreMatchers.is;
@ -24,14 +28,25 @@ import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.willCallRealMethod;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
public class TbGetTelemetryNodeTest {
TbGetTelemetryNode node;
TbGetTelemetryNodeConfiguration config;
TbNodeConfiguration nodeConfiguration;
TbContext ctx;
@Before
public void setUp() throws Exception {
node = mock(TbGetTelemetryNode.class);
ctx = mock(TbContext.class);
node = spy(new TbGetTelemetryNode());
config = new TbGetTelemetryNodeConfiguration();
config.setFetchMode("ALL");
ObjectMapper mapper = JacksonUtil.OBJECT_MAPPER;
nodeConfiguration = new TbNodeConfiguration(mapper.valueToTree(config));
node.init(ctx, nodeConfiguration);
willCallRealMethod().given(node).parseAggregationConfig(any());
}

6
ui-ngx/src/app/core/api/entity-data-subscription.ts

@ -165,7 +165,11 @@ export class EntityDataSubscription {
if (key.comparisonResultType === ComparisonResultType.DELTA_ABSOLUTE) {
value = currentVal - prevVal;
} else {
value = (currentVal - prevVal) / prevVal * 100;
if(prevVal === 0){
value = 100;
} else {
value = (currentVal - prevVal) / prevVal * 100;
}
}
} else {
value = '';

38
ui-ngx/src/app/shared/models/rule-node.models.ts

@ -347,6 +347,14 @@ export enum MessageType {
POST_TELEMETRY_REQUEST = 'POST_TELEMETRY_REQUEST',
TO_SERVER_RPC_REQUEST = 'TO_SERVER_RPC_REQUEST',
RPC_CALL_FROM_SERVER_TO_DEVICE = 'RPC_CALL_FROM_SERVER_TO_DEVICE',
RPC_QUEUED = 'RPC_QUEUED',
RPC_SENT = 'RPC_SENT',
RPC_DELIVERED = 'RPC_DELIVERED',
RPC_SUCCESSFUL = 'RPC_SUCCESSFUL',
RPC_TIMEOUT = 'RPC_TIMEOUT',
RPC_EXPIRED = 'RPC_EXPIRED',
RPC_FAILED = 'RPC_FAILED',
RPC_DELETED = 'RPC_DELETED',
ACTIVITY_EVENT = 'ACTIVITY_EVENT',
INACTIVITY_EVENT = 'INACTIVITY_EVENT',
CONNECT_EVENT = 'CONNECT_EVENT',
@ -358,13 +366,12 @@ export enum MessageType {
ENTITY_UNASSIGNED = 'ENTITY_UNASSIGNED',
ATTRIBUTES_UPDATED = 'ATTRIBUTES_UPDATED',
ATTRIBUTES_DELETED = 'ATTRIBUTES_DELETED',
ALARM_ACKNOWLEDGED = 'ALARM_ACKNOWLEDGED',
ALARM_CLEARED = 'ALARM_CLEARED',
ENTITY_ASSIGNED_FROM_TENANT = 'ENTITY_ASSIGNED_FROM_TENANT',
ENTITY_ASSIGNED_TO_TENANT = 'ENTITY_ASSIGNED_TO_TENANT',
TIMESERIES_UPDATED = 'TIMESERIES_UPDATED',
TIMESERIES_DELETED = 'TIMESERIES_DELETED',
RPC_QUEUED = 'RPC_QUEUED',
RPC_DELIVERED = 'RPC_DELIVERED',
RPC_SUCCESSFUL = 'RPC_SUCCESSFUL',
RPC_TIMEOUT = 'RPC_TIMEOUT',
RPC_FAILED = 'RPC_FAILED'
TIMESERIES_DELETED = 'TIMESERIES_DELETED'
}
export const messageTypeNames = new Map<MessageType, string>(
@ -373,6 +380,14 @@ export const messageTypeNames = new Map<MessageType, string>(
[MessageType.POST_TELEMETRY_REQUEST, 'Post telemetry'],
[MessageType.TO_SERVER_RPC_REQUEST, 'RPC Request from Device'],
[MessageType.RPC_CALL_FROM_SERVER_TO_DEVICE, 'RPC Request to Device'],
[MessageType.RPC_QUEUED, 'RPC Queued'],
[MessageType.RPC_SENT, 'RPC Sent'],
[MessageType.RPC_DELIVERED, 'RPC Delivered'],
[MessageType.RPC_SUCCESSFUL, 'RPC Successful'],
[MessageType.RPC_TIMEOUT, 'RPC Timeout'],
[MessageType.RPC_EXPIRED, 'RPC Expired'],
[MessageType.RPC_FAILED, 'RPC Failed'],
[MessageType.RPC_DELETED, 'RPC Deleted'],
[MessageType.ACTIVITY_EVENT, 'Activity Event'],
[MessageType.INACTIVITY_EVENT, 'Inactivity Event'],
[MessageType.CONNECT_EVENT, 'Connect Event'],
@ -384,13 +399,12 @@ export const messageTypeNames = new Map<MessageType, string>(
[MessageType.ENTITY_UNASSIGNED, 'Entity Unassigned'],
[MessageType.ATTRIBUTES_UPDATED, 'Attributes Updated'],
[MessageType.ATTRIBUTES_DELETED, 'Attributes Deleted'],
[MessageType.ALARM_ACKNOWLEDGED, 'Alarm Acknowledged'],
[MessageType.ALARM_CLEARED, 'Alarm Cleared'],
[MessageType.ENTITY_ASSIGNED_FROM_TENANT, 'Entity Assigned From Tenant'],
[MessageType.ENTITY_ASSIGNED_TO_TENANT, 'Entity Assigned To Tenant'],
[MessageType.TIMESERIES_UPDATED, 'Timeseries Updated'],
[MessageType.TIMESERIES_DELETED, 'Timeseries Deleted'],
[MessageType.RPC_QUEUED, 'RPC Queued'],
[MessageType.RPC_DELIVERED, 'RPC Delivered'],
[MessageType.RPC_SUCCESSFUL, 'RPC Successful'],
[MessageType.RPC_TIMEOUT, 'RPC Timeout'],
[MessageType.RPC_FAILED, 'RPC Failed']
[MessageType.TIMESERIES_DELETED, 'Timeseries Deleted']
]
);

Loading…
Cancel
Save