Browse Source

Refactoring of the rule engine

pull/2560/head
Andrii Shvaika 7 years ago
parent
commit
99d322d449
  1. 18
      application/src/main/java/org/thingsboard/server/actors/app/AppActor.java
  2. 24
      application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java
  3. 26
      application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java
  4. 7
      application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainActor.java
  5. 13
      application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainActorMessageProcessor.java
  6. 6
      application/src/main/java/org/thingsboard/server/actors/shared/EntityActorsManager.java
  7. 35
      application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java
  8. 6
      application/src/main/java/org/thingsboard/server/controller/BaseController.java
  9. 3
      application/src/main/java/org/thingsboard/server/controller/RuleChainController.java
  10. 2
      application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java
  11. 24
      application/src/main/java/org/thingsboard/server/service/queue/DefaultTbRuleEngineConsumerService.java
  12. 1
      application/src/main/java/org/thingsboard/server/service/queue/MsgPackCallback.java
  13. 6
      application/src/main/java/org/thingsboard/server/service/rpc/DefaultDeviceRpcService.java
  14. 2
      application/src/main/java/org/thingsboard/server/service/script/RuleNodeJsScriptEngine.java
  15. 8
      application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java
  16. 2
      application/src/main/java/org/thingsboard/server/service/state/DeviceStateService.java
  17. 2
      application/src/main/java/org/thingsboard/server/service/subscription/DefaultLocalSubscriptionService.java
  18. 3
      application/src/main/java/org/thingsboard/server/service/subscription/DefaultSubscriptionManagerService.java
  19. 2
      application/src/main/java/org/thingsboard/server/service/subscription/LocalSubscriptionService.java
  20. 2
      application/src/main/java/org/thingsboard/server/service/subscription/SubscriptionManagerService.java
  21. 2
      application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetrySubscriptionService.java
  22. 2
      application/src/main/java/org/thingsboard/server/service/transaction/BaseRuleChainTransactionService.java
  23. 2
      application/src/main/java/org/thingsboard/server/service/transport/msg/TransportToDeviceActorMsgWrapper.java
  24. 21
      application/src/test/java/org/thingsboard/server/rules/flow/AbstractRuleEngineFlowIntegrationTest.java
  25. 10
      application/src/test/java/org/thingsboard/server/rules/lifecycle/AbstractRuleEngineLifecycleIntegrationTest.java
  26. 15
      application/src/test/java/org/thingsboard/server/service/script/RuleNodeJsScriptEngineTest.java
  27. 8
      common/message/src/main/java/org/thingsboard/server/common/msg/MsgType.java
  28. 49
      common/message/src/main/java/org/thingsboard/server/common/msg/TbMsg.java
  29. 6
      common/message/src/main/java/org/thingsboard/server/common/msg/queue/QueueToRuleEngineMsg.java
  30. 2
      common/message/src/main/java/org/thingsboard/server/common/msg/queue/TbMsgCallback.java
  31. 5
      common/queue/src/main/proto/queue.proto
  32. 77
      common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java
  33. 2
      common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/util/JsonUtils.java
  34. 3
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbMsgCountNode.java
  35. 3
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbRedisQueueProcessor.java
  36. 3
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transaction/TbSynchronizationBeginNode.java
  37. 12
      rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbAlarmNodeTest.java
  38. 7
      rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbJsFilterNodeTest.java
  39. 3
      rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbJsSwitchNodeTest.java
  40. 3
      rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/mail/TbMsgToEmailNodeTest.java
  41. 17
      rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNodeTest.java
  42. 7
      rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbChangeOriginatorNodeTest.java
  43. 7
      rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbTransformMsgNodeTest.java

18
application/src/main/java/org/thingsboard/server/actors/app/AppActor.java

@ -20,14 +20,9 @@ import akka.actor.LocalActorRef;
import akka.actor.OneForOneStrategy; import akka.actor.OneForOneStrategy;
import akka.actor.Props; import akka.actor.Props;
import akka.actor.SupervisorStrategy; import akka.actor.SupervisorStrategy;
import akka.actor.SupervisorStrategy.Directive;
import akka.actor.Terminated; import akka.actor.Terminated;
import akka.event.Logging;
import akka.event.LoggingAdapter;
import akka.japi.Function;
import com.google.common.collect.BiMap; import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap; import com.google.common.collect.HashBiMap;
import lombok.extern.slf4j.Slf4j;
import org.thingsboard.server.actors.ActorSystemContext; import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.actors.ruleChain.RuleChainManagerActor; import org.thingsboard.server.actors.ruleChain.RuleChainManagerActor;
import org.thingsboard.server.actors.service.ContextBasedCreator; import org.thingsboard.server.actors.service.ContextBasedCreator;
@ -43,17 +38,12 @@ import org.thingsboard.server.common.msg.MsgType;
import org.thingsboard.server.common.msg.TbActorMsg; import org.thingsboard.server.common.msg.TbActorMsg;
import org.thingsboard.server.common.msg.aware.TenantAwareMsg; import org.thingsboard.server.common.msg.aware.TenantAwareMsg;
import org.thingsboard.server.common.msg.cluster.SendToClusterMsg; import org.thingsboard.server.common.msg.cluster.SendToClusterMsg;
import org.thingsboard.server.common.msg.cluster.ServerAddress;
import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg;
import org.thingsboard.server.common.msg.system.ServiceToRuleEngineMsg; import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg;
import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.tenant.TenantService; import org.thingsboard.server.dao.tenant.TenantService;
import scala.concurrent.duration.Duration; import scala.concurrent.duration.Duration;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
public class AppActor extends RuleChainManagerActor { public class AppActor extends RuleChainManagerActor {
private static final TenantId SYSTEM_TENANT = new TenantId(ModelConstants.NULL_UUID); private static final TenantId SYSTEM_TENANT = new TenantId(ModelConstants.NULL_UUID);
@ -97,8 +87,8 @@ public class AppActor extends RuleChainManagerActor {
case COMPONENT_LIFE_CYCLE_MSG: case COMPONENT_LIFE_CYCLE_MSG:
onComponentLifecycleMsg((ComponentLifecycleMsg) msg); onComponentLifecycleMsg((ComponentLifecycleMsg) msg);
break; break;
case SERVICE_TO_RULE_ENGINE_MSG: case QUEUE_TO_RULE_ENGINE_MSG:
onServiceToRuleEngineMsg((ServiceToRuleEngineMsg) msg); onQueueToRuleEngineMsg((QueueToRuleEngineMsg) msg);
break; break;
case TRANSPORT_TO_DEVICE_ACTOR_MSG: case TRANSPORT_TO_DEVICE_ACTOR_MSG:
case DEVICE_ATTRIBUTES_UPDATE_TO_DEVICE_ACTOR_MSG: case DEVICE_ATTRIBUTES_UPDATE_TO_DEVICE_ACTOR_MSG:
@ -145,7 +135,7 @@ public class AppActor extends RuleChainManagerActor {
// } // }
} }
private void onServiceToRuleEngineMsg(ServiceToRuleEngineMsg msg) { private void onQueueToRuleEngineMsg(QueueToRuleEngineMsg msg) {
if (SYSTEM_TENANT.equals(msg.getTenantId())) { if (SYSTEM_TENANT.equals(msg.getTenantId())) {
// this may be a notification about system entities created. // this may be a notification about system entities created.
// log.warn("[{}] Invalid service to rule engine msg called. System messages are not supported yet: {}", SYSTEM_TENANT, msg); // log.warn("[{}] Invalid service to rule engine msg called. System messages are not supported yet: {}", SYSTEM_TENANT, msg);

24
application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java

@ -65,12 +65,12 @@ import org.thingsboard.server.gen.transport.TransportProtos.ToDeviceRpcResponseM
import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg; import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg;
import org.thingsboard.server.gen.transport.TransportProtos.TsKvListProto; import org.thingsboard.server.gen.transport.TransportProtos.TsKvListProto;
import org.thingsboard.server.gen.transport.TransportProtos.TsKvProto; import org.thingsboard.server.gen.transport.TransportProtos.TsKvProto;
import org.thingsboard.server.service.queue.TbMsgCallback; import org.thingsboard.server.common.msg.queue.TbMsgCallback;
import org.thingsboard.server.service.rpc.FromDeviceRpcResponse; import org.thingsboard.server.service.rpc.FromDeviceRpcResponse;
import org.thingsboard.server.service.rpc.ToDeviceRpcRequestActorMsg; import org.thingsboard.server.service.rpc.ToDeviceRpcRequestActorMsg;
import org.thingsboard.server.service.rpc.ToServerRpcResponseActorMsg; import org.thingsboard.server.service.rpc.ToServerRpcResponseActorMsg;
import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWrapper; import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWrapper;
import org.thingsboard.server.utils.JsonUtils; import org.thingsboard.server.common.transport.util.JsonUtils;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
@ -224,6 +224,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
} }
void process(ActorContext context, TransportToDeviceActorMsgWrapper wrapper) { void process(ActorContext context, TransportToDeviceActorMsgWrapper wrapper) {
//TODO 2.5
boolean reportDeviceActivity = true; boolean reportDeviceActivity = true;
TransportToDeviceActorMsg msg = wrapper.getMsg(); TransportToDeviceActorMsg msg = wrapper.getMsg();
TbMsgCallback callback = wrapper.getCallback(); TbMsgCallback callback = wrapper.getCallback();
@ -329,23 +330,6 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
return new HashSet<>(strings); return new HashSet<>(strings);
} }
private void handlePostAttributesRequest(ActorContext context, SessionInfoProto sessionInfo, PostAttributeMsg postAttributes) {
JsonObject json = JsonUtils.getJsonObject(postAttributes.getKvList());
TbMsg tbMsg = new TbMsg(UUIDs.timeBased(), SessionMsgType.POST_ATTRIBUTES_REQUEST.name(), deviceId, defaultMetaData.copy(),
TbMsgDataType.JSON, gson.toJson(json), null, null, 0L);
pushToRuleEngine(context, tbMsg);
}
private void handlePostTelemetryRequest(ActorContext context, SessionInfoProto sessionInfo, PostTelemetryMsg postTelemetry) {
for (TsKvListProto tsKv : postTelemetry.getTsKvListList()) {
JsonObject json = JsonUtils.getJsonObject(tsKv.getKvList());
TbMsgMetaData metaData = defaultMetaData.copy();
metaData.putValue("ts", tsKv.getTs() + "");
TbMsg tbMsg = new TbMsg(UUIDs.timeBased(), SessionMsgType.POST_TELEMETRY_REQUEST.name(), deviceId, metaData, TbMsgDataType.JSON, gson.toJson(json), null, null, 0L);
pushToRuleEngine(context, tbMsg);
}
}
private void handleClientSideRPCRequest(ActorContext context, SessionInfoProto sessionInfo, TransportProtos.ToServerRpcRequestMsg request) { private void handleClientSideRPCRequest(ActorContext context, SessionInfoProto sessionInfo, TransportProtos.ToServerRpcRequestMsg request) {
UUID sessionId = getSessionId(sessionInfo); UUID sessionId = getSessionId(sessionInfo);
JsonObject json = new JsonObject(); JsonObject json = new JsonObject();
@ -354,7 +338,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
TbMsgMetaData requestMetaData = defaultMetaData.copy(); TbMsgMetaData requestMetaData = defaultMetaData.copy();
requestMetaData.putValue("requestId", Integer.toString(request.getRequestId())); requestMetaData.putValue("requestId", Integer.toString(request.getRequestId()));
TbMsg tbMsg = new TbMsg(UUIDs.timeBased(), SessionMsgType.TO_SERVER_RPC_REQUEST.name(), deviceId, requestMetaData, TbMsgDataType.JSON, gson.toJson(json), null, null, 0L); TbMsg tbMsg = new TbMsg(UUIDs.timeBased(), SessionMsgType.TO_SERVER_RPC_REQUEST.name(), deviceId, requestMetaData, TbMsgDataType.JSON, gson.toJson(json), null, null, null);
context.parent().tell(new DeviceActorToRuleEngineMsg(context.self(), tbMsg), context.self()); context.parent().tell(new DeviceActorToRuleEngineMsg(context.self(), tbMsg), context.self());
scheduleMsgWithDelay(context, new DeviceActorClientSideRpcTimeoutMsg(request.getRequestId(), systemContext.getClientSideRpcTimeout()), systemContext.getClientSideRpcTimeout()); scheduleMsgWithDelay(context, new DeviceActorClientSideRpcTimeoutMsg(request.getRequestId(), systemContext.getClientSideRpcTimeout()), systemContext.getClientSideRpcTimeout());

26
application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java

@ -23,7 +23,6 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import io.netty.channel.EventLoopGroup; import io.netty.channel.EventLoopGroup;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StringUtils;
import org.thingsboard.common.util.ListeningExecutor; import org.thingsboard.common.util.ListeningExecutor;
import org.thingsboard.rule.engine.api.MailService; import org.thingsboard.rule.engine.api.MailService;
import org.thingsboard.rule.engine.api.RuleChainTransactionService; import org.thingsboard.rule.engine.api.RuleChainTransactionService;
@ -47,12 +46,11 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.rpc.ToDeviceRpcRequestBody; import org.thingsboard.server.common.data.rpc.ToDeviceRpcRequestBody;
import org.thingsboard.server.common.data.rule.RuleNode; import org.thingsboard.server.common.data.rule.RuleNode;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgDataType;
import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.TbMsgMetaData;
import org.thingsboard.server.common.msg.cluster.SendToClusterMsg; import org.thingsboard.server.common.msg.cluster.SendToClusterMsg;
import org.thingsboard.server.common.msg.cluster.ServerAddress;
import org.thingsboard.server.common.msg.cluster.ServerType;
import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest; import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest;
import org.thingsboard.server.common.msg.system.ServiceToRuleEngineMsg; import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg;
import org.thingsboard.server.dao.alarm.AlarmService; import org.thingsboard.server.dao.alarm.AlarmService;
import org.thingsboard.server.dao.asset.AssetService; import org.thingsboard.server.dao.asset.AssetService;
import org.thingsboard.server.dao.attributes.AttributesService; import org.thingsboard.server.dao.attributes.AttributesService;
@ -71,7 +69,6 @@ import org.thingsboard.server.service.script.RuleNodeJsScriptEngine;
import scala.concurrent.duration.Duration; import scala.concurrent.duration.Duration;
import java.util.Collections; import java.util.Collections;
import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -146,23 +143,25 @@ class DefaultTbContext implements TbContext {
@Override @Override
public TbMsg newMsg(String type, EntityId originator, TbMsgMetaData metaData, String data) { public TbMsg newMsg(String type, EntityId originator, TbMsgMetaData metaData, String data) {
return new TbMsg(UUIDs.timeBased(), type, originator, metaData.copy(), data, nodeCtx.getSelf().getRuleChainId(), nodeCtx.getSelf().getId(), 0); return new TbMsg(UUIDs.timeBased(), type, originator, metaData.copy(), TbMsgDataType.JSON, data, nodeCtx.getSelf().getRuleChainId(), nodeCtx.getSelf().getId(),null);
} }
@Override @Override
public TbMsg transformMsg(TbMsg origMsg, String type, EntityId originator, TbMsgMetaData metaData, String data) { public TbMsg transformMsg(TbMsg origMsg, String type, EntityId originator, TbMsgMetaData metaData, String data) {
return new TbMsg(origMsg.getId(), type, originator, metaData.copy(), origMsg.getDataType(), data, origMsg.getTransactionData(), origMsg.getRuleChainId(), origMsg.getRuleNodeId(), 0); return new TbMsg(origMsg.getId(), type, originator, metaData.copy(), origMsg.getDataType(),
data, origMsg.getTransactionData(), origMsg.getRuleChainId(), origMsg.getRuleNodeId(), null);
} }
@Override @Override
public void sendTbMsgToRuleEngine(TbMsg msg) { public void sendTbMsgToRuleEngine(TbMsg msg) {
mainCtx.getActorService().onMsg(new SendToClusterMsg(msg.getOriginator(), new ServiceToRuleEngineMsg(getTenantId(), msg))); mainCtx.getActorService().onMsg(new SendToClusterMsg(msg.getOriginator(), new QueueToRuleEngineMsg(getTenantId(), msg)));
} }
public TbMsg customerCreatedMsg(Customer customer, RuleNodeId ruleNodeId) { public TbMsg customerCreatedMsg(Customer customer, RuleNodeId ruleNodeId) {
try { try {
ObjectNode entityNode = mapper.valueToTree(customer); ObjectNode entityNode = mapper.valueToTree(customer);
return new TbMsg(UUIDs.timeBased(), DataConstants.ENTITY_CREATED, customer.getId(), getActionMetaData(ruleNodeId), mapper.writeValueAsString(entityNode), null, null, 0L); return new TbMsg(UUIDs.timeBased(), DataConstants.ENTITY_CREATED, customer.getId(),
getActionMetaData(ruleNodeId), TbMsgDataType.JSON, mapper.writeValueAsString(entityNode), null, null, null);
} catch (JsonProcessingException | IllegalArgumentException e) { } catch (JsonProcessingException | IllegalArgumentException e) {
throw new RuntimeException("Failed to process customer created msg: " + e); throw new RuntimeException("Failed to process customer created msg: " + e);
} }
@ -171,7 +170,8 @@ class DefaultTbContext implements TbContext {
public TbMsg deviceCreatedMsg(Device device, RuleNodeId ruleNodeId) { public TbMsg deviceCreatedMsg(Device device, RuleNodeId ruleNodeId) {
try { try {
ObjectNode entityNode = mapper.valueToTree(device); ObjectNode entityNode = mapper.valueToTree(device);
return new TbMsg(UUIDs.timeBased(), DataConstants.ENTITY_CREATED, device.getId(), getActionMetaData(ruleNodeId), mapper.writeValueAsString(entityNode), null, null, 0L); return new TbMsg(UUIDs.timeBased(), DataConstants.ENTITY_CREATED, device.getId(), getActionMetaData(ruleNodeId),
TbMsgDataType.JSON, mapper.writeValueAsString(entityNode), null, null, null);
} catch (JsonProcessingException | IllegalArgumentException e) { } catch (JsonProcessingException | IllegalArgumentException e) {
throw new RuntimeException("Failed to process device created msg: " + e); throw new RuntimeException("Failed to process device created msg: " + e);
} }
@ -180,7 +180,8 @@ class DefaultTbContext implements TbContext {
public TbMsg assetCreatedMsg(Asset asset, RuleNodeId ruleNodeId) { public TbMsg assetCreatedMsg(Asset asset, RuleNodeId ruleNodeId) {
try { try {
ObjectNode entityNode = mapper.valueToTree(asset); ObjectNode entityNode = mapper.valueToTree(asset);
return new TbMsg(UUIDs.timeBased(), DataConstants.ENTITY_CREATED, asset.getId(), getActionMetaData(ruleNodeId), mapper.writeValueAsString(entityNode), null, null, 0L); return new TbMsg(UUIDs.timeBased(), DataConstants.ENTITY_CREATED, asset.getId(), getActionMetaData(ruleNodeId),
TbMsgDataType.JSON, mapper.writeValueAsString(entityNode), null, null, null);
} catch (JsonProcessingException | IllegalArgumentException e) { } catch (JsonProcessingException | IllegalArgumentException e) {
throw new RuntimeException("Failed to process asset created msg: " + e); throw new RuntimeException("Failed to process asset created msg: " + e);
} }
@ -189,7 +190,8 @@ class DefaultTbContext implements TbContext {
public TbMsg alarmCreatedMsg(Alarm alarm, RuleNodeId ruleNodeId) { public TbMsg alarmCreatedMsg(Alarm alarm, RuleNodeId ruleNodeId) {
try { try {
ObjectNode entityNode = mapper.valueToTree(alarm); ObjectNode entityNode = mapper.valueToTree(alarm);
return new TbMsg(UUIDs.timeBased(), DataConstants.ENTITY_CREATED, alarm.getId(), getActionMetaData(ruleNodeId), mapper.writeValueAsString(entityNode), null, null, 0L); return new TbMsg(UUIDs.timeBased(), DataConstants.ENTITY_CREATED, alarm.getId(), getActionMetaData(ruleNodeId),
TbMsgDataType.JSON, mapper.writeValueAsString(entityNode), null, null, null);
} catch (JsonProcessingException | IllegalArgumentException e) { } catch (JsonProcessingException | IllegalArgumentException e) {
throw new RuntimeException("Failed to process alarm created msg: " + e); throw new RuntimeException("Failed to process alarm created msg: " + e);
} }

7
application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainActor.java

@ -15,7 +15,6 @@
*/ */
package org.thingsboard.server.actors.ruleChain; package org.thingsboard.server.actors.ruleChain;
import akka.actor.ActorInitializationException;
import akka.actor.OneForOneStrategy; import akka.actor.OneForOneStrategy;
import akka.actor.SupervisorStrategy; import akka.actor.SupervisorStrategy;
import org.thingsboard.server.actors.ActorSystemContext; import org.thingsboard.server.actors.ActorSystemContext;
@ -26,7 +25,7 @@ import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.msg.TbActorMsg; import org.thingsboard.server.common.msg.TbActorMsg;
import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg;
import org.thingsboard.server.common.msg.system.ServiceToRuleEngineMsg; import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg;
import scala.concurrent.duration.Duration; import scala.concurrent.duration.Duration;
public class RuleChainActor extends ComponentActor<RuleChainId, RuleChainActorMessageProcessor> { public class RuleChainActor extends ComponentActor<RuleChainId, RuleChainActorMessageProcessor> {
@ -43,8 +42,8 @@ public class RuleChainActor extends ComponentActor<RuleChainId, RuleChainActorMe
case COMPONENT_LIFE_CYCLE_MSG: case COMPONENT_LIFE_CYCLE_MSG:
onComponentLifecycleMsg((ComponentLifecycleMsg) msg); onComponentLifecycleMsg((ComponentLifecycleMsg) msg);
break; break;
case SERVICE_TO_RULE_ENGINE_MSG: case QUEUE_TO_RULE_ENGINE_MSG:
processor.onServiceToRuleEngineMsg((ServiceToRuleEngineMsg) msg); processor.onServiceToRuleEngineMsg((QueueToRuleEngineMsg) msg);
break; break;
case DEVICE_ACTOR_TO_RULE_ENGINE_MSG: case DEVICE_ACTOR_TO_RULE_ENGINE_MSG:
processor.onDeviceActorToRuleEngineMsg((DeviceActorToRuleEngineMsg) msg); processor.onDeviceActorToRuleEngineMsg((DeviceActorToRuleEngineMsg) msg);

13
application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainActorMessageProcessor.java

@ -18,11 +18,8 @@ package org.thingsboard.server.actors.ruleChain;
import akka.actor.ActorContext; import akka.actor.ActorContext;
import akka.actor.ActorRef; import akka.actor.ActorRef;
import akka.actor.Props; import akka.actor.Props;
import akka.event.LoggingAdapter;
import com.datastax.driver.core.utils.UUIDs; import com.datastax.driver.core.utils.UUIDs;
import java.util.Optional;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.thingsboard.server.actors.ActorSystemContext; import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.actors.device.DeviceActorToRuleEngineMsg; import org.thingsboard.server.actors.device.DeviceActorToRuleEngineMsg;
@ -42,7 +39,7 @@ import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.cluster.ClusterEventMsg; import org.thingsboard.server.common.msg.cluster.ClusterEventMsg;
import org.thingsboard.server.common.msg.cluster.ServerAddress; import org.thingsboard.server.common.msg.cluster.ServerAddress;
import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg;
import org.thingsboard.server.common.msg.system.ServiceToRuleEngineMsg; import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg;
import org.thingsboard.server.dao.rule.RuleChainService; import org.thingsboard.server.dao.rule.RuleChainService;
import java.util.ArrayList; import java.util.ArrayList;
@ -192,7 +189,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh
state = ComponentLifecycleState.ACTIVE; state = ComponentLifecycleState.ACTIVE;
} }
void onServiceToRuleEngineMsg(ServiceToRuleEngineMsg envelope) { void onServiceToRuleEngineMsg(QueueToRuleEngineMsg envelope) {
log.trace("[{}][{}] Processing message [{}]: {}", entityId, firstId, envelope.getTbMsg().getId(), envelope.getTbMsg()); log.trace("[{}][{}] Processing message [{}]: {}", entityId, firstId, envelope.getTbMsg().getId(), envelope.getTbMsg());
checkActive(); checkActive();
if (firstNode != null) { if (firstNode != null) {
@ -301,14 +298,14 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh
private void enqueueAndForwardMsgCopyToChain(TbMsg msg, EntityId target, String fromRelationType) { private void enqueueAndForwardMsgCopyToChain(TbMsg msg, EntityId target, String fromRelationType) {
RuleChainId targetRCId = new RuleChainId(target.getId()); RuleChainId targetRCId = new RuleChainId(target.getId());
TbMsg copyMsg = msg.copy(UUIDs.timeBased(), targetRCId, null, DEFAULT_CLUSTER_PARTITION); TbMsg copyMsg = msg.copy(UUIDs.timeBased(), targetRCId, null, null);
parent.tell(new RuleChainToRuleChainMsg(new RuleChainId(target.getId()), entityId, copyMsg, fromRelationType, true), self); parent.tell(new RuleChainToRuleChainMsg(new RuleChainId(target.getId()), entityId, copyMsg, fromRelationType, true), self);
} }
private void enqueueAndForwardMsgCopyToNode(TbMsg msg, EntityId target, String fromRelationType) { private void enqueueAndForwardMsgCopyToNode(TbMsg msg, EntityId target, String fromRelationType) {
RuleNodeId targetId = new RuleNodeId(target.getId()); RuleNodeId targetId = new RuleNodeId(target.getId());
RuleNodeCtx targetNodeCtx = nodeActors.get(targetId); RuleNodeCtx targetNodeCtx = nodeActors.get(targetId);
TbMsg copy = msg.copy(UUIDs.timeBased(), entityId, targetId, DEFAULT_CLUSTER_PARTITION); TbMsg copy = msg.copy(UUIDs.timeBased(), entityId, targetId, null);
pushMsgToNode(targetNodeCtx, copy, fromRelationType); pushMsgToNode(targetNodeCtx, copy, fromRelationType);
} }
@ -331,6 +328,6 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh
private TbMsg enrichWithRuleChainId(TbMsg tbMsg) { private TbMsg enrichWithRuleChainId(TbMsg tbMsg) {
// We don't put firstNodeId because it may change over time; // We don't put firstNodeId because it may change over time;
return new TbMsg(tbMsg.getId(), tbMsg.getType(), tbMsg.getOriginator(), tbMsg.getMetaData().copy(), tbMsg.getData(), entityId, null, 0); return new TbMsg(tbMsg.getId(), tbMsg.getType(), tbMsg.getOriginator(), tbMsg.getMetaData().copy(), tbMsg.getDataType(), tbMsg.getData(), entityId, null, null);
} }
} }

6
application/src/main/java/org/thingsboard/server/actors/shared/EntityActorsManager.java

@ -24,9 +24,11 @@ import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap; import com.google.common.collect.HashBiMap;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.thingsboard.server.actors.ActorSystemContext; import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.actors.ruleChain.RuleChainActor;
import org.thingsboard.server.actors.service.ContextAwareActor; import org.thingsboard.server.actors.service.ContextAwareActor;
import org.thingsboard.server.common.data.SearchTextBased; import org.thingsboard.server.common.data.SearchTextBased;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UUIDBased; import org.thingsboard.server.common.data.id.UUIDBased;
import org.thingsboard.server.common.data.page.PageDataIterable; import org.thingsboard.server.common.data.page.PageDataIterable;
@ -84,4 +86,8 @@ public abstract class EntityActorsManager<T extends EntityId, A extends UntypedA
actors.remove(id); actors.remove(id);
} }
public ActorRef get(T id) {
return actors.get(id);
}
} }

35
application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java

@ -25,7 +25,6 @@ import akka.actor.Terminated;
import akka.japi.Function; import akka.japi.Function;
import com.google.common.collect.BiMap; import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap; import com.google.common.collect.HashBiMap;
import lombok.extern.slf4j.Slf4j;
import org.thingsboard.server.actors.ActorSystemContext; import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.actors.device.DeviceActorCreator; import org.thingsboard.server.actors.device.DeviceActorCreator;
import org.thingsboard.server.actors.device.DeviceActorToRuleEngineMsg; import org.thingsboard.server.actors.device.DeviceActorToRuleEngineMsg;
@ -37,18 +36,15 @@ import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.common.msg.TbActorMsg; import org.thingsboard.server.common.msg.TbActorMsg;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.aware.DeviceAwareMsg; import org.thingsboard.server.common.msg.aware.DeviceAwareMsg;
import org.thingsboard.server.common.msg.aware.RuleChainAwareMsg; import org.thingsboard.server.common.msg.aware.RuleChainAwareMsg;
import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg;
import org.thingsboard.server.common.msg.system.ServiceToRuleEngineMsg; import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg;
import scala.concurrent.duration.Duration; import scala.concurrent.duration.Duration;
import java.util.HashMap;
import java.util.Map;
public class TenantActor extends RuleChainManagerActor { public class TenantActor extends RuleChainManagerActor {
private final TenantId tenantId; private final TenantId tenantId;
@ -90,8 +86,8 @@ public class TenantActor extends RuleChainManagerActor {
case COMPONENT_LIFE_CYCLE_MSG: case COMPONENT_LIFE_CYCLE_MSG:
onComponentLifecycleMsg((ComponentLifecycleMsg) msg); onComponentLifecycleMsg((ComponentLifecycleMsg) msg);
break; break;
case SERVICE_TO_RULE_ENGINE_MSG: case QUEUE_TO_RULE_ENGINE_MSG:
onServiceToRuleEngineMsg((ServiceToRuleEngineMsg) msg); onQueueToRuleEngineMsg((QueueToRuleEngineMsg) msg);
break; break;
case DEVICE_ACTOR_TO_RULE_ENGINE_MSG: case DEVICE_ACTOR_TO_RULE_ENGINE_MSG:
onDeviceActorToRuleEngineMsg((DeviceActorToRuleEngineMsg) msg); onDeviceActorToRuleEngineMsg((DeviceActorToRuleEngineMsg) msg);
@ -114,11 +110,24 @@ public class TenantActor extends RuleChainManagerActor {
return true; return true;
} }
private void onServiceToRuleEngineMsg(ServiceToRuleEngineMsg msg) { private void onQueueToRuleEngineMsg(QueueToRuleEngineMsg msg) {
if (ruleChainManager.getRootChainActor() != null) { TbMsg tbMsg = msg.getTbMsg();
ruleChainManager.getRootChainActor().tell(msg, self()); if (tbMsg.getRuleChainId() == null) {
if (ruleChainManager.getRootChainActor() != null) {
ruleChainManager.getRootChainActor().tell(msg, self());
} else {
tbMsg.getCallback().onFailure(new RuntimeException("No Root Rule Chain available!"));
log.info("[{}] No Root Chain: {}", tenantId, msg);
}
} else { } else {
log.info("[{}] No Root Chain: {}", tenantId, msg); ActorRef ruleChainActor = ruleChainManager.get(tbMsg.getRuleChainId());
if (ruleChainActor != null) {
ruleChainActor.tell(msg, self());
} else {
log.trace("Received message for non-existing rule chain: [{}]", tbMsg.getRuleChainId());
//TODO: 3.1 Log it to dead letters queue;
tbMsg.getCallback().onSuccess();
}
} }
} }
@ -172,7 +181,7 @@ public class TenantActor extends RuleChainManagerActor {
if (removed) { if (removed) {
log.debug("[{}] Removed actor:", terminated); log.debug("[{}] Removed actor:", terminated);
} else { } else {
log.warn("[{}] Removed actor was not found in the device map!"); log.warn("Removed actor was not found in the device map!");
} }
} else { } else {
throw new IllegalStateException("Remote actors are not supported!"); throw new IllegalStateException("Remote actors are not supported!");

6
application/src/main/java/org/thingsboard/server/controller/BaseController.java

@ -72,7 +72,7 @@ import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgDataType; import org.thingsboard.server.common.msg.TbMsgDataType;
import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.TbMsgMetaData;
import org.thingsboard.server.common.msg.cluster.SendToClusterMsg; import org.thingsboard.server.common.msg.cluster.SendToClusterMsg;
import org.thingsboard.server.common.msg.system.ServiceToRuleEngineMsg; import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg;
import org.thingsboard.server.dao.alarm.AlarmService; import org.thingsboard.server.dao.alarm.AlarmService;
import org.thingsboard.server.dao.asset.AssetService; import org.thingsboard.server.dao.asset.AssetService;
import org.thingsboard.server.dao.attributes.AttributesService; import org.thingsboard.server.dao.attributes.AttributesService;
@ -661,8 +661,8 @@ public abstract class BaseController {
} }
TbMsg tbMsg = new TbMsg(UUIDs.timeBased(), msgType, entityId, metaData, TbMsgDataType.JSON TbMsg tbMsg = new TbMsg(UUIDs.timeBased(), msgType, entityId, metaData, TbMsgDataType.JSON
, json.writeValueAsString(entityNode) , json.writeValueAsString(entityNode)
, null, null, 0L); , null, null, null);
actorService.onMsg(new SendToClusterMsg(entityId, new ServiceToRuleEngineMsg(user.getTenantId(), tbMsg))); actorService.onMsg(new SendToClusterMsg(entityId, new QueueToRuleEngineMsg(user.getTenantId(), tbMsg)));
} catch (Exception e) { } catch (Exception e) {
log.warn("[{}] Failed to push entity action to rule engine: {}", entityId, actionType, e); log.warn("[{}] Failed to push entity action to rule engine: {}", entityId, actionType, e);
} }

3
application/src/main/java/org/thingsboard/server/controller/RuleChainController.java

@ -52,6 +52,7 @@ import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.common.data.rule.RuleChainMetaData; import org.thingsboard.server.common.data.rule.RuleChainMetaData;
import org.thingsboard.server.common.data.rule.RuleNode; import org.thingsboard.server.common.data.rule.RuleNode;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgDataType;
import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.TbMsgMetaData;
import org.thingsboard.server.dao.event.EventService; import org.thingsboard.server.dao.event.EventService;
import org.thingsboard.server.service.script.JsInvokeService; import org.thingsboard.server.service.script.JsInvokeService;
@ -317,7 +318,7 @@ public class RuleChainController extends BaseController {
ScriptEngine engine = null; ScriptEngine engine = null;
try { try {
engine = new RuleNodeJsScriptEngine(jsInvokeService, getCurrentUser().getId(), script, argNames); engine = new RuleNodeJsScriptEngine(jsInvokeService, getCurrentUser().getId(), script, argNames);
TbMsg inMsg = new TbMsg(UUIDs.timeBased(), msgType, null, new TbMsgMetaData(metadata), data, null, null, 0L); TbMsg inMsg = new TbMsg(UUIDs.timeBased(), msgType, null, new TbMsgMetaData(metadata), TbMsgDataType.JSON, data, null, null, null);
switch (scriptType) { switch (scriptType) {
case "update": case "update":
output = msgToOutput(engine.executeUpdate(inMsg)); output = msgToOutput(engine.executeUpdate(inMsg));

2
application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java

@ -25,6 +25,7 @@ import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.thingsboard.common.util.ThingsBoardThreadFactory; import org.thingsboard.common.util.ThingsBoardThreadFactory;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.msg.queue.TbMsgCallback;
import org.thingsboard.server.queue.TbQueueConsumer; import org.thingsboard.server.queue.TbQueueConsumer;
import org.thingsboard.server.actors.ActorSystemContext; import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.queue.common.TbProtoQueueMsg; import org.thingsboard.server.queue.common.TbProtoQueueMsg;
@ -38,7 +39,6 @@ import org.thingsboard.server.service.state.DeviceStateService;
import org.thingsboard.server.service.subscription.LocalSubscriptionService; import org.thingsboard.server.service.subscription.LocalSubscriptionService;
import org.thingsboard.server.service.subscription.SubscriptionManagerService; import org.thingsboard.server.service.subscription.SubscriptionManagerService;
import org.thingsboard.server.service.subscription.TbSubscriptionUtils; import org.thingsboard.server.service.subscription.TbSubscriptionUtils;
import org.thingsboard.server.service.telemetry.sub.SubscriptionUpdate;
import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWrapper; import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWrapper;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;

24
application/src/main/java/org/thingsboard/server/service/queue/DefaultTbRuleEngineConsumerService.java

@ -15,6 +15,8 @@
*/ */
package org.thingsboard.server.service.queue; package org.thingsboard.server.service.queue;
import akka.actor.ActorRef;
import com.google.protobuf.ByteString;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
@ -23,6 +25,10 @@ import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.thingsboard.common.util.ThingsBoardThreadFactory; import org.thingsboard.common.util.ThingsBoardThreadFactory;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg;
import org.thingsboard.server.common.msg.queue.TbMsgCallback;
import org.thingsboard.server.queue.TbQueueConsumer; import org.thingsboard.server.queue.TbQueueConsumer;
import org.thingsboard.server.actors.ActorSystemContext; import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.queue.common.TbProtoQueueMsg; import org.thingsboard.server.queue.common.TbProtoQueueMsg;
@ -48,7 +54,6 @@ import java.util.stream.Collectors;
@Slf4j @Slf4j
public class DefaultTbRuleEngineConsumerService implements TbRuleEngineConsumerService { public class DefaultTbRuleEngineConsumerService implements TbRuleEngineConsumerService {
@Value("${queue.rule_engine.poll_interval}") @Value("${queue.rule_engine.poll_interval}")
private long pollDuration; private long pollDuration;
@Value("${queue.rule_engine.pack_processing_timeout}") @Value("${queue.rule_engine.pack_processing_timeout}")
@ -86,7 +91,7 @@ public class DefaultTbRuleEngineConsumerService implements TbRuleEngineConsumerS
while (!stopped) { while (!stopped) {
try { try {
List<TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> msgs = consumer.poll(pollDuration); List<TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> msgs = consumer.poll(pollDuration);
if(msgs.isEmpty()){ if (msgs.isEmpty()) {
continue; continue;
} }
ConcurrentMap<UUID, TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> ackMap = msgs.stream().collect( ConcurrentMap<UUID, TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> ackMap = msgs.stream().collect(
@ -96,9 +101,10 @@ public class DefaultTbRuleEngineConsumerService implements TbRuleEngineConsumerS
TbMsgCallback callback = new MsgPackCallback<>(id, processingTimeoutLatch, ackMap); TbMsgCallback callback = new MsgPackCallback<>(id, processingTimeoutLatch, ackMap);
try { try {
TransportProtos.ToRuleEngineMsg toRuleEngineMsg = msg.getValue(); TransportProtos.ToRuleEngineMsg toRuleEngineMsg = msg.getValue();
TenantId tenantId = new TenantId(new UUID(toRuleEngineMsg.getTenantIdMSB(), toRuleEngineMsg.getTenantIdLSB()));
log.trace("Forwarding message to rule engine {}", toRuleEngineMsg); log.trace("Forwarding message to rule engine {}", toRuleEngineMsg);
if (toRuleEngineMsg.hasToRuleEngineMsg()) { if (toRuleEngineMsg.getTbMsg() != null && !toRuleEngineMsg.getTbMsg().isEmpty()) {
forwardToRuleEngineActor(toRuleEngineMsg.getToRuleEngineMsg(), callback); forwardToRuleEngineActor(tenantId, toRuleEngineMsg.getTbMsg(), callback);
} else { } else {
callback.onSuccess(); callback.onSuccess();
} }
@ -122,16 +128,16 @@ public class DefaultTbRuleEngineConsumerService implements TbRuleEngineConsumerS
}); });
} }
//TODO 2.5 private void forwardToRuleEngineActor(TenantId tenantId, ByteString tbMsgData, TbMsgCallback callback) {
private void forwardToRuleEngineActor(TransportProtos.TransportToRuleEngineMsg toRuleEngineMsg, TbMsgCallback callback) { TbMsg tbMsg = TbMsg.fromBytes(tbMsgData.toByteArray(), callback);
log.info("Received RULE ENGINE msg: {}", toRuleEngineMsg); log.info("[{}] Received RULE ENGINE msg: {}", tbMsg.getType(), tbMsg);
actorContext.getAppActor().tell(new QueueToRuleEngineMsg(tenantId, tbMsg), ActorRef.noSender());
// if (statsEnabled) { // if (statsEnabled) {
// stats.log(toDeviceActorMsg); // stats.log(toDeviceActorMsg);
// } // }
// actorContext.getAppActor().tell(new TransportToDeviceActorMsgWrapper(toDeviceActorMsg, callback), ActorRef.noSender());
} }
@Scheduled(fixedDelayString = "${queue.core.stats.print_interval_ms}") @Scheduled(fixedDelayString = "${queue.rule_engine.stats.print_interval_ms}")
public void printStats() { public void printStats() {
if (statsEnabled) { if (statsEnabled) {
stats.printStats(); stats.printStats();

1
application/src/main/java/org/thingsboard/server/service/queue/MsgPackCallback.java

@ -16,6 +16,7 @@
package org.thingsboard.server.service.queue; package org.thingsboard.server.service.queue;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.thingsboard.server.common.msg.queue.TbMsgCallback;
import org.thingsboard.server.queue.common.TbProtoQueueMsg; import org.thingsboard.server.queue.common.TbProtoQueueMsg;
import java.util.UUID; import java.util.UUID;

6
application/src/main/java/org/thingsboard/server/service/rpc/DefaultDeviceRpcService.java

@ -39,7 +39,7 @@ import org.thingsboard.server.common.msg.cluster.SendToClusterMsg;
import org.thingsboard.server.common.msg.cluster.ServerAddress; import org.thingsboard.server.common.msg.cluster.ServerAddress;
import org.thingsboard.server.common.msg.core.ToServerRpcResponseMsg; import org.thingsboard.server.common.msg.core.ToServerRpcResponseMsg;
import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest; import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest;
import org.thingsboard.server.common.msg.system.ServiceToRuleEngineMsg; import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg;
import org.thingsboard.server.dao.device.DeviceService; import org.thingsboard.server.dao.device.DeviceService;
import org.thingsboard.server.gen.cluster.ClusterAPIProtos; import org.thingsboard.server.gen.cluster.ClusterAPIProtos;
@ -185,8 +185,8 @@ public class DefaultDeviceRpcService implements DeviceRpcService {
try { try {
TbMsg tbMsg = new TbMsg(UUIDs.timeBased(), DataConstants.RPC_CALL_FROM_SERVER_TO_DEVICE, msg.getDeviceId(), metaData, TbMsgDataType.JSON TbMsg tbMsg = new TbMsg(UUIDs.timeBased(), DataConstants.RPC_CALL_FROM_SERVER_TO_DEVICE, msg.getDeviceId(), metaData, TbMsgDataType.JSON
, json.writeValueAsString(entityNode) , json.writeValueAsString(entityNode)
, null, null, 0L); , null, null, null);
actorService.onMsg(new SendToClusterMsg(msg.getDeviceId(), new ServiceToRuleEngineMsg(msg.getTenantId(), tbMsg))); actorService.onMsg(new SendToClusterMsg(msg.getDeviceId(), new QueueToRuleEngineMsg(msg.getTenantId(), tbMsg)));
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }

2
application/src/main/java/org/thingsboard/server/service/script/RuleNodeJsScriptEngine.java

@ -94,7 +94,7 @@ public class RuleNodeJsScriptEngine implements org.thingsboard.rule.engine.api.S
String newData = data != null ? data : msg.getData(); String newData = data != null ? data : msg.getData();
TbMsgMetaData newMetadata = metadata != null ? new TbMsgMetaData(metadata) : msg.getMetaData().copy(); TbMsgMetaData newMetadata = metadata != null ? new TbMsgMetaData(metadata) : msg.getMetaData().copy();
String newMessageType = !StringUtils.isEmpty(messageType) ? messageType : msg.getType(); String newMessageType = !StringUtils.isEmpty(messageType) ? messageType : msg.getType();
return new TbMsg(msg.getId(), newMessageType, msg.getOriginator(), newMetadata, newData, msg.getRuleChainId(), msg.getRuleNodeId(), msg.getClusterPartition()); return new TbMsg(msg.getId(), newMessageType, msg.getOriginator(), newMetadata, msg.getDataType(), newData, msg.getRuleChainId(), msg.getRuleNodeId(), msg.getCallback());
} catch (Throwable th) { } catch (Throwable th) {
th.printStackTrace(); th.printStackTrace();
throw new RuntimeException("Failed to unbind message data from javascript result", th); throw new RuntimeException("Failed to unbind message data from javascript result", th);

8
application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java

@ -50,7 +50,7 @@ import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgDataType; import org.thingsboard.server.common.msg.TbMsgDataType;
import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.TbMsgMetaData;
import org.thingsboard.server.common.msg.cluster.SendToClusterMsg; import org.thingsboard.server.common.msg.cluster.SendToClusterMsg;
import org.thingsboard.server.common.msg.system.ServiceToRuleEngineMsg; import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg;
import org.thingsboard.server.dao.attributes.AttributesService; import org.thingsboard.server.dao.attributes.AttributesService;
import org.thingsboard.server.dao.device.DeviceService; import org.thingsboard.server.dao.device.DeviceService;
import org.thingsboard.server.dao.tenant.TenantService; import org.thingsboard.server.dao.tenant.TenantService;
@ -61,7 +61,7 @@ import org.thingsboard.server.queue.discovery.ServiceType;
import org.thingsboard.server.queue.discovery.TopicPartitionInfo; import org.thingsboard.server.queue.discovery.TopicPartitionInfo;
import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.queue.provider.TbCoreQueueProvider; import org.thingsboard.server.queue.provider.TbCoreQueueProvider;
import org.thingsboard.server.service.queue.TbMsgCallback; import org.thingsboard.server.common.msg.queue.TbMsgCallback;
import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService; import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -501,8 +501,8 @@ public class DefaultDeviceStateService implements DeviceStateService {
try { try {
TbMsg tbMsg = new TbMsg(UUIDs.timeBased(), msgType, stateData.getDeviceId(), stateData.getMetaData().copy(), TbMsgDataType.JSON TbMsg tbMsg = new TbMsg(UUIDs.timeBased(), msgType, stateData.getDeviceId(), stateData.getMetaData().copy(), TbMsgDataType.JSON
, json.writeValueAsString(state) , json.writeValueAsString(state)
, null, null, 0L); , null, null, null);
actorService.onMsg(new SendToClusterMsg(stateData.getDeviceId(), new ServiceToRuleEngineMsg(stateData.getTenantId(), tbMsg))); actorService.onMsg(new SendToClusterMsg(stateData.getDeviceId(), new QueueToRuleEngineMsg(stateData.getTenantId(), tbMsg)));
} catch (Exception e) { } catch (Exception e) {
log.warn("[{}] Failed to push inactivity alarm: {}", stateData.getDeviceId(), state, e); log.warn("[{}] Failed to push inactivity alarm: {}", stateData.getDeviceId(), state, e);
} }

2
application/src/main/java/org/thingsboard/server/service/state/DeviceStateService.java

@ -20,7 +20,7 @@ import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.queue.discovery.PartitionChangeEvent; import org.thingsboard.server.queue.discovery.PartitionChangeEvent;
import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.service.queue.TbMsgCallback; import org.thingsboard.server.common.msg.queue.TbMsgCallback;
/** /**
* Created by ashvayka on 01.05.18. * Created by ashvayka on 01.05.18.

2
application/src/main/java/org/thingsboard/server/service/subscription/DefaultLocalSubscriptionService.java

@ -36,7 +36,7 @@ import org.thingsboard.server.queue.discovery.PartitionService;
import org.thingsboard.server.queue.discovery.ServiceType; import org.thingsboard.server.queue.discovery.ServiceType;
import org.thingsboard.server.queue.discovery.TopicPartitionInfo; import org.thingsboard.server.queue.discovery.TopicPartitionInfo;
import org.thingsboard.server.queue.provider.TbCoreQueueProvider; import org.thingsboard.server.queue.provider.TbCoreQueueProvider;
import org.thingsboard.server.service.queue.TbMsgCallback; import org.thingsboard.server.common.msg.queue.TbMsgCallback;
import org.thingsboard.server.service.telemetry.TelemetryWebSocketService; import org.thingsboard.server.service.telemetry.TelemetryWebSocketService;
import org.thingsboard.server.service.telemetry.sub.SubscriptionUpdate; import org.thingsboard.server.service.telemetry.sub.SubscriptionUpdate;

3
application/src/main/java/org/thingsboard/server/service/subscription/DefaultSubscriptionManagerService.java

@ -34,7 +34,6 @@ import org.thingsboard.server.common.data.kv.BaseReadTsKvQuery;
import org.thingsboard.server.common.data.kv.BasicTsKvEntry; import org.thingsboard.server.common.data.kv.BasicTsKvEntry;
import org.thingsboard.server.common.data.kv.ReadTsKvQuery; import org.thingsboard.server.common.data.kv.ReadTsKvQuery;
import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.common.data.kv.TsKvEntry;
import org.thingsboard.server.common.msg.cluster.SendToClusterMsg;
import org.thingsboard.server.dao.attributes.AttributesService; import org.thingsboard.server.dao.attributes.AttributesService;
import org.thingsboard.server.dao.timeseries.TimeseriesService; import org.thingsboard.server.dao.timeseries.TimeseriesService;
import org.thingsboard.server.gen.transport.TransportProtos.LocalSubscriptionServiceMsgProto; import org.thingsboard.server.gen.transport.TransportProtos.LocalSubscriptionServiceMsgProto;
@ -49,7 +48,7 @@ import org.thingsboard.server.queue.discovery.ServiceType;
import org.thingsboard.server.queue.discovery.TbServiceInfoProvider; import org.thingsboard.server.queue.discovery.TbServiceInfoProvider;
import org.thingsboard.server.queue.discovery.TopicPartitionInfo; import org.thingsboard.server.queue.discovery.TopicPartitionInfo;
import org.thingsboard.server.queue.provider.TbCoreQueueProvider; import org.thingsboard.server.queue.provider.TbCoreQueueProvider;
import org.thingsboard.server.service.queue.TbMsgCallback; import org.thingsboard.server.common.msg.queue.TbMsgCallback;
import org.thingsboard.server.service.state.DefaultDeviceStateService; import org.thingsboard.server.service.state.DefaultDeviceStateService;
import org.thingsboard.server.service.state.DeviceStateService; import org.thingsboard.server.service.state.DeviceStateService;
import org.thingsboard.server.service.telemetry.sub.SubscriptionUpdate; import org.thingsboard.server.service.telemetry.sub.SubscriptionUpdate;

2
application/src/main/java/org/thingsboard/server/service/subscription/LocalSubscriptionService.java

@ -17,7 +17,7 @@ package org.thingsboard.server.service.subscription;
import org.thingsboard.server.queue.discovery.ClusterTopologyChangeEvent; import org.thingsboard.server.queue.discovery.ClusterTopologyChangeEvent;
import org.thingsboard.server.queue.discovery.PartitionChangeEvent; import org.thingsboard.server.queue.discovery.PartitionChangeEvent;
import org.thingsboard.server.service.queue.TbMsgCallback; import org.thingsboard.server.common.msg.queue.TbMsgCallback;
import org.thingsboard.server.service.telemetry.sub.SubscriptionUpdate; import org.thingsboard.server.service.telemetry.sub.SubscriptionUpdate;
public interface LocalSubscriptionService { public interface LocalSubscriptionService {

2
application/src/main/java/org/thingsboard/server/service/subscription/SubscriptionManagerService.java

@ -21,7 +21,7 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.kv.AttributeKvEntry; import org.thingsboard.server.common.data.kv.AttributeKvEntry;
import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.common.data.kv.TsKvEntry;
import org.thingsboard.server.queue.discovery.PartitionChangeEvent; import org.thingsboard.server.queue.discovery.PartitionChangeEvent;
import org.thingsboard.server.service.queue.TbMsgCallback; import org.thingsboard.server.common.msg.queue.TbMsgCallback;
import java.util.List; import java.util.List;

2
application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetrySubscriptionService.java

@ -42,7 +42,7 @@ import org.thingsboard.server.queue.discovery.PartitionService;
import org.thingsboard.server.queue.discovery.ServiceType; import org.thingsboard.server.queue.discovery.ServiceType;
import org.thingsboard.server.queue.discovery.TopicPartitionInfo; import org.thingsboard.server.queue.discovery.TopicPartitionInfo;
import org.thingsboard.server.queue.provider.TbCoreQueueProvider; import org.thingsboard.server.queue.provider.TbCoreQueueProvider;
import org.thingsboard.server.service.queue.TbMsgCallback; import org.thingsboard.server.common.msg.queue.TbMsgCallback;
import org.thingsboard.server.service.subscription.SubscriptionManagerService; import org.thingsboard.server.service.subscription.SubscriptionManagerService;
import org.thingsboard.server.service.subscription.TbSubscriptionUtils; import org.thingsboard.server.service.subscription.TbSubscriptionUtils;

2
application/src/main/java/org/thingsboard/server/service/transaction/BaseRuleChainTransactionService.java

@ -113,7 +113,7 @@ public class BaseRuleChainTransactionService implements RuleChainTransactionServ
@Override @Override
public void onRemoteTransactionMsg(ServerAddress serverAddress, byte[] data) { public void onRemoteTransactionMsg(ServerAddress serverAddress, byte[] data) {
endLocalTransaction(TbMsg.fromBytes(data), msg -> { endLocalTransaction(TbMsg.fromBytes(data, null), msg -> {
}, error -> { }, error -> {
}); });
} }

2
application/src/main/java/org/thingsboard/server/service/transport/msg/TransportToDeviceActorMsgWrapper.java

@ -23,7 +23,7 @@ import org.thingsboard.server.common.msg.TbActorMsg;
import org.thingsboard.server.common.msg.aware.DeviceAwareMsg; import org.thingsboard.server.common.msg.aware.DeviceAwareMsg;
import org.thingsboard.server.common.msg.aware.TenantAwareMsg; import org.thingsboard.server.common.msg.aware.TenantAwareMsg;
import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg; import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg;
import org.thingsboard.server.service.queue.TbMsgCallback; import org.thingsboard.server.common.msg.queue.TbMsgCallback;
import java.io.Serializable; import java.io.Serializable;
import java.util.UUID; import java.util.UUID;

21
application/src/test/java/org/thingsboard/server/rules/flow/AbstractRuleEngineFlowIntegrationTest.java

@ -16,9 +16,6 @@
package org.thingsboard.server.rules.flow; package org.thingsboard.server.rules.flow;
import com.datastax.driver.core.utils.UUIDs; import com.datastax.driver.core.utils.UUIDs;
import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.collect.Lists;
import lombok.Data;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.junit.After; import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
@ -30,25 +27,22 @@ import org.thingsboard.server.actors.service.ActorService;
import org.thingsboard.server.common.data.*; import org.thingsboard.server.common.data.*;
import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry;
import org.thingsboard.server.common.data.kv.StringDataEntry; import org.thingsboard.server.common.data.kv.StringDataEntry;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.common.data.page.TimePageData; import org.thingsboard.server.common.data.page.TimePageData;
import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.common.data.rule.RuleChainMetaData; import org.thingsboard.server.common.data.rule.RuleChainMetaData;
import org.thingsboard.server.common.data.rule.RuleNode; import org.thingsboard.server.common.data.rule.RuleNode;
import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgDataType;
import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.TbMsgMetaData;
import org.thingsboard.server.common.msg.cluster.SendToClusterMsg; import org.thingsboard.server.common.msg.cluster.SendToClusterMsg;
import org.thingsboard.server.common.msg.system.ServiceToRuleEngineMsg; import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg;
import org.thingsboard.server.controller.AbstractRuleEngineControllerTest; import org.thingsboard.server.controller.AbstractRuleEngineControllerTest;
import org.thingsboard.server.dao.attributes.AttributesService; import org.thingsboard.server.dao.attributes.AttributesService;
import org.thingsboard.server.dao.rule.RuleChainService;
import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@ -154,9 +148,9 @@ public abstract class AbstractRuleEngineFlowIntegrationTest extends AbstractRule
TbMsg tbMsg = new TbMsg(UUIDs.timeBased(), TbMsg tbMsg = new TbMsg(UUIDs.timeBased(),
"CUSTOM", "CUSTOM",
device.getId(), device.getId(),
new TbMsgMetaData(), new TbMsgMetaData(), TbMsgDataType.JSON,
"{}", null, null, 0L); "{}", null, null, null);
actorService.onMsg(new SendToClusterMsg(device.getId(), new ServiceToRuleEngineMsg(savedTenant.getId(), tbMsg))); actorService.onMsg(new SendToClusterMsg(device.getId(), new QueueToRuleEngineMsg(savedTenant.getId(), tbMsg)));
Thread.sleep(3000); Thread.sleep(3000);
@ -270,8 +264,9 @@ public abstract class AbstractRuleEngineFlowIntegrationTest extends AbstractRule
"CUSTOM", "CUSTOM",
device.getId(), device.getId(),
new TbMsgMetaData(), new TbMsgMetaData(),
"{}", null, null, 0L); TbMsgDataType.JSON,
actorService.onMsg(new SendToClusterMsg(device.getId(), new ServiceToRuleEngineMsg(savedTenant.getId(), tbMsg))); "{}", null, null, null);
actorService.onMsg(new SendToClusterMsg(device.getId(), new QueueToRuleEngineMsg(savedTenant.getId(), tbMsg)));
Thread.sleep(3000); Thread.sleep(3000);

10
application/src/test/java/org/thingsboard/server/rules/lifecycle/AbstractRuleEngineLifecycleIntegrationTest.java

@ -16,7 +16,6 @@
package org.thingsboard.server.rules.lifecycle; package org.thingsboard.server.rules.lifecycle;
import com.datastax.driver.core.utils.UUIDs; import com.datastax.driver.core.utils.UUIDs;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.junit.After; import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
@ -38,13 +37,13 @@ import org.thingsboard.server.common.data.rule.RuleChainMetaData;
import org.thingsboard.server.common.data.rule.RuleNode; import org.thingsboard.server.common.data.rule.RuleNode;
import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgDataType;
import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.TbMsgMetaData;
import org.thingsboard.server.common.msg.cluster.SendToClusterMsg; import org.thingsboard.server.common.msg.cluster.SendToClusterMsg;
import org.thingsboard.server.common.msg.system.ServiceToRuleEngineMsg; import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg;
import org.thingsboard.server.controller.AbstractRuleEngineControllerTest; import org.thingsboard.server.controller.AbstractRuleEngineControllerTest;
import org.thingsboard.server.dao.attributes.AttributesService; import org.thingsboard.server.dao.attributes.AttributesService;
import java.io.IOException;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -141,9 +140,10 @@ public abstract class AbstractRuleEngineLifecycleIntegrationTest extends Abstrac
"CUSTOM", "CUSTOM",
device.getId(), device.getId(),
new TbMsgMetaData(), new TbMsgMetaData(),
TbMsgDataType.JSON,
"{}", "{}",
null, null, 0L); null, null, null);
actorService.onMsg(new SendToClusterMsg(device.getId(), new ServiceToRuleEngineMsg(savedTenant.getId(), tbMsg))); actorService.onMsg(new SendToClusterMsg(device.getId(), new QueueToRuleEngineMsg(savedTenant.getId(), tbMsg)));
Thread.sleep(3000); Thread.sleep(3000);

15
application/src/test/java/org/thingsboard/server/service/script/RuleNodeJsScriptEngineTest.java

@ -24,6 +24,7 @@ import org.thingsboard.rule.engine.api.ScriptEngine;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.id.RuleNodeId;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgDataType;
import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.TbMsgMetaData;
import javax.script.ScriptException; import javax.script.ScriptException;
@ -62,7 +63,7 @@ public class RuleNodeJsScriptEngineTest {
metaData.putValue("humidity", "99"); metaData.putValue("humidity", "99");
String rawJson = "{\"name\": \"Vit\", \"passed\": 5, \"bigObj\": {\"prop\":42}}"; String rawJson = "{\"name\": \"Vit\", \"passed\": 5, \"bigObj\": {\"prop\":42}}";
TbMsg msg = new TbMsg(UUIDs.timeBased(), "USER", null, metaData, rawJson, null, null, 0L); TbMsg msg = new TbMsg(UUIDs.timeBased(), "USER", null, metaData, TbMsgDataType.JSON, rawJson, null, null, null);
TbMsg actual = scriptEngine.executeUpdate(msg); TbMsg actual = scriptEngine.executeUpdate(msg);
assertEquals("70", actual.getMetaData().getValue("temp")); assertEquals("70", actual.getMetaData().getValue("temp"));
@ -78,7 +79,7 @@ public class RuleNodeJsScriptEngineTest {
metaData.putValue("humidity", "99"); metaData.putValue("humidity", "99");
String rawJson = "{\"name\": \"Vit\", \"passed\": 5, \"bigObj\": {\"prop\":42}}"; String rawJson = "{\"name\": \"Vit\", \"passed\": 5, \"bigObj\": {\"prop\":42}}";
TbMsg msg = new TbMsg(UUIDs.timeBased(), "USER", null, metaData, rawJson, null, null, 0L); TbMsg msg = new TbMsg(UUIDs.timeBased(), "USER", null, metaData, TbMsgDataType.JSON, rawJson, null, null, null);
TbMsg actual = scriptEngine.executeUpdate(msg); TbMsg actual = scriptEngine.executeUpdate(msg);
assertEquals("94", actual.getMetaData().getValue("newAttr")); assertEquals("94", actual.getMetaData().getValue("newAttr"));
@ -94,7 +95,7 @@ public class RuleNodeJsScriptEngineTest {
metaData.putValue("humidity", "99"); metaData.putValue("humidity", "99");
String rawJson = "{\"name\":\"Vit\",\"passed\": 5,\"bigObj\":{\"prop\":42}}"; String rawJson = "{\"name\":\"Vit\",\"passed\": 5,\"bigObj\":{\"prop\":42}}";
TbMsg msg = new TbMsg(UUIDs.timeBased(), "USER", null, metaData, rawJson, null, null, 0L); TbMsg msg = new TbMsg(UUIDs.timeBased(), "USER", null, metaData, TbMsgDataType.JSON, rawJson, null, null, null);
TbMsg actual = scriptEngine.executeUpdate(msg); TbMsg actual = scriptEngine.executeUpdate(msg);
@ -112,7 +113,7 @@ public class RuleNodeJsScriptEngineTest {
metaData.putValue("humidity", "99"); metaData.putValue("humidity", "99");
String rawJson = "{\"name\": \"Vit\", \"passed\": 5, \"bigObj\": {\"prop\":42}}"; String rawJson = "{\"name\": \"Vit\", \"passed\": 5, \"bigObj\": {\"prop\":42}}";
TbMsg msg = new TbMsg(UUIDs.timeBased(), "USER", null, metaData, rawJson, null, null, 0L); TbMsg msg = new TbMsg(UUIDs.timeBased(), "USER", null, metaData, TbMsgDataType.JSON, rawJson, null, null, null);
assertFalse(scriptEngine.executeFilter(msg)); assertFalse(scriptEngine.executeFilter(msg));
scriptEngine.destroy(); scriptEngine.destroy();
} }
@ -126,7 +127,7 @@ public class RuleNodeJsScriptEngineTest {
metaData.putValue("humidity", "99"); metaData.putValue("humidity", "99");
String rawJson = "{\"name\": \"Vit\", \"passed\": 5, \"bigObj\": {\"prop\":42}}"; String rawJson = "{\"name\": \"Vit\", \"passed\": 5, \"bigObj\": {\"prop\":42}}";
TbMsg msg = new TbMsg(UUIDs.timeBased(), "USER", null, metaData, rawJson, null, null, 0L); TbMsg msg = new TbMsg(UUIDs.timeBased(), "USER", null, metaData,TbMsgDataType.JSON, rawJson, null, null, null);
assertTrue(scriptEngine.executeFilter(msg)); assertTrue(scriptEngine.executeFilter(msg));
scriptEngine.destroy(); scriptEngine.destroy();
} }
@ -147,7 +148,7 @@ public class RuleNodeJsScriptEngineTest {
metaData.putValue("humidity", "99"); metaData.putValue("humidity", "99");
String rawJson = "{\"name\": \"Vit\", \"passed\": 5, \"bigObj\": {\"prop\":42}}"; String rawJson = "{\"name\": \"Vit\", \"passed\": 5, \"bigObj\": {\"prop\":42}}";
TbMsg msg = new TbMsg(UUIDs.timeBased(), "USER", null, metaData, rawJson, null, null, 0L); TbMsg msg = new TbMsg(UUIDs.timeBased(), "USER", null, metaData, TbMsgDataType.JSON, rawJson, null, null, null);
Set<String> actual = scriptEngine.executeSwitch(msg); Set<String> actual = scriptEngine.executeSwitch(msg);
assertEquals(Sets.newHashSet("one"), actual); assertEquals(Sets.newHashSet("one"), actual);
scriptEngine.destroy(); scriptEngine.destroy();
@ -169,7 +170,7 @@ public class RuleNodeJsScriptEngineTest {
metaData.putValue("humidity", "99"); metaData.putValue("humidity", "99");
String rawJson = "{\"name\": \"Vit\", \"passed\": 5, \"bigObj\": {\"prop\":42}}"; String rawJson = "{\"name\": \"Vit\", \"passed\": 5, \"bigObj\": {\"prop\":42}}";
TbMsg msg = new TbMsg(UUIDs.timeBased(), "USER", null, metaData, rawJson, null, null, 0L); TbMsg msg = new TbMsg(UUIDs.timeBased(), "USER", null, metaData, TbMsgDataType.JSON, rawJson, null, null, null);
Set<String> actual = scriptEngine.executeSwitch(msg); Set<String> actual = scriptEngine.executeSwitch(msg);
assertEquals(Sets.newHashSet("one", "three"), actual); assertEquals(Sets.newHashSet("one", "three"), actual);
scriptEngine.destroy(); scriptEngine.destroy();

8
common/message/src/main/java/org/thingsboard/server/common/msg/MsgType.java

@ -15,6 +15,8 @@
*/ */
package org.thingsboard.server.common.msg; package org.thingsboard.server.common.msg;
import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg;
/** /**
* Created by ashvayka on 15.03.18. * Created by ashvayka on 15.03.18.
*/ */
@ -43,11 +45,11 @@ public enum MsgType {
COMPONENT_LIFE_CYCLE_MSG, COMPONENT_LIFE_CYCLE_MSG,
/** /**
* Misc messages from the REST API/SERVICE layer to the new rule engine. * Misc messages consumed from the Queue and forwarded to Rule Engine Actor.
* *
* See {@link org.thingsboard.server.common.msg.system.ServiceToRuleEngineMsg} * See {@link QueueToRuleEngineMsg}
*/ */
SERVICE_TO_RULE_ENGINE_MSG, QUEUE_TO_RULE_ENGINE_MSG,
/** /**
* Message that is sent by RuleChainActor to RuleActor with command to process TbMsg. * Message that is sent by RuleChainActor to RuleActor with command to process TbMsg.

49
common/message/src/main/java/org/thingsboard/server/common/msg/TbMsg.java

@ -17,12 +17,14 @@ package org.thingsboard.server.common.msg;
import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.InvalidProtocolBufferException;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data; import lombok.Data;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityIdFactory; import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.id.RuleNodeId;
import org.thingsboard.server.common.msg.gen.MsgProtos; import org.thingsboard.server.common.msg.gen.MsgProtos;
import org.thingsboard.server.common.msg.queue.TbMsgCallback;
import java.io.Serializable; import java.io.Serializable;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
@ -32,6 +34,7 @@ import java.util.UUID;
* Created by ashvayka on 13.01.18. * Created by ashvayka on 13.01.18.
*/ */
@Data @Data
@Builder
@AllArgsConstructor @AllArgsConstructor
public final class TbMsg implements Serializable { public final class TbMsg implements Serializable {
@ -42,29 +45,14 @@ public final class TbMsg implements Serializable {
private final TbMsgDataType dataType; private final TbMsgDataType dataType;
private final String data; private final String data;
private final TbMsgTransactionData transactionData; private final TbMsgTransactionData transactionData;
//The following fields are not persisted to DB, because they can always be recovered from the context;
private final RuleChainId ruleChainId; private final RuleChainId ruleChainId;
private final RuleNodeId ruleNodeId; private final RuleNodeId ruleNodeId;
private final long clusterPartition; //This field is not serialized because we use queues and there is no need to do it
private final TbMsgCallback callback;
public TbMsg(UUID id, String type, EntityId originator, TbMsgMetaData metaData, String data,
RuleChainId ruleChainId, RuleNodeId ruleNodeId, long clusterPartition) {
this.id = id;
this.type = type;
this.originator = originator;
this.metaData = metaData;
this.data = data;
this.dataType = TbMsgDataType.JSON;
this.transactionData = new TbMsgTransactionData(id, originator);
this.ruleChainId = ruleChainId;
this.ruleNodeId = ruleNodeId;
this.clusterPartition = clusterPartition;
}
public TbMsg(UUID id, String type, EntityId originator, TbMsgMetaData metaData, TbMsgDataType dataType, String data, public TbMsg(UUID id, String type, EntityId originator, TbMsgMetaData metaData, TbMsgDataType dataType, String data,
RuleChainId ruleChainId, RuleNodeId ruleNodeId, long clusterPartition) { RuleChainId ruleChainId, RuleNodeId ruleNodeId, TbMsgCallback callback) {
this(id, type, originator, metaData, dataType, data, new TbMsgTransactionData(id, originator), ruleChainId, ruleNodeId, clusterPartition); this(id, type, originator, metaData, dataType, data, new TbMsgTransactionData(id, originator), ruleChainId, ruleNodeId, callback);
} }
public static byte[] toByteArray(TbMsg msg) { public static byte[] toByteArray(TbMsg msg) {
@ -105,36 +93,31 @@ public final class TbMsg implements Serializable {
} }
public static ByteBuffer toBytes(TbMsg msg) { public static TbMsg fromBytes(byte[] data, TbMsgCallback callback) {
return ByteBuffer.wrap(toByteArray(msg));
}
public static TbMsg fromBytes(byte[] data) {
return fromBytes(ByteBuffer.wrap(data));
}
public static TbMsg fromBytes(ByteBuffer buffer) {
try { try {
MsgProtos.TbMsgProto proto = MsgProtos.TbMsgProto.parseFrom(buffer.array()); MsgProtos.TbMsgProto proto = MsgProtos.TbMsgProto.parseFrom(data);
TbMsgMetaData metaData = new TbMsgMetaData(proto.getMetaData().getDataMap()); TbMsgMetaData metaData = new TbMsgMetaData(proto.getMetaData().getDataMap());
EntityId transactionEntityId = EntityIdFactory.getByTypeAndUuid(proto.getTransactionData().getEntityType(), EntityId transactionEntityId = EntityIdFactory.getByTypeAndUuid(proto.getTransactionData().getEntityType(),
new UUID(proto.getTransactionData().getEntityIdMSB(), proto.getTransactionData().getEntityIdLSB())); new UUID(proto.getTransactionData().getEntityIdMSB(), proto.getTransactionData().getEntityIdLSB()));
TbMsgTransactionData transactionData = new TbMsgTransactionData(UUID.fromString(proto.getTransactionData().getId()), transactionEntityId); TbMsgTransactionData transactionData = new TbMsgTransactionData(UUID.fromString(proto.getTransactionData().getId()), transactionEntityId);
EntityId entityId = EntityIdFactory.getByTypeAndUuid(proto.getEntityType(), new UUID(proto.getEntityIdMSB(), proto.getEntityIdLSB())); EntityId entityId = EntityIdFactory.getByTypeAndUuid(proto.getEntityType(), new UUID(proto.getEntityIdMSB(), proto.getEntityIdLSB()));
RuleChainId ruleChainId = new RuleChainId(new UUID(proto.getRuleChainIdMSB(), proto.getRuleChainIdLSB())); RuleChainId ruleChainId = null;
RuleNodeId ruleNodeId = null; RuleNodeId ruleNodeId = null;
if (proto.getRuleChainIdMSB() != 0L && proto.getRuleChainIdLSB() != 0L) {
ruleChainId = new RuleChainId(new UUID(proto.getRuleChainIdMSB(), proto.getRuleChainIdLSB()));
}
if (proto.getRuleNodeIdMSB() != 0L && proto.getRuleNodeIdLSB() != 0L) { if (proto.getRuleNodeIdMSB() != 0L && proto.getRuleNodeIdLSB() != 0L) {
ruleNodeId = new RuleNodeId(new UUID(proto.getRuleNodeIdMSB(), proto.getRuleNodeIdLSB())); ruleNodeId = new RuleNodeId(new UUID(proto.getRuleNodeIdMSB(), proto.getRuleNodeIdLSB()));
} }
TbMsgDataType dataType = TbMsgDataType.values()[proto.getDataType()]; TbMsgDataType dataType = TbMsgDataType.values()[proto.getDataType()];
return new TbMsg(UUID.fromString(proto.getId()), proto.getType(), entityId, metaData, dataType, proto.getData(), transactionData, ruleChainId, ruleNodeId, proto.getClusterPartition()); return new TbMsg(UUID.fromString(proto.getId()), proto.getType(), entityId, metaData, dataType, proto.getData(), transactionData, ruleChainId, ruleNodeId, callback);
} catch (InvalidProtocolBufferException e) { } catch (InvalidProtocolBufferException e) {
throw new IllegalStateException("Could not parse protobuf for TbMsg", e); throw new IllegalStateException("Could not parse protobuf for TbMsg", e);
} }
} }
public TbMsg copy(UUID newId, RuleChainId ruleChainId, RuleNodeId ruleNodeId, long clusterPartition) { public TbMsg copy(UUID newId, RuleChainId ruleChainId, RuleNodeId ruleNodeId, TbMsgCallback callback) {
return new TbMsg(newId, type, originator, metaData.copy(), dataType, data, transactionData, ruleChainId, ruleNodeId, clusterPartition); return new TbMsg(newId, type, originator, metaData.copy(), dataType, data, transactionData, ruleChainId, ruleNodeId, callback);
} }
} }

6
common/message/src/main/java/org/thingsboard/server/common/msg/system/ServiceToRuleEngineMsg.java → common/message/src/main/java/org/thingsboard/server/common/msg/queue/QueueToRuleEngineMsg.java

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.thingsboard.server.common.msg.system; package org.thingsboard.server.common.msg.queue;
import lombok.Data; import lombok.Data;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
@ -27,13 +27,13 @@ import java.io.Serializable;
* Created by ashvayka on 15.03.18. * Created by ashvayka on 15.03.18.
*/ */
@Data @Data
public final class ServiceToRuleEngineMsg implements TbActorMsg, Serializable { public final class QueueToRuleEngineMsg implements TbActorMsg {
private final TenantId tenantId; private final TenantId tenantId;
private final TbMsg tbMsg; private final TbMsg tbMsg;
@Override @Override
public MsgType getMsgType() { public MsgType getMsgType() {
return MsgType.SERVICE_TO_RULE_ENGINE_MSG; return MsgType.QUEUE_TO_RULE_ENGINE_MSG;
} }
} }

2
application/src/main/java/org/thingsboard/server/service/queue/TbMsgCallback.java → common/message/src/main/java/org/thingsboard/server/common/msg/queue/TbMsgCallback.java

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.thingsboard.server.service.queue; package org.thingsboard.server.common.msg.queue;
public interface TbMsgCallback { public interface TbMsgCallback {

5
common/queue/src/main/proto/queue.proto

@ -226,7 +226,6 @@ message TransportToRuleEngineMsg {
PostAttributeMsg postAttributes = 3; PostAttributeMsg postAttributes = 3;
ToDeviceRpcResponseMsg toDeviceRPCCallResponse = 4; ToDeviceRpcResponseMsg toDeviceRPCCallResponse = 4;
ToServerRpcRequestMsg toServerRPCCallRequest = 5; ToServerRpcRequestMsg toServerRPCCallRequest = 5;
SubscriptionInfoProto subscriptionInfo = 6;
} }
message DeviceActorToTransportMsg { message DeviceActorToTransportMsg {
@ -365,7 +364,9 @@ message ToCoreMsg {
/* Messages that are handled by ThingsBoard RuleEngine Service */ /* Messages that are handled by ThingsBoard RuleEngine Service */
message ToRuleEngineMsg { message ToRuleEngineMsg {
TransportToRuleEngineMsg toRuleEngineMsg = 1; int64 tenantIdMSB = 1;
int64 tenantIdLSB = 2;
bytes tbMsg = 3;
} }
/* Messages that are handled by ThingsBoard Transport Service */ /* Messages that are handled by ThingsBoard Transport Service */

77
common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java

@ -15,11 +15,20 @@
*/ */
package org.thingsboard.server.common.transport.service; package org.thingsboard.server.common.transport.service;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.protobuf.ByteString;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.thingsboard.common.util.ThingsBoardThreadFactory; import org.thingsboard.common.util.ThingsBoardThreadFactory;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgDataType;
import org.thingsboard.server.common.msg.TbMsgMetaData;
import org.thingsboard.server.common.msg.queue.TbMsgCallback;
import org.thingsboard.server.common.msg.session.SessionMsgType;
import org.thingsboard.server.common.transport.util.JsonUtils;
import org.thingsboard.server.queue.TbQueueCallback; import org.thingsboard.server.queue.TbQueueCallback;
import org.thingsboard.server.queue.TbQueueConsumer; import org.thingsboard.server.queue.TbQueueConsumer;
import org.thingsboard.server.queue.TbQueueMsgMetadata; import org.thingsboard.server.queue.TbQueueMsgMetadata;
@ -50,16 +59,19 @@ import org.thingsboard.server.queue.common.AsyncCallbackTemplate;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy; import javax.annotation.PreDestroy;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/** /**
* Created by ashvayka on 17.10.18. * Created by ashvayka on 17.10.18.
@ -82,6 +94,7 @@ public class DefaultTransportService implements TransportService {
@Value("${queue.transport.poll_interval}") @Value("${queue.transport.poll_interval}")
private int notificationsPollDuration; private int notificationsPollDuration;
private final Gson gson = new Gson();
private final TransportQueueProvider queueProvider; private final TransportQueueProvider queueProvider;
private final PartitionService partitionService; private final PartitionService partitionService;
@ -221,8 +234,19 @@ public class DefaultTransportService implements TransportService {
public void process(TransportProtos.SessionInfoProto sessionInfo, TransportProtos.PostTelemetryMsg msg, TransportServiceCallback<Void> callback) { public void process(TransportProtos.SessionInfoProto sessionInfo, TransportProtos.PostTelemetryMsg msg, TransportServiceCallback<Void> callback) {
if (checkLimits(sessionInfo, msg, callback)) { if (checkLimits(sessionInfo, msg, callback)) {
reportActivityInternal(sessionInfo); reportActivityInternal(sessionInfo);
sendToRuleEngine(sessionInfo, TransportToRuleEngineMsg.newBuilder().setSessionInfo(sessionInfo). TenantId tenantId = new TenantId(new UUID(sessionInfo.getTenantIdMSB(), sessionInfo.getTenantIdLSB()));
setPostTelemetry(msg).build(), callback); DeviceId deviceId = new DeviceId(new UUID(sessionInfo.getDeviceIdMSB(), sessionInfo.getDeviceIdLSB()));
MsgPackCallback packCallback = new MsgPackCallback(msg.getTsKvListCount(), callback);
for (TransportProtos.TsKvListProto tsKv : msg.getTsKvListList()) {
TbMsgMetaData metaData = new TbMsgMetaData();
metaData.putValue("deviceName", sessionInfo.getDeviceName());
metaData.putValue("deviceType", sessionInfo.getDeviceType());
metaData.putValue("ts", tsKv.getTs() + "");
JsonObject json = JsonUtils.getJsonObject(tsKv.getKvList());
TbMsg tbMsg = new TbMsg(UUID.randomUUID(), SessionMsgType.POST_TELEMETRY_REQUEST.name(),
deviceId, metaData, TbMsgDataType.JSON, gson.toJson(json), null, null, null);
sendToRuleEngine(tenantId, tbMsg, packCallback);
}
} }
} }
@ -230,8 +254,15 @@ public class DefaultTransportService implements TransportService {
public void process(TransportProtos.SessionInfoProto sessionInfo, TransportProtos.PostAttributeMsg msg, TransportServiceCallback<Void> callback) { public void process(TransportProtos.SessionInfoProto sessionInfo, TransportProtos.PostAttributeMsg msg, TransportServiceCallback<Void> callback) {
if (checkLimits(sessionInfo, msg, callback)) { if (checkLimits(sessionInfo, msg, callback)) {
reportActivityInternal(sessionInfo); reportActivityInternal(sessionInfo);
sendToRuleEngine(sessionInfo, TransportToRuleEngineMsg.newBuilder().setSessionInfo(sessionInfo). TenantId tenantId = new TenantId(new UUID(sessionInfo.getTenantIdMSB(), sessionInfo.getTenantIdLSB()));
setPostAttributes(msg).build(), callback); DeviceId deviceId = new DeviceId(new UUID(sessionInfo.getDeviceIdMSB(), sessionInfo.getDeviceIdLSB()));
JsonObject json = JsonUtils.getJsonObject(msg.getKvList());
TbMsgMetaData metaData = new TbMsgMetaData();
metaData.putValue("deviceName", sessionInfo.getDeviceName());
metaData.putValue("deviceType", sessionInfo.getDeviceType());
TbMsg tbMsg = new TbMsg(UUID.randomUUID(), SessionMsgType.POST_ATTRIBUTES_REQUEST.name(), deviceId, metaData,
TbMsgDataType.JSON, gson.toJson(json), null, null, null);
sendToRuleEngine(tenantId, tbMsg, new TransportTbQueueCallback(callback));
} }
} }
@ -278,8 +309,8 @@ public class DefaultTransportService implements TransportService {
public void process(TransportProtos.SessionInfoProto sessionInfo, TransportProtos.ToServerRpcRequestMsg msg, TransportServiceCallback<Void> callback) { public void process(TransportProtos.SessionInfoProto sessionInfo, TransportProtos.ToServerRpcRequestMsg msg, TransportServiceCallback<Void> callback) {
if (checkLimits(sessionInfo, msg, callback)) { if (checkLimits(sessionInfo, msg, callback)) {
reportActivityInternal(sessionInfo); reportActivityInternal(sessionInfo);
sendToRuleEngine(sessionInfo, TransportToRuleEngineMsg.newBuilder().setSessionInfo(sessionInfo). // sendToRuleEngine(sessionInfo, TransportToRuleEngineMsg.newBuilder().setSessionInfo(sessionInfo).
setToServerRPCCallRequest(msg).build(), callback); // setToServerRPCCallRequest(msg).build(), new TransportTbQueueCallback(callback));
} }
} }
@ -455,12 +486,12 @@ public class DefaultTransportService implements TransportService {
new TransportTbQueueCallback(callback) : null); new TransportTbQueueCallback(callback) : null);
} }
protected void sendToRuleEngine(TransportProtos.SessionInfoProto sessionInfo, TransportToRuleEngineMsg toRuleEngineMsg, TransportServiceCallback<Void> callback) { protected void sendToRuleEngine(TenantId tenantId, TbMsg tbMsg, TbQueueCallback callback) {
TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_RULE_ENGINE, getTenantId(sessionInfo), getDeviceId(sessionInfo)); TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_RULE_ENGINE, tenantId, tbMsg.getOriginator());
ruleEngineMsgProducer.send(tpi, ToRuleEngineMsg msg = ToRuleEngineMsg.newBuilder().setTbMsg(ByteString.copyFrom(TbMsg.toByteArray(tbMsg)))
new TbProtoQueueMsg<>(getRoutingKey(sessionInfo), .setTenantIdMSB(tenantId.getId().getMostSignificantBits())
ToRuleEngineMsg.newBuilder().setToRuleEngineMsg(toRuleEngineMsg).build()), callback != null ? .setTenantIdLSB(tenantId.getId().getLeastSignificantBits()).build();
new TransportTbQueueCallback(callback) : null); ruleEngineMsgProducer.send(tpi, new TbProtoQueueMsg<>(tbMsg.getId(), msg), callback);
} }
private class TransportTbQueueCallback implements TbQueueCallback { private class TransportTbQueueCallback implements TbQueueCallback {
@ -480,4 +511,26 @@ public class DefaultTransportService implements TransportService {
DefaultTransportService.this.transportCallbackExecutor.submit(() -> callback.onError(t)); DefaultTransportService.this.transportCallbackExecutor.submit(() -> callback.onError(t));
} }
} }
private class MsgPackCallback implements TbQueueCallback {
private final AtomicInteger msgCount;
private final TransportServiceCallback<Void> callback;
public MsgPackCallback(Integer msgCount, TransportServiceCallback<Void> callback) {
this.msgCount = new AtomicInteger(msgCount);
this.callback = callback;
}
@Override
public void onSuccess(TbQueueMsgMetadata metadata) {
if (msgCount.decrementAndGet() <= 0) {
callback.onSuccess(null);
}
}
@Override
public void onFailure(Throwable t) {
callback.onError(t);
}
}
} }

2
application/src/main/java/org/thingsboard/server/utils/JsonUtils.java → common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/util/JsonUtils.java

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.thingsboard.server.utils; package org.thingsboard.server.common.transport.util;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;

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

@ -75,7 +75,8 @@ public class TbMsgCountNode implements TbNode {
TbMsgMetaData metaData = new TbMsgMetaData(); TbMsgMetaData metaData = new TbMsgMetaData();
metaData.putValue("delta", Long.toString(System.currentTimeMillis() - lastScheduledTs + delay)); metaData.putValue("delta", Long.toString(System.currentTimeMillis() - lastScheduledTs + delay));
TbMsg tbMsg = new TbMsg(UUIDs.timeBased(), SessionMsgType.POST_TELEMETRY_REQUEST.name(), ctx.getTenantId(), metaData, TbMsgDataType.JSON, gson.toJson(telemetryJson), null, null, 0L); //TODO 2.5: Callback?
TbMsg tbMsg = new TbMsg(UUIDs.timeBased(), SessionMsgType.POST_TELEMETRY_REQUEST.name(), ctx.getTenantId(), metaData, TbMsgDataType.JSON, gson.toJson(telemetryJson), null, null, null);
ctx.tellNext(tbMsg, SUCCESS); ctx.tellNext(tbMsg, SUCCESS);
scheduleTickMsg(ctx); scheduleTickMsg(ctx);
} else { } else {

3
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbRedisQueueProcessor.java

@ -66,7 +66,8 @@ class TbRedisQueueProcessor {
if (listOperations.size(redisKey) > 0) { if (listOperations.size(redisKey) > 0) {
List<Object> list = listOperations.range(redisKey, -10, -1); List<Object> list = listOperations.range(redisKey, -10, -1);
list.forEach(obj -> { list.forEach(obj -> {
TbMsg msg = TbMsg.fromBytes((byte[]) obj); //TODO 2.5: Callback?
TbMsg msg = TbMsg.fromBytes((byte[]) obj, null);
log.debug("Trying to send the message: {}", msg); log.debug("Trying to send the message: {}", msg);
listOperations.remove(redisKey, -1, obj); listOperations.remove(redisKey, -1, obj);
httpClient.processMessage(ctx, msg, this); httpClient.processMessage(ctx, msg, this);

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

@ -57,8 +57,9 @@ public class TbSynchronizationBeginNode implements TbNode {
log.trace("Msg enters transaction - [{}][{}]", msg.getId(), msg.getType()); log.trace("Msg enters transaction - [{}][{}]", msg.getId(), msg.getType());
TbMsgTransactionData transactionData = new TbMsgTransactionData(msg.getId(), msg.getOriginator()); TbMsgTransactionData transactionData = new TbMsgTransactionData(msg.getId(), msg.getOriginator());
//TODO 2.5: Callback?
TbMsg tbMsg = new TbMsg(msg.getId(), msg.getType(), msg.getOriginator(), msg.getMetaData(), TbMsgDataType.JSON, TbMsg tbMsg = new TbMsg(msg.getId(), msg.getType(), msg.getOriginator(), msg.getMetaData(), TbMsgDataType.JSON,
msg.getData(), transactionData, msg.getRuleChainId(), msg.getRuleNodeId(), msg.getClusterPartition()); msg.getData(), transactionData, msg.getRuleChainId(), msg.getRuleNodeId(), null);
ctx.getRuleChainTransactionService().beginTransaction(tbMsg, startMsg -> { ctx.getRuleChainTransactionService().beginTransaction(tbMsg, startMsg -> {
log.trace("Transaction starting...[{}][{}]", startMsg.getId(), startMsg.getType()); log.trace("Transaction starting...[{}][{}]", startMsg.getId(), startMsg.getType());

12
rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbAlarmNodeTest.java

@ -37,7 +37,9 @@ import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.id.RuleNodeId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.kv.DataType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgDataType;
import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.TbMsgMetaData;
import org.thingsboard.server.dao.alarm.AlarmService; import org.thingsboard.server.dao.alarm.AlarmService;
@ -99,7 +101,7 @@ public class TbAlarmNodeTest {
public void newAlarmCanBeCreated() throws ScriptException, IOException { public void newAlarmCanBeCreated() throws ScriptException, IOException {
initWithCreateAlarmScript(); initWithCreateAlarmScript();
metaData.putValue("key", "value"); metaData.putValue("key", "value");
TbMsg msg = new TbMsg(UUIDs.timeBased(), "USER", originator, metaData, rawJson, ruleChainId, ruleNodeId, 0L); TbMsg msg = new TbMsg(UUIDs.timeBased(), "USER", originator, metaData, TbMsgDataType.JSON, rawJson, ruleChainId, ruleNodeId, null);
when(detailsJs.executeJsonAsync(msg)).thenReturn(Futures.immediateFuture(null)); when(detailsJs.executeJsonAsync(msg)).thenReturn(Futures.immediateFuture(null));
when(alarmService.findLatestByOriginatorAndType(tenantId, originator, "SomeType")).thenReturn(Futures.immediateFuture(null)); when(alarmService.findLatestByOriginatorAndType(tenantId, originator, "SomeType")).thenReturn(Futures.immediateFuture(null));
@ -141,7 +143,7 @@ public class TbAlarmNodeTest {
public void buildDetailsThrowsException() throws ScriptException, IOException { public void buildDetailsThrowsException() throws ScriptException, IOException {
initWithCreateAlarmScript(); initWithCreateAlarmScript();
metaData.putValue("key", "value"); metaData.putValue("key", "value");
TbMsg msg = new TbMsg(UUIDs.timeBased(), "USER", originator, metaData, rawJson, ruleChainId, ruleNodeId, 0L); TbMsg msg = new TbMsg(UUIDs.timeBased(), "USER", originator, metaData, TbMsgDataType.JSON, rawJson, ruleChainId, ruleNodeId, null);
when(detailsJs.executeJsonAsync(msg)).thenReturn(Futures.immediateFailedFuture(new NotImplementedException("message"))); when(detailsJs.executeJsonAsync(msg)).thenReturn(Futures.immediateFailedFuture(new NotImplementedException("message")));
when(alarmService.findLatestByOriginatorAndType(tenantId, originator, "SomeType")).thenReturn(Futures.immediateFuture(null)); when(alarmService.findLatestByOriginatorAndType(tenantId, originator, "SomeType")).thenReturn(Futures.immediateFuture(null));
@ -164,7 +166,7 @@ public class TbAlarmNodeTest {
public void ifAlarmClearedCreateNew() throws ScriptException, IOException { public void ifAlarmClearedCreateNew() throws ScriptException, IOException {
initWithCreateAlarmScript(); initWithCreateAlarmScript();
metaData.putValue("key", "value"); metaData.putValue("key", "value");
TbMsg msg = new TbMsg(UUIDs.timeBased(), "USER", originator, metaData, rawJson, ruleChainId, ruleNodeId, 0L); TbMsg msg = new TbMsg(UUIDs.timeBased(), "USER", originator, metaData, TbMsgDataType.JSON, rawJson, ruleChainId, ruleNodeId, null);
Alarm clearedAlarm = Alarm.builder().status(CLEARED_ACK).build(); Alarm clearedAlarm = Alarm.builder().status(CLEARED_ACK).build();
@ -209,7 +211,7 @@ public class TbAlarmNodeTest {
public void alarmCanBeUpdated() throws ScriptException, IOException { public void alarmCanBeUpdated() throws ScriptException, IOException {
initWithCreateAlarmScript(); initWithCreateAlarmScript();
metaData.putValue("key", "value"); metaData.putValue("key", "value");
TbMsg msg = new TbMsg(UUIDs.timeBased(), "USER", originator, metaData, rawJson, ruleChainId, ruleNodeId, 0L); TbMsg msg = new TbMsg(UUIDs.timeBased(), "USER", originator, metaData, TbMsgDataType.JSON, rawJson, ruleChainId, ruleNodeId, null);
long oldEndDate = System.currentTimeMillis(); long oldEndDate = System.currentTimeMillis();
Alarm activeAlarm = Alarm.builder().type("SomeType").tenantId(tenantId).originator(originator).status(ACTIVE_UNACK).severity(WARNING).endTs(oldEndDate).build(); Alarm activeAlarm = Alarm.builder().type("SomeType").tenantId(tenantId).originator(originator).status(ACTIVE_UNACK).severity(WARNING).endTs(oldEndDate).build();
@ -256,7 +258,7 @@ public class TbAlarmNodeTest {
public void alarmCanBeCleared() throws ScriptException, IOException { public void alarmCanBeCleared() throws ScriptException, IOException {
initWithClearAlarmScript(); initWithClearAlarmScript();
metaData.putValue("key", "value"); metaData.putValue("key", "value");
TbMsg msg = new TbMsg(UUIDs.timeBased(), "USER", originator, metaData, rawJson, ruleChainId, ruleNodeId, 0L); TbMsg msg = new TbMsg(UUIDs.timeBased(), "USER", originator, metaData, TbMsgDataType.JSON, rawJson, ruleChainId, ruleNodeId, null);
long oldEndDate = System.currentTimeMillis(); long oldEndDate = System.currentTimeMillis();
Alarm activeAlarm = Alarm.builder().type("SomeType").tenantId(tenantId).originator(originator).status(ACTIVE_UNACK).severity(WARNING).endTs(oldEndDate).build(); Alarm activeAlarm = Alarm.builder().type("SomeType").tenantId(tenantId).originator(originator).status(ACTIVE_UNACK).severity(WARNING).endTs(oldEndDate).build();

7
rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbJsFilterNodeTest.java

@ -32,6 +32,7 @@ import org.thingsboard.rule.engine.api.*;
import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.id.RuleNodeId;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgDataType;
import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.TbMsgMetaData;
import javax.script.ScriptException; import javax.script.ScriptException;
@ -58,7 +59,7 @@ public class TbJsFilterNodeTest {
@Test @Test
public void falseEvaluationDoNotSendMsg() throws TbNodeException, ScriptException { public void falseEvaluationDoNotSendMsg() throws TbNodeException, ScriptException {
initWithScript(); initWithScript();
TbMsg msg = new TbMsg(UUIDs.timeBased(), "USER", null, new TbMsgMetaData(), "{}", ruleChainId, ruleNodeId, 0L); TbMsg msg = new TbMsg(UUIDs.timeBased(), "USER", null, new TbMsgMetaData(), TbMsgDataType.JSON, "{}", ruleChainId, ruleNodeId, null);
mockJsExecutor(); mockJsExecutor();
when(scriptEngine.executeFilterAsync(msg)).thenReturn(Futures.immediateFuture(false)); when(scriptEngine.executeFilterAsync(msg)).thenReturn(Futures.immediateFuture(false));
@ -71,7 +72,7 @@ public class TbJsFilterNodeTest {
public void exceptionInJsThrowsException() throws TbNodeException, ScriptException { public void exceptionInJsThrowsException() throws TbNodeException, ScriptException {
initWithScript(); initWithScript();
TbMsgMetaData metaData = new TbMsgMetaData(); TbMsgMetaData metaData = new TbMsgMetaData();
TbMsg msg = new TbMsg(UUIDs.timeBased(), "USER", null, metaData, "{}", ruleChainId, ruleNodeId, 0L); TbMsg msg = new TbMsg(UUIDs.timeBased(), "USER", null, metaData, TbMsgDataType.JSON, "{}", ruleChainId, ruleNodeId, null);
mockJsExecutor(); mockJsExecutor();
when(scriptEngine.executeFilterAsync(msg)).thenReturn(Futures.immediateFailedFuture(new ScriptException("error"))); when(scriptEngine.executeFilterAsync(msg)).thenReturn(Futures.immediateFailedFuture(new ScriptException("error")));
@ -84,7 +85,7 @@ public class TbJsFilterNodeTest {
public void metadataConditionCanBeTrue() throws TbNodeException, ScriptException { public void metadataConditionCanBeTrue() throws TbNodeException, ScriptException {
initWithScript(); initWithScript();
TbMsgMetaData metaData = new TbMsgMetaData(); TbMsgMetaData metaData = new TbMsgMetaData();
TbMsg msg = new TbMsg(UUIDs.timeBased(), "USER", null, metaData, "{}", ruleChainId, ruleNodeId, 0L); TbMsg msg = new TbMsg(UUIDs.timeBased(), "USER", null, metaData, TbMsgDataType.JSON, "{}", ruleChainId, ruleNodeId, null);
mockJsExecutor(); mockJsExecutor();
when(scriptEngine.executeFilterAsync(msg)).thenReturn(Futures.immediateFuture(true)); when(scriptEngine.executeFilterAsync(msg)).thenReturn(Futures.immediateFuture(true));

3
rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbJsSwitchNodeTest.java

@ -32,6 +32,7 @@ import org.thingsboard.rule.engine.api.*;
import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.id.RuleNodeId;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgDataType;
import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.TbMsgMetaData;
import javax.script.ScriptException; import javax.script.ScriptException;
@ -65,7 +66,7 @@ public class TbJsSwitchNodeTest {
metaData.putValue("humidity", "99"); metaData.putValue("humidity", "99");
String rawJson = "{\"name\": \"Vit\", \"passed\": 5}"; String rawJson = "{\"name\": \"Vit\", \"passed\": 5}";
TbMsg msg = new TbMsg(UUIDs.timeBased(), "USER", null, metaData, rawJson, ruleChainId, ruleNodeId, 0L); TbMsg msg = new TbMsg(UUIDs.timeBased(), "USER", null, metaData, TbMsgDataType.JSON, rawJson, ruleChainId, ruleNodeId, null);
mockJsExecutor(); mockJsExecutor();
when(scriptEngine.executeSwitch(msg)).thenReturn(Sets.newHashSet("one", "three")); when(scriptEngine.executeSwitch(msg)).thenReturn(Sets.newHashSet("one", "three"));

3
rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/mail/TbMsgToEmailNodeTest.java

@ -30,6 +30,7 @@ import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.id.RuleNodeId;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgDataType;
import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.TbMsgMetaData;
import java.io.IOException; import java.io.IOException;
@ -62,7 +63,7 @@ public class TbMsgToEmailNodeTest {
metaData.putValue("name", "temp"); metaData.putValue("name", "temp");
metaData.putValue("passed", "5"); metaData.putValue("passed", "5");
metaData.putValue("count", "100"); metaData.putValue("count", "100");
TbMsg msg = new TbMsg(UUIDs.timeBased(), "USER", originator, metaData, rawJson, ruleChainId, ruleNodeId, 0L); TbMsg msg = new TbMsg(UUIDs.timeBased(), "USER", originator, metaData, TbMsgDataType.JSON, rawJson, ruleChainId, ruleNodeId, null);
emailNode.onMsg(ctx, msg); emailNode.onMsg(ctx, msg);

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

@ -34,6 +34,7 @@ import org.thingsboard.server.common.data.asset.Asset;
import org.thingsboard.server.common.data.id.*; import org.thingsboard.server.common.data.id.*;
import org.thingsboard.server.common.data.kv.*; import org.thingsboard.server.common.data.kv.*;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgDataType;
import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.TbMsgMetaData;
import org.thingsboard.server.dao.asset.AssetService; import org.thingsboard.server.dao.asset.AssetService;
import org.thingsboard.server.dao.attributes.AttributesService; import org.thingsboard.server.dao.attributes.AttributesService;
@ -102,7 +103,7 @@ public class TbGetCustomerAttributeNodeTest {
User user = new User(); User user = new User();
user.setCustomerId(customerId); user.setCustomerId(customerId);
msg = new TbMsg(UUIDs.timeBased(), "USER", userId, new TbMsgMetaData(), "{}", ruleChainId, ruleNodeId, 0L); msg = new TbMsg(UUIDs.timeBased(), "USER", userId, new TbMsgMetaData(), TbMsgDataType.JSON, "{}", ruleChainId, ruleNodeId, null);
when(ctx.getUserService()).thenReturn(userService); when(ctx.getUserService()).thenReturn(userService);
when(userService.findUserByIdAsync(any(), eq(userId))).thenReturn(Futures.immediateFuture(user)); when(userService.findUserByIdAsync(any(), eq(userId))).thenReturn(Futures.immediateFuture(user));
@ -127,7 +128,7 @@ public class TbGetCustomerAttributeNodeTest {
User user = new User(); User user = new User();
user.setCustomerId(customerId); user.setCustomerId(customerId);
msg = new TbMsg(UUIDs.timeBased(), "USER", userId, new TbMsgMetaData(), "{}", ruleChainId, ruleNodeId, 0L); msg = new TbMsg(UUIDs.timeBased(), "USER", userId, new TbMsgMetaData(), TbMsgDataType.JSON, "{}", ruleChainId, ruleNodeId, null);
when(ctx.getUserService()).thenReturn(userService); when(ctx.getUserService()).thenReturn(userService);
when(userService.findUserByIdAsync(any(), eq(userId))).thenReturn(Futures.immediateFuture(user)); when(userService.findUserByIdAsync(any(), eq(userId))).thenReturn(Futures.immediateFuture(user));
@ -152,7 +153,7 @@ public class TbGetCustomerAttributeNodeTest {
User user = new User(); User user = new User();
user.setCustomerId(customerId); user.setCustomerId(customerId);
msg = new TbMsg(UUIDs.timeBased(), "USER", userId, new TbMsgMetaData(), "{}", ruleChainId, ruleNodeId, 0L); msg = new TbMsg(UUIDs.timeBased(), "USER", userId, new TbMsgMetaData(), TbMsgDataType.JSON,"{}", ruleChainId, ruleNodeId, null);
when(ctx.getUserService()).thenReturn(userService); when(ctx.getUserService()).thenReturn(userService);
when(userService.findUserByIdAsync(any(), eq(userId))).thenReturn(Futures.immediateFuture(null)); when(userService.findUserByIdAsync(any(), eq(userId))).thenReturn(Futures.immediateFuture(null));
@ -166,7 +167,7 @@ public class TbGetCustomerAttributeNodeTest {
@Test @Test
public void customerAttributeAddedInMetadata() { public void customerAttributeAddedInMetadata() {
CustomerId customerId = new CustomerId(UUIDs.timeBased()); CustomerId customerId = new CustomerId(UUIDs.timeBased());
msg = new TbMsg(UUIDs.timeBased(), "CUSTOMER", customerId, new TbMsgMetaData(), "{}", ruleChainId, ruleNodeId, 0L); msg = new TbMsg(UUIDs.timeBased(), "CUSTOMER", customerId, new TbMsgMetaData(), TbMsgDataType.JSON, "{}", ruleChainId, ruleNodeId, null);
entityAttributeFetched(customerId); entityAttributeFetched(customerId);
} }
@ -177,7 +178,7 @@ public class TbGetCustomerAttributeNodeTest {
User user = new User(); User user = new User();
user.setCustomerId(customerId); user.setCustomerId(customerId);
msg = new TbMsg(UUIDs.timeBased(), "USER", userId, new TbMsgMetaData(), "{}", ruleChainId, ruleNodeId, 0L); msg = new TbMsg(UUIDs.timeBased(), "USER", userId, new TbMsgMetaData(), TbMsgDataType.JSON, "{}", ruleChainId, ruleNodeId, null);
when(ctx.getUserService()).thenReturn(userService); when(ctx.getUserService()).thenReturn(userService);
when(userService.findUserByIdAsync(any(), eq(userId))).thenReturn(Futures.immediateFuture(user)); when(userService.findUserByIdAsync(any(), eq(userId))).thenReturn(Futures.immediateFuture(user));
@ -192,7 +193,7 @@ public class TbGetCustomerAttributeNodeTest {
Asset asset = new Asset(); Asset asset = new Asset();
asset.setCustomerId(customerId); asset.setCustomerId(customerId);
msg = new TbMsg(UUIDs.timeBased(), "USER", assetId, new TbMsgMetaData(), "{}", ruleChainId, ruleNodeId, 0L); msg = new TbMsg(UUIDs.timeBased(), "USER", assetId, new TbMsgMetaData(), TbMsgDataType.JSON, "{}", ruleChainId, ruleNodeId, null);
when(ctx.getAssetService()).thenReturn(assetService); when(ctx.getAssetService()).thenReturn(assetService);
when(assetService.findAssetByIdAsync(any(), eq(assetId))).thenReturn(Futures.immediateFuture(asset)); when(assetService.findAssetByIdAsync(any(), eq(assetId))).thenReturn(Futures.immediateFuture(asset));
@ -207,7 +208,7 @@ public class TbGetCustomerAttributeNodeTest {
Device device = new Device(); Device device = new Device();
device.setCustomerId(customerId); device.setCustomerId(customerId);
msg = new TbMsg(UUIDs.timeBased(), "USER", deviceId, new TbMsgMetaData(), "{}", ruleChainId, ruleNodeId, 0L); msg = new TbMsg(UUIDs.timeBased(), "USER", deviceId, new TbMsgMetaData(), TbMsgDataType.JSON, "{}", ruleChainId, ruleNodeId, null);
when(ctx.getDeviceService()).thenReturn(deviceService); when(ctx.getDeviceService()).thenReturn(deviceService);
when(deviceService.findDeviceByIdAsync(any(), eq(deviceId))).thenReturn(Futures.immediateFuture(device)); when(deviceService.findDeviceByIdAsync(any(), eq(deviceId))).thenReturn(Futures.immediateFuture(device));
@ -234,7 +235,7 @@ public class TbGetCustomerAttributeNodeTest {
Device device = new Device(); Device device = new Device();
device.setCustomerId(customerId); device.setCustomerId(customerId);
msg = new TbMsg(UUIDs.timeBased(), "USER", deviceId, new TbMsgMetaData(), "{}", ruleChainId, ruleNodeId, 0L); msg = new TbMsg(UUIDs.timeBased(), "USER", deviceId, new TbMsgMetaData(), TbMsgDataType.JSON,"{}", ruleChainId, ruleNodeId, null);
when(ctx.getDeviceService()).thenReturn(deviceService); when(ctx.getDeviceService()).thenReturn(deviceService);
when(deviceService.findDeviceByIdAsync(any(), eq(deviceId))).thenReturn(Futures.immediateFuture(device)); when(deviceService.findDeviceByIdAsync(any(), eq(deviceId))).thenReturn(Futures.immediateFuture(device));

7
rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbChangeOriginatorNodeTest.java

@ -36,6 +36,7 @@ import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.id.RuleNodeId;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgDataType;
import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.TbMsgMetaData;
import org.thingsboard.server.dao.asset.AssetService; import org.thingsboard.server.dao.asset.AssetService;
@ -91,7 +92,7 @@ public class TbChangeOriginatorNodeTest {
RuleChainId ruleChainId = new RuleChainId(UUIDs.timeBased()); RuleChainId ruleChainId = new RuleChainId(UUIDs.timeBased());
RuleNodeId ruleNodeId = new RuleNodeId(UUIDs.timeBased()); RuleNodeId ruleNodeId = new RuleNodeId(UUIDs.timeBased());
TbMsg msg = new TbMsg(UUIDs.timeBased(), "ASSET", assetId, new TbMsgMetaData(), "{}", ruleChainId, ruleNodeId, 0L); TbMsg msg = new TbMsg(UUIDs.timeBased(), "ASSET", assetId, new TbMsgMetaData(), TbMsgDataType.JSON, "{}", ruleChainId, ruleNodeId, null);
when(ctx.getAssetService()).thenReturn(assetService); when(ctx.getAssetService()).thenReturn(assetService);
when(assetService.findAssetByIdAsync(any(),eq( assetId))).thenReturn(Futures.immediateFuture(asset)); when(assetService.findAssetByIdAsync(any(),eq( assetId))).thenReturn(Futures.immediateFuture(asset));
@ -119,7 +120,7 @@ public class TbChangeOriginatorNodeTest {
RuleChainId ruleChainId = new RuleChainId(UUIDs.timeBased()); RuleChainId ruleChainId = new RuleChainId(UUIDs.timeBased());
RuleNodeId ruleNodeId = new RuleNodeId(UUIDs.timeBased()); RuleNodeId ruleNodeId = new RuleNodeId(UUIDs.timeBased());
TbMsg msg = new TbMsg(UUIDs.timeBased(), "ASSET", assetId, new TbMsgMetaData(), "{}", ruleChainId, ruleNodeId, 0L); TbMsg msg = new TbMsg(UUIDs.timeBased(), "ASSET", assetId, new TbMsgMetaData(), TbMsgDataType.JSON,"{}", ruleChainId, ruleNodeId, null);
when(ctx.getAssetService()).thenReturn(assetService); when(ctx.getAssetService()).thenReturn(assetService);
when(assetService.findAssetByIdAsync(any(), eq(assetId))).thenReturn(Futures.immediateFuture(asset)); when(assetService.findAssetByIdAsync(any(), eq(assetId))).thenReturn(Futures.immediateFuture(asset));
@ -146,7 +147,7 @@ public class TbChangeOriginatorNodeTest {
RuleChainId ruleChainId = new RuleChainId(UUIDs.timeBased()); RuleChainId ruleChainId = new RuleChainId(UUIDs.timeBased());
RuleNodeId ruleNodeId = new RuleNodeId(UUIDs.timeBased()); RuleNodeId ruleNodeId = new RuleNodeId(UUIDs.timeBased());
TbMsg msg = new TbMsg(UUIDs.timeBased(), "ASSET", assetId, new TbMsgMetaData(), "{}", ruleChainId, ruleNodeId, 0L); TbMsg msg = new TbMsg(UUIDs.timeBased(), "ASSET", assetId, new TbMsgMetaData(), TbMsgDataType.JSON,"{}", ruleChainId, ruleNodeId, null);
when(ctx.getAssetService()).thenReturn(assetService); when(ctx.getAssetService()).thenReturn(assetService);
when(assetService.findAssetByIdAsync(any(), eq(assetId))).thenReturn(Futures.immediateFuture(null)); when(assetService.findAssetByIdAsync(any(), eq(assetId))).thenReturn(Futures.immediateFuture(null));

7
rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbTransformMsgNodeTest.java

@ -31,6 +31,7 @@ import org.thingsboard.rule.engine.api.*;
import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.id.RuleNodeId;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgDataType;
import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.TbMsgMetaData;
import javax.script.ScriptException; import javax.script.ScriptException;
@ -62,8 +63,8 @@ public class TbTransformMsgNodeTest {
RuleChainId ruleChainId = new RuleChainId(UUIDs.timeBased()); RuleChainId ruleChainId = new RuleChainId(UUIDs.timeBased());
RuleNodeId ruleNodeId = new RuleNodeId(UUIDs.timeBased()); RuleNodeId ruleNodeId = new RuleNodeId(UUIDs.timeBased());
TbMsg msg = new TbMsg(UUIDs.timeBased(), "USER", null, metaData, rawJson, ruleChainId, ruleNodeId, 0L); TbMsg msg = new TbMsg(UUIDs.timeBased(), "USER", null, metaData, TbMsgDataType.JSON,rawJson, ruleChainId, ruleNodeId, null);
TbMsg transformedMsg = new TbMsg(UUIDs.timeBased(), "USER", null, metaData, "{new}", ruleChainId, ruleNodeId, 0L); TbMsg transformedMsg = new TbMsg(UUIDs.timeBased(), "USER", null, metaData, TbMsgDataType.JSON, "{new}", ruleChainId, ruleNodeId, null);
mockJsExecutor(); mockJsExecutor();
when(scriptEngine.executeUpdateAsync(msg)).thenReturn(Futures.immediateFuture(transformedMsg)); when(scriptEngine.executeUpdateAsync(msg)).thenReturn(Futures.immediateFuture(transformedMsg));
@ -84,7 +85,7 @@ public class TbTransformMsgNodeTest {
RuleChainId ruleChainId = new RuleChainId(UUIDs.timeBased()); RuleChainId ruleChainId = new RuleChainId(UUIDs.timeBased());
RuleNodeId ruleNodeId = new RuleNodeId(UUIDs.timeBased()); RuleNodeId ruleNodeId = new RuleNodeId(UUIDs.timeBased());
TbMsg msg = new TbMsg(UUIDs.timeBased(), "USER", null, metaData, rawJson, ruleChainId, ruleNodeId, 0L); TbMsg msg = new TbMsg(UUIDs.timeBased(), "USER", null, metaData, TbMsgDataType.JSON, rawJson, ruleChainId, ruleNodeId, null);
mockJsExecutor(); mockJsExecutor();
when(scriptEngine.executeUpdateAsync(msg)).thenReturn(Futures.immediateFailedFuture(new IllegalStateException("error"))); when(scriptEngine.executeUpdateAsync(msg)).thenReturn(Futures.immediateFailedFuture(new IllegalStateException("error")));

Loading…
Cancel
Save