Commit 7531a26e617092c437b9df6c8d13b22511eac1ab

Authored by Andrii Shvaika
1 parent 07bdcac0

Implementation of RPC Call support

Showing 91 changed files with 1568 additions and 722 deletions
... ... @@ -5,7 +5,7 @@
5 5 * you may not use this file except in compliance with the License.
6 6 * You may obtain a copy of the License at
7 7 *
8   - * http://www.apache.org/licenses/LICENSE-2.0
  8 + * http://www.apache.org/licenses/LICENSE-2.0
9 9 *
10 10 * Unless required by applicable law or agreed to in writing, software
11 11 * distributed under the License is distributed on an "AS IS" BASIS,
... ... @@ -45,6 +45,8 @@ import org.thingsboard.server.common.data.id.EntityId;
45 45 import org.thingsboard.server.common.data.id.TenantId;
46 46 import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
47 47 import org.thingsboard.server.common.msg.TbMsg;
  48 +import org.thingsboard.server.common.msg.queue.ServiceType;
  49 +import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
48 50 import org.thingsboard.server.common.msg.tools.TbRateLimits;
49 51 import org.thingsboard.server.common.transport.auth.DeviceAuthService;
50 52 import org.thingsboard.server.dao.alarm.AlarmService;
... ... @@ -63,14 +65,9 @@ import org.thingsboard.server.dao.rule.RuleChainService;
63 65 import org.thingsboard.server.dao.tenant.TenantService;
64 66 import org.thingsboard.server.dao.timeseries.TimeseriesService;
65 67 import org.thingsboard.server.dao.user.UserService;
66   -import org.thingsboard.server.gen.transport.TransportProtos;
67   -import org.thingsboard.server.queue.TbQueueProducer;
68   -import org.thingsboard.server.queue.common.TbProtoQueueMsg;
69 68 import org.thingsboard.server.queue.discovery.PartitionService;
70   -import org.thingsboard.server.queue.discovery.ServiceType;
71 69 import org.thingsboard.server.queue.discovery.TbServiceInfoProvider;
72   -import org.thingsboard.server.queue.discovery.TopicPartitionInfo;
73   -import org.thingsboard.server.queue.provider.TbRuleEngineQueueProvider;
  70 +import org.thingsboard.server.queue.provider.TbQueueProducerProvider;
74 71 import org.thingsboard.server.service.component.ComponentDiscoveryService;
75 72 import org.thingsboard.server.service.encoding.DataDecodingEncodingService;
76 73 import org.thingsboard.server.service.executors.ClusterRpcCallbackExecutorService;
... ... @@ -78,7 +75,9 @@ import org.thingsboard.server.service.executors.DbCallbackExecutorService;
78 75 import org.thingsboard.server.service.executors.ExternalCallExecutorService;
79 76 import org.thingsboard.server.service.executors.SharedEventLoopGroupService;
80 77 import org.thingsboard.server.service.mail.MailExecutorService;
81   -import org.thingsboard.server.service.rpc.DeviceRpcService;
  78 +import org.thingsboard.server.service.queue.TbClusterService;
  79 +import org.thingsboard.server.service.rpc.TbCoreDeviceRpcService;
  80 +import org.thingsboard.server.service.rpc.TbRuleEngineDeviceRpcService;
82 81 import org.thingsboard.server.service.script.JsExecutorService;
83 82 import org.thingsboard.server.service.script.JsInvokeService;
84 83 import org.thingsboard.server.service.session.DeviceSessionCacheService;
... ... @@ -163,7 +162,11 @@ public class ActorSystemContext {
163 162
164 163 @Autowired
165 164 @Getter
166   - private TbRuleEngineQueueProvider ruleEngineQueueProvider;
  165 + private TbClusterService clusterService;
  166 +
  167 + @Autowired
  168 + @Getter
  169 + private TbQueueProducerProvider producerProvider;
167 170
168 171 @Autowired
169 172 @Getter
... ... @@ -199,10 +202,6 @@ public class ActorSystemContext {
199 202
200 203 @Autowired
201 204 @Getter
202   - private DeviceRpcService deviceRpcService;
203   -
204   - @Autowired
205   - @Getter
206 205 private JsInvokeService jsSandbox;
207 206
208 207 @Autowired
... ... @@ -246,6 +245,22 @@ public class ActorSystemContext {
246 245 @Getter
247 246 private TbCoreToTransportService tbCoreToTransportService;
248 247
  248 + /**
  249 + * The following Service will be null if we operate in tb-core mode
  250 + */
  251 + @Lazy
  252 + @Getter
  253 + @Autowired(required = false)
  254 + private TbRuleEngineDeviceRpcService tbRuleEngineDeviceRpcService;
  255 +
  256 + /**
  257 + * The following Service will be null if we operate in tb-rule-engine mode
  258 + */
  259 + @Lazy
  260 + @Getter
  261 + @Autowired(required = false)
  262 + private TbCoreDeviceRpcService tbCoreDeviceRpcService;
  263 +
249 264 @Lazy
250 265 @Autowired
251 266 @Getter
... ... @@ -406,14 +421,6 @@ public class ActorSystemContext {
406 421 return mapper.createObjectNode().put("server", serviceId).put("method", method).put("error", body);
407 422 }
408 423
409   - public TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToCoreMsg>> getTbCoreMsgProducer() {
410   - return ruleEngineQueueProvider.getTbCoreMsgProducer();
411   - }
412   -
413   - public TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> getRuleEngineMsgProducer() {
414   - return ruleEngineQueueProvider.getRuleEngineMsgProducer();
415   - }
416   -
417 424 public TopicPartitionInfo resolve(ServiceType serviceType, TenantId tenantId, EntityId entityId) {
418 425 return partitionService.resolve(serviceType, tenantId, entityId);
419 426 }
... ...
... ... @@ -39,7 +39,9 @@ import org.thingsboard.server.common.msg.TbActorMsg;
39 39 import org.thingsboard.server.common.msg.aware.TenantAwareMsg;
40 40 import org.thingsboard.server.common.msg.cluster.SendToClusterMsg;
41 41 import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg;
  42 +import org.thingsboard.server.common.msg.queue.PartitionChangeMsg;
42 43 import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg;
  44 +import org.thingsboard.server.common.msg.queue.ServiceType;
43 45 import org.thingsboard.server.dao.model.ModelConstants;
44 46 import org.thingsboard.server.dao.tenant.TenantService;
45 47 import scala.concurrent.duration.Duration;
... ... @@ -81,7 +83,7 @@ public class AppActor extends RuleChainManagerActor {
81 83 case SEND_TO_CLUSTER_MSG:
82 84 onPossibleClusterMsg((SendToClusterMsg) msg);
83 85 break;
84   - case CLUSTER_EVENT_MSG:
  86 + case PARTITION_CHANGE_MSG:
85 87 broadcast(msg);
86 88 break;
87 89 case COMPONENT_LIFE_CYCLE_MSG:
... ... @@ -131,7 +133,7 @@ public class AppActor extends RuleChainManagerActor {
131 133 // systemContext.getRpcService().tell(
132 134 // systemContext.getEncodingService().convertToProtoDataMessage(address.get(), msg.getMsg()));
133 135 // } else {
134   - self().tell(msg.getMsg(), ActorRef.noSender());
  136 + self().tell(msg.getMsg(), ActorRef.noSender());
135 137 // }
136 138 }
137 139
... ...
... ... @@ -22,6 +22,7 @@ import org.thingsboard.server.actors.service.ContextAwareActor;
22 22 import org.thingsboard.server.common.data.id.DeviceId;
23 23 import org.thingsboard.server.common.data.id.TenantId;
24 24 import org.thingsboard.server.common.msg.TbActorMsg;
  25 +import org.thingsboard.server.common.msg.queue.PartitionChangeMsg;
25 26 import org.thingsboard.server.common.msg.timeout.DeviceActorClientSideRpcTimeoutMsg;
26 27 import org.thingsboard.server.common.msg.timeout.DeviceActorServerSideRpcTimeoutMsg;
27 28 import org.thingsboard.server.service.rpc.ToDeviceRpcRequestActorMsg;
... ... @@ -49,6 +50,11 @@ public class DeviceActor extends ContextAwareActor {
49 50 }
50 51
51 52 @Override
  53 + public void postStop() {
  54 +
  55 + }
  56 +
  57 + @Override
52 58 protected boolean process(TbActorMsg msg) {
53 59 switch (msg.getMsgType()) {
54 60 case TRANSPORT_TO_DEVICE_ACTOR_MSG:
... ...
... ... @@ -16,13 +16,10 @@
16 16 package org.thingsboard.server.actors.device;
17 17
18 18 import akka.actor.ActorContext;
19   -import com.datastax.driver.core.utils.UUIDs;
20 19 import com.google.common.util.concurrent.FutureCallback;
21 20 import com.google.common.util.concurrent.Futures;
22 21 import com.google.common.util.concurrent.ListenableFuture;
23 22 import com.google.common.util.concurrent.MoreExecutors;
24   -import com.google.gson.Gson;
25   -import com.google.gson.JsonObject;
26 23 import com.google.protobuf.InvalidProtocolBufferException;
27 24 import lombok.extern.slf4j.Slf4j;
28 25 import org.apache.commons.collections.CollectionUtils;
... ... @@ -38,11 +35,8 @@ import org.thingsboard.server.common.data.kv.AttributeKey;
38 35 import org.thingsboard.server.common.data.kv.AttributeKvEntry;
39 36 import org.thingsboard.server.common.data.kv.KvEntry;
40 37 import org.thingsboard.server.common.data.rpc.ToDeviceRpcRequestBody;
41   -import org.thingsboard.server.common.msg.TbMsg;
42   -import org.thingsboard.server.common.msg.TbMsgDataType;
43 38 import org.thingsboard.server.common.msg.TbMsgMetaData;
44 39 import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest;
45   -import org.thingsboard.server.common.msg.session.SessionMsgType;
46 40 import org.thingsboard.server.common.msg.timeout.DeviceActorClientSideRpcTimeoutMsg;
47 41 import org.thingsboard.server.common.msg.timeout.DeviceActorServerSideRpcTimeoutMsg;
48 42 import org.thingsboard.server.gen.transport.TransportProtos;
... ... @@ -52,8 +46,6 @@ import org.thingsboard.server.gen.transport.TransportProtos.GetAttributeRequestM
52 46 import org.thingsboard.server.gen.transport.TransportProtos.GetAttributeResponseMsg;
53 47 import org.thingsboard.server.gen.transport.TransportProtos.KeyValueProto;
54 48 import org.thingsboard.server.gen.transport.TransportProtos.KeyValueType;
55   -import org.thingsboard.server.gen.transport.TransportProtos.PostAttributeMsg;
56   -import org.thingsboard.server.gen.transport.TransportProtos.PostTelemetryMsg;
57 49 import org.thingsboard.server.gen.transport.TransportProtos.SessionCloseNotificationProto;
58 50 import org.thingsboard.server.gen.transport.TransportProtos.SessionEvent;
59 51 import org.thingsboard.server.gen.transport.TransportProtos.SessionEventMsg;
... ... @@ -63,14 +55,12 @@ import org.thingsboard.server.gen.transport.TransportProtos.SubscribeToRPCMsg;
63 55 import org.thingsboard.server.gen.transport.TransportProtos.ToDeviceRpcRequestMsg;
64 56 import org.thingsboard.server.gen.transport.TransportProtos.ToDeviceRpcResponseMsg;
65 57 import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg;
66   -import org.thingsboard.server.gen.transport.TransportProtos.TsKvListProto;
67 58 import org.thingsboard.server.gen.transport.TransportProtos.TsKvProto;
68 59 import org.thingsboard.server.common.msg.queue.TbMsgCallback;
69 60 import org.thingsboard.server.service.rpc.FromDeviceRpcResponse;
70 61 import org.thingsboard.server.service.rpc.ToDeviceRpcRequestActorMsg;
71 62 import org.thingsboard.server.service.rpc.ToServerRpcResponseActorMsg;
72 63 import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWrapper;
73   -import org.thingsboard.server.common.transport.util.JsonUtils;
74 64
75 65 import javax.annotation.Nullable;
76 66 import java.util.ArrayList;
... ... @@ -103,8 +93,6 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
103 93 private final Map<Integer, ToDeviceRpcRequestMetadata> toDeviceRpcPendingMap;
104 94 private final Map<Integer, ToServerRpcRequestMetadata> toServerRpcPendingMap;
105 95
106   - private final Gson gson = new Gson();
107   -
108 96 private int rpcSeq = 0;
109 97 private String deviceName;
110 98 private String deviceType;
... ... @@ -162,7 +150,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
162 150
163 151 if (request.isOneway() && sent) {
164 152 log.debug("[{}] Rpc command response sent [{}]!", deviceId, request.getId());
165   - systemContext.getDeviceRpcService().processResponseToServerSideRPCRequestFromDeviceActor(new FromDeviceRpcResponse(msg.getMsg().getId(), null, null));
  153 + systemContext.getTbCoreDeviceRpcService().processRpcResponseFromDeviceActor(new FromDeviceRpcResponse(msg.getMsg().getId(), null, null));
166 154 } else {
167 155 registerPendingRpcRequest(context, msg, sent, rpcRequest, timeout);
168 156 }
... ... @@ -183,7 +171,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
183 171 ToDeviceRpcRequestMetadata requestMd = toDeviceRpcPendingMap.remove(msg.getId());
184 172 if (requestMd != null) {
185 173 log.debug("[{}] RPC request [{}] timeout detected!", deviceId, msg.getId());
186   - systemContext.getDeviceRpcService().processResponseToServerSideRPCRequestFromDeviceActor(new FromDeviceRpcResponse(requestMd.getMsg().getMsg().getId(),
  174 + systemContext.getTbCoreDeviceRpcService().processRpcResponseFromDeviceActor(new FromDeviceRpcResponse(requestMd.getMsg().getMsg().getId(),
187 175 null, requestMd.isSent() ? RpcError.TIMEOUT : RpcError.NO_ACTIVE_CONNECTION));
188 176 }
189 177 }
... ... @@ -215,7 +203,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
215 203 ToDeviceRpcRequestBody body = request.getBody();
216 204 if (request.isOneway()) {
217 205 sentOneWayIds.add(entry.getKey());
218   - systemContext.getDeviceRpcService().processResponseToServerSideRPCRequestFromDeviceActor(new FromDeviceRpcResponse(request.getId(), null, null));
  206 + systemContext.getTbCoreDeviceRpcService().processRpcResponseFromDeviceActor(new FromDeviceRpcResponse(request.getId(), null, null));
219 207 }
220 208 ToDeviceRpcRequestMsg rpcRequest = ToDeviceRpcRequestMsg.newBuilder().setRequestId(
221 209 entry.getKey()).setMethodName(body.getMethod()).setParams(body.getParams()).build();
... ... @@ -417,7 +405,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
417 405 ToDeviceRpcRequestMetadata requestMd = toDeviceRpcPendingMap.remove(responseMsg.getRequestId());
418 406 boolean success = requestMd != null;
419 407 if (success) {
420   - systemContext.getDeviceRpcService().processResponseToServerSideRPCRequestFromDeviceActor(new FromDeviceRpcResponse(requestMd.getMsg().getMsg().getId(),
  408 + systemContext.getTbCoreDeviceRpcService().processRpcResponseFromDeviceActor(new FromDeviceRpcResponse(requestMd.getMsg().getMsg().getId(),
421 409 responseMsg.getPayload(), null));
422 410 } else {
423 411 log.debug("[{}] Rpc command response [{}] is stale!", deviceId, responseMsg.getRequestId());
... ... @@ -689,4 +677,5 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
689 677 dumpSessions();
690 678 }
691 679 }
  680 +
692 681 }
... ...
... ... @@ -5,7 +5,7 @@
5 5 * you may not use this file except in compliance with the License.
6 6 * You may obtain a copy of the License at
7 7 *
8   - * http://www.apache.org/licenses/LICENSE-2.0
  8 + * http://www.apache.org/licenses/LICENSE-2.0
9 9 *
10 10 * Unless required by applicable law or agreed to in writing, software
11 11 * distributed under the License is distributed on an "AS IS" BASIS,
... ... @@ -48,9 +48,7 @@ import org.thingsboard.server.common.data.rule.RuleNode;
48 48 import org.thingsboard.server.common.msg.TbMsg;
49 49 import org.thingsboard.server.common.msg.TbMsgDataType;
50 50 import org.thingsboard.server.common.msg.TbMsgMetaData;
51   -import org.thingsboard.server.common.msg.cluster.SendToClusterMsg;
52 51 import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest;
53   -import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg;
54 52 import org.thingsboard.server.dao.alarm.AlarmService;
55 53 import org.thingsboard.server.dao.asset.AssetService;
56 54 import org.thingsboard.server.dao.attributes.AttributesService;
... ... @@ -67,8 +65,8 @@ import org.thingsboard.server.dao.timeseries.TimeseriesService;
67 65 import org.thingsboard.server.dao.user.UserService;
68 66 import org.thingsboard.server.gen.transport.TransportProtos;
69 67 import org.thingsboard.server.queue.common.TbProtoQueueMsg;
70   -import org.thingsboard.server.queue.discovery.ServiceType;
71   -import org.thingsboard.server.queue.discovery.TopicPartitionInfo;
  68 +import org.thingsboard.server.common.msg.queue.ServiceType;
  69 +import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
72 70 import org.thingsboard.server.service.script.RuleNodeJsScriptEngine;
73 71 import scala.concurrent.duration.Duration;
74 72
... ... @@ -155,12 +153,7 @@ class DefaultTbContext implements TbContext {
155 153
156 154 @Override
157 155 public void sendTbMsgToRuleEngine(TbMsg tbMsg) {
158   - TenantId tenantId = getTenantId();
159   - TopicPartitionInfo tpi = mainCtx.resolve(ServiceType.TB_RULE_ENGINE, tenantId, tbMsg.getOriginator());
160   - TransportProtos.ToRuleEngineMsg msg = TransportProtos.ToRuleEngineMsg.newBuilder().setTbMsg(TbMsg.toByteString(tbMsg))
161   - .setTenantIdMSB(tenantId.getId().getMostSignificantBits())
162   - .setTenantIdLSB(tenantId.getId().getLeastSignificantBits()).build();
163   - mainCtx.getRuleEngineMsgProducer().send(tpi, new TbProtoQueueMsg<>(tbMsg.getId(), msg), null);
  156 + mainCtx.getClusterService().onToRuleEngineMsg(getTenantId(), tbMsg.getOriginator(), tbMsg);
164 157 }
165 158
166 159 public TbMsg customerCreatedMsg(Customer customer, RuleNodeId ruleNodeId) {
... ... @@ -351,36 +344,7 @@ class DefaultTbContext implements TbContext {
351 344
352 345 @Override
353 346 public RuleEngineRpcService getRpcService() {
354   - return new RuleEngineRpcService() {
355   - @Override
356   - public void sendRpcReply(DeviceId deviceId, int requestId, String body) {
357   - mainCtx.getDeviceRpcService().sendReplyToRpcCallFromDevice(nodeCtx.getTenantId(), deviceId, requestId, body);
358   - }
359   -
360   - @Override
361   - public void sendRpcRequest(RuleEngineDeviceRpcRequest src, Consumer<RuleEngineDeviceRpcResponse> consumer) {
362   - ToDeviceRpcRequest request = new ToDeviceRpcRequest(src.getRequestUUID(), nodeCtx.getTenantId(), src.getDeviceId(),
363   - src.isOneway(), src.getExpirationTime(), new ToDeviceRpcRequestBody(src.getMethod(), src.getBody()));
364   - mainCtx.getDeviceRpcService().forwardServerSideRPCRequestToDeviceActor(request, response -> {
365   - if (src.isRestApiCall()) {
366   - //TODO 2.5
367   -// ServerAddress requestOriginAddress;
368   -// if (!StringUtils.isEmpty(src.getOriginHost())) {
369   -// requestOriginAddress = new ServerAddress(src.getOriginHost(), src.getOriginPort(), ServerType.CORE);
370   -// } else {
371   -// requestOriginAddress = mainCtx.getRoutingService().getCurrentServer();
372   -// }
373   -// mainCtx.getDeviceRpcService().processResponseToServerSideRPCRequestFromRuleEngine(requestOriginAddress, response);
374   - }
375   - consumer.accept(RuleEngineDeviceRpcResponse.builder()
376   - .deviceId(src.getDeviceId())
377   - .requestId(src.getRequestId())
378   - .error(response.getError())
379   - .response(response.getResponse())
380   - .build());
381   - });
382   - }
383   - };
  347 + return mainCtx.getTbRuleEngineDeviceRpcService();
384 348 }
385 349
386 350 @Override
... ...
... ... @@ -24,6 +24,7 @@ import org.thingsboard.server.common.data.id.RuleChainId;
24 24 import org.thingsboard.server.common.data.id.TenantId;
25 25 import org.thingsboard.server.common.msg.TbActorMsg;
26 26 import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg;
  27 +import org.thingsboard.server.common.msg.queue.PartitionChangeMsg;
27 28 import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg;
28 29 import scala.concurrent.duration.Duration;
29 30
... ... @@ -51,7 +52,8 @@ public class RuleChainActor extends ComponentActor<RuleChainId, RuleChainActorMe
51 52 case RULE_CHAIN_TO_RULE_CHAIN_MSG:
52 53 processor.onRuleChainToRuleChainMsg((RuleChainToRuleChainMsg) msg);
53 54 break;
54   - case CLUSTER_EVENT_MSG:
  55 + case PARTITION_CHANGE_MSG:
  56 + onClusterEventMsg((PartitionChangeMsg) msg);
55 57 break;
56 58 case STATS_PERSIST_TICK_MSG:
57 59 onStatsPersistTick(id);
... ...
... ... @@ -5,7 +5,7 @@
5 5 * you may not use this file except in compliance with the License.
6 6 * You may obtain a copy of the License at
7 7 *
8   - * http://www.apache.org/licenses/LICENSE-2.0
  8 + * http://www.apache.org/licenses/LICENSE-2.0
9 9 *
10 10 * Unless required by applicable law or agreed to in writing, software
11 11 * distributed under the License is distributed on an "AS IS" BASIS,
... ... @@ -18,7 +18,6 @@ package org.thingsboard.server.actors.ruleChain;
18 18 import akka.actor.ActorContext;
19 19 import akka.actor.ActorRef;
20 20 import akka.actor.Props;
21   -import com.google.protobuf.ByteString;
22 21 import lombok.extern.slf4j.Slf4j;
23 22 import org.thingsboard.rule.engine.api.TbRelationTypes;
24 23 import org.thingsboard.server.actors.ActorSystemContext;
... ... @@ -35,7 +34,7 @@ import org.thingsboard.server.common.data.relation.EntityRelation;
35 34 import org.thingsboard.server.common.data.rule.RuleChain;
36 35 import org.thingsboard.server.common.data.rule.RuleNode;
37 36 import org.thingsboard.server.common.msg.TbMsg;
38   -import org.thingsboard.server.common.msg.cluster.ClusterEventMsg;
  37 +import org.thingsboard.server.common.msg.queue.PartitionChangeMsg;
39 38 import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg;
40 39 import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg;
41 40 import org.thingsboard.server.dao.rule.RuleChainService;
... ... @@ -45,9 +44,8 @@ import org.thingsboard.server.queue.TbQueueCallback;
45 44 import org.thingsboard.server.queue.TbQueueProducer;
46 45 import org.thingsboard.server.queue.TbQueueTbMsgCallbackWrapper;
47 46 import org.thingsboard.server.queue.common.TbProtoQueueMsg;
48   -import org.thingsboard.server.queue.discovery.PartitionService;
49   -import org.thingsboard.server.queue.discovery.ServiceType;
50   -import org.thingsboard.server.queue.discovery.TopicPartitionInfo;
  47 +import org.thingsboard.server.common.msg.queue.ServiceType;
  48 +import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
51 49
52 50 import java.util.ArrayList;
53 51 import java.util.Collections;
... ... @@ -82,7 +80,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh
82 80 this.nodeActors = new HashMap<>();
83 81 this.nodeRoutes = new HashMap<>();
84 82 this.service = systemContext.getRuleChainService();
85   - this.producer = systemContext.getRuleEngineQueueProvider().getRuleEngineMsgProducer();
  83 + this.producer = systemContext.getProducerProvider().getRuleEngineMsgProducer();
86 84 }
87 85
88 86 @Override
... ... @@ -153,8 +151,8 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh
153 151 }
154 152
155 153 @Override
156   - public void onClusterEventMsg(ClusterEventMsg msg) {
157   -
  154 + public void onPartitionChangeMsg(PartitionChangeMsg msg) {
  155 + nodeActors.values().stream().map(RuleNodeCtx::getSelfActor).forEach(actorRef -> actorRef.tell(msg, self));
158 156 }
159 157
160 158 private ActorRef createRuleNodeActor(ActorContext context, RuleNode ruleNode) {
... ...
... ... @@ -27,7 +27,7 @@ import org.thingsboard.server.common.data.id.RuleNodeId;
27 27 import org.thingsboard.server.common.data.id.TenantId;
28 28 import org.thingsboard.server.common.data.plugin.ComponentLifecycleState;
29 29 import org.thingsboard.server.common.data.rule.RuleNode;
30   -import org.thingsboard.server.common.msg.cluster.ClusterEventMsg;
  30 +import org.thingsboard.server.common.msg.queue.PartitionChangeMsg;
31 31 import org.thingsboard.server.dao.rule.RuleChainService;
32 32
33 33 /**
... ... @@ -84,9 +84,9 @@ public class RuleNodeActorMessageProcessor extends ComponentMsgProcessor<RuleNod
84 84 }
85 85
86 86 @Override
87   - public void onClusterEventMsg(ClusterEventMsg msg) {
  87 + public void onPartitionChangeMsg(PartitionChangeMsg msg) {
88 88 if (tbNode != null) {
89   - tbNode.onClusterEventMsg(defaultCtx, msg);
  89 + tbNode.onPartitionChangeMsg(defaultCtx, msg);
90 90 }
91 91 }
92 92
... ...
... ... @@ -15,22 +15,7 @@
15 15 */
16 16 package org.thingsboard.server.actors.service;
17 17
18   -import org.thingsboard.server.common.data.id.DeviceId;
19   -import org.thingsboard.server.common.data.id.EntityId;
20   -import org.thingsboard.server.common.data.id.TenantId;
21   -import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
22   -import org.thingsboard.server.common.msg.TbActorMsg;
23   -import org.thingsboard.server.common.msg.cluster.SendToClusterMsg;
24   -import org.thingsboard.server.common.transport.SessionMsgProcessor;
  18 +public interface ActorService {
25 19
26   -public interface ActorService extends SessionMsgProcessor {
27   -
28   - void onEntityStateChange(TenantId tenantId, EntityId entityId, ComponentLifecycleEvent state);
29   -
30   - void onMsg(TbActorMsg msg);
31   -
32   - void onCredentialsUpdate(TenantId tenantId, DeviceId deviceId);
33   -
34   - void onDeviceNameOrTypeUpdate(TenantId tenantId, DeviceId deviceId, String deviceName, String deviceType);
35 20
36 21 }
... ...
... ... @@ -22,7 +22,7 @@ import org.thingsboard.server.actors.stats.StatsPersistMsg;
22 22 import org.thingsboard.server.common.data.id.EntityId;
23 23 import org.thingsboard.server.common.data.id.TenantId;
24 24 import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
25   -import org.thingsboard.server.common.msg.cluster.ClusterEventMsg;
  25 +import org.thingsboard.server.common.msg.queue.PartitionChangeMsg;
26 26 import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg;
27 27
28 28 /**
... ... @@ -115,9 +115,9 @@ public abstract class ComponentActor<T extends EntityId, P extends ComponentMsgP
115 115 }
116 116 }
117 117
118   - protected void onClusterEventMsg(ClusterEventMsg msg) {
  118 + protected void onClusterEventMsg(PartitionChangeMsg msg) {
119 119 try {
120   - processor.onClusterEventMsg(msg);
  120 + processor.onPartitionChangeMsg(msg);
121 121 } catch (Exception e) {
122 122 logAndPersist("onClusterEventMsg", e);
123 123 }
... ...
... ... @@ -32,17 +32,16 @@ import org.thingsboard.server.actors.ActorSystemContext;
32 32 import org.thingsboard.server.actors.app.AppActor;
33 33 import org.thingsboard.server.actors.app.AppInitMsg;
34 34 import org.thingsboard.server.actors.stats.StatsActor;
35   -import org.thingsboard.server.common.data.Device;
36 35 import org.thingsboard.server.common.data.id.DeviceId;
37 36 import org.thingsboard.server.common.data.id.EntityId;
38 37 import org.thingsboard.server.common.data.id.TenantId;
39 38 import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
40 39 import org.thingsboard.server.common.msg.TbActorMsg;
41   -import org.thingsboard.server.common.msg.cluster.ClusterEventMsg;
  40 +import org.thingsboard.server.common.msg.queue.PartitionChangeMsg;
42 41 import org.thingsboard.server.common.msg.cluster.SendToClusterMsg;
43 42 import org.thingsboard.server.common.msg.cluster.ToAllNodesMsg;
44 43 import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg;
45   -import org.thingsboard.server.service.state.DeviceStateService;
  44 +import org.thingsboard.server.queue.discovery.PartitionChangeEvent;
46 45 import scala.concurrent.Await;
47 46 import scala.concurrent.Future;
48 47 import scala.concurrent.duration.Duration;
... ... @@ -61,20 +60,14 @@ public class DefaultActorService implements ActorService {
61 60 public static final String CORE_DISPATCHER_NAME = "core-dispatcher";
62 61 public static final String SYSTEM_RULE_DISPATCHER_NAME = "system-rule-dispatcher";
63 62 public static final String TENANT_RULE_DISPATCHER_NAME = "rule-dispatcher";
64   - public static final String RPC_DISPATCHER_NAME = "rpc-dispatcher";
65 63
66 64 @Autowired
67 65 private ActorSystemContext actorContext;
68 66
69   - @Autowired
70   - private DeviceStateService deviceStateService;
71   -
72 67 private ActorSystem system;
73 68
74 69 private ActorRef appActor;
75 70
76   - private ActorRef rpcManagerActor;
77   -
78 71 @PostConstruct
79 72 public void initActorSystem() {
80 73 log.info("Initializing Actor system.");
... ... @@ -97,6 +90,12 @@ public class DefaultActorService implements ActorService {
97 90 appActor.tell(new AppInitMsg(), ActorRef.noSender());
98 91 }
99 92
  93 + @EventListener(PartitionChangeEvent.class)
  94 + public void onApplicationEvent(PartitionChangeEvent partitionChangeEvent) {
  95 + log.info("Received partition change event.");
  96 + this.appActor.tell(new PartitionChangeMsg(partitionChangeEvent.getServiceKey(), partitionChangeEvent.getPartitions()), ActorRef.noSender());
  97 + }
  98 +
100 99 @PreDestroy
101 100 public void stopActorSystem() {
102 101 Future<Terminated> status = system.terminate();
... ... @@ -108,68 +107,10 @@ public class DefaultActorService implements ActorService {
108 107 }
109 108 }
110 109
111   - @Override
112   - public void onMsg(TbActorMsg msg) {
113   - appActor.tell(msg, ActorRef.noSender());
114   - }
115   -
116   - //TODO 2.5
117   -// @Override
118   -// public void onServerAdded(ServerInstance server) {
119   -// log.trace("Processing onServerAdded msg: {}", server);
120   -// broadcast(new ClusterEventMsg(server.getServerAddress(), true));
121   -// }
122   -//
123   -// @Override
124   -// public void onServerUpdated(ServerInstance server) {
125   -// //Do nothing
126   -// }
127   -//
128   -// @Override
129   -// public void onServerRemoved(ServerInstance server) {
130   -// log.trace("Processing onServerRemoved msg: {}", server);
131   -// broadcast(new ClusterEventMsg(server.getServerAddress(), false));
132   -// }
133   -
134   - @Override
135   - public void onEntityStateChange(TenantId tenantId, EntityId entityId, ComponentLifecycleEvent state) {
136   - log.trace("[{}] Processing {} state change event: {}", tenantId, entityId.getEntityType(), state);
137   - broadcast(new ComponentLifecycleMsg(tenantId, entityId, state));
138   - }
139   -
140   - @Override
141   - public void onCredentialsUpdate(TenantId tenantId, DeviceId deviceId) {
142   - DeviceCredentialsUpdateNotificationMsg msg = new DeviceCredentialsUpdateNotificationMsg(tenantId, deviceId);
143   - appActor.tell(new SendToClusterMsg(deviceId, msg), ActorRef.noSender());
144   - }
145   -
146   - @Override
147   - public void onDeviceNameOrTypeUpdate(TenantId tenantId, DeviceId deviceId, String deviceName, String deviceType) {
148   - log.trace("[{}] Processing onDeviceNameOrTypeUpdate event, deviceName: {}, deviceType: {}", deviceId, deviceName, deviceType);
149   - DeviceNameOrTypeUpdateMsg msg = new DeviceNameOrTypeUpdateMsg(tenantId, deviceId, deviceName, deviceType);
150   - appActor.tell(new SendToClusterMsg(deviceId, msg), ActorRef.noSender());
151   - }
152   -
153   - public void broadcast(ToAllNodesMsg msg) {
154   - actorContext.getEncodingService().encode(msg);
155   - //TODO 2.5
156   -// rpcService.broadcast(new RpcBroadcastMsg(ClusterAPIProtos.ClusterMessage
157   -// .newBuilder()
158   -// .setPayload(ByteString
159   -// .copyFrom(actorContext.getEncodingService().encode(msg)))
160   -// .setMessageType(CLUSTER_ACTOR_MESSAGE)
161   -// .build()));
162   - appActor.tell(msg, ActorRef.noSender());
163   - }
164   -
165   - private void broadcast(ClusterEventMsg msg) {
166   - this.appActor.tell(msg, ActorRef.noSender());
167   - this.rpcManagerActor.tell(msg, ActorRef.noSender());
168   - }
169   -
170 110 @Value("${cluster.stats.enabled:false}")
171 111 private boolean statsEnabled;
172 112
  113 + //TODO 2.5
173 114 private final AtomicInteger sentClusterMsgs = new AtomicInteger(0);
174 115 private final AtomicInteger receivedClusterMsgs = new AtomicInteger(0);
175 116
... ... @@ -258,8 +199,4 @@ public class DefaultActorService implements ActorService {
258 199 // rpcManagerActor.tell(msg, ActorRef.noSender());
259 200 // }
260 201
261   - @Override
262   - public void onDeviceAdded(Device device) {
263   - deviceStateService.onDeviceAdded(device);
264   - }
265 202 }
... ...
... ... @@ -16,20 +16,13 @@
16 16 package org.thingsboard.server.actors.shared;
17 17
18 18 import akka.actor.ActorContext;
19   -import akka.event.LoggingAdapter;
20   -import com.google.common.util.concurrent.FutureCallback;
21   -import com.google.common.util.concurrent.Futures;
22 19 import lombok.extern.slf4j.Slf4j;
23 20 import org.thingsboard.server.actors.ActorSystemContext;
24 21 import org.thingsboard.server.actors.stats.StatsPersistTick;
25 22 import org.thingsboard.server.common.data.id.EntityId;
26 23 import org.thingsboard.server.common.data.id.TenantId;
27 24 import org.thingsboard.server.common.data.plugin.ComponentLifecycleState;
28   -import org.thingsboard.server.common.msg.TbMsg;
29   -import org.thingsboard.server.common.msg.cluster.ClusterEventMsg;
30   -
31   -import javax.annotation.Nullable;
32   -import java.util.function.Consumer;
  25 +import org.thingsboard.server.common.msg.queue.PartitionChangeMsg;
33 26
34 27 @Slf4j
35 28 public abstract class ComponentMsgProcessor<T extends EntityId> extends AbstractContextAwareMsgProcessor {
... ... @@ -50,7 +43,7 @@ public abstract class ComponentMsgProcessor<T extends EntityId> extends Abstract
50 43
51 44 public abstract void stop(ActorContext context) throws Exception;
52 45
53   - public abstract void onClusterEventMsg(ClusterEventMsg msg) throws Exception;
  46 + public abstract void onPartitionChangeMsg(PartitionChangeMsg msg) throws Exception;
54 47
55 48 public void onCreated(ActorContext context) throws Exception {
56 49 start(context);
... ...
... ... @@ -41,9 +41,14 @@ import org.thingsboard.server.common.msg.TbMsg;
41 41 import org.thingsboard.server.common.msg.aware.DeviceAwareMsg;
42 42 import org.thingsboard.server.common.msg.aware.RuleChainAwareMsg;
43 43 import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg;
  44 +import org.thingsboard.server.common.msg.queue.PartitionChangeMsg;
44 45 import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg;
  46 +import org.thingsboard.server.common.msg.queue.ServiceType;
45 47 import scala.concurrent.duration.Duration;
46 48
  49 +import java.util.List;
  50 +import java.util.stream.Collectors;
  51 +
47 52 public class TenantActor extends RuleChainManagerActor {
48 53
49 54 private final TenantId tenantId;
... ... @@ -79,8 +84,21 @@ public class TenantActor extends RuleChainManagerActor {
79 84 @Override
80 85 protected boolean process(TbActorMsg msg) {
81 86 switch (msg.getMsgType()) {
82   - case CLUSTER_EVENT_MSG:
83   - broadcast(msg);
  87 + case PARTITION_CHANGE_MSG:
  88 + PartitionChangeMsg partitionChangeMsg = (PartitionChangeMsg) msg;
  89 + ServiceType serviceType = partitionChangeMsg.getServiceKey().getServiceType();
  90 + if (ServiceType.TB_RULE_ENGINE.equals(serviceType)) {
  91 + //To Rule Chain Actors
  92 + broadcast(msg);
  93 + } else if (ServiceType.TB_CORE.equals(serviceType)) {
  94 + //To Device Actors
  95 + List<DeviceId> repartitionedDevices =
  96 + deviceActors.keySet().stream().filter(deviceId -> !isMyPartition(deviceId)).collect(Collectors.toList());
  97 + for (DeviceId deviceId : repartitionedDevices) {
  98 + ActorRef deviceActor = deviceActors.remove(deviceId);
  99 + context().stop(deviceActor);
  100 + }
  101 + }
84 102 break;
85 103 case COMPONENT_LIFE_CYCLE_MSG:
86 104 onComponentLifecycleMsg((ComponentLifecycleMsg) msg);
... ... @@ -106,6 +124,10 @@ public class TenantActor extends RuleChainManagerActor {
106 124 return true;
107 125 }
108 126
  127 + private boolean isMyPartition(DeviceId deviceId) {
  128 + return systemContext.resolve(ServiceType.TB_CORE, tenantId, deviceId).isMyPartition();
  129 + }
  130 +
109 131 private void onQueueToRuleEngineMsg(QueueToRuleEngineMsg msg) {
110 132 TbMsg tbMsg = msg.getTbMsg();
111 133 if (tbMsg.getRuleChainId() == null) {
... ... @@ -169,7 +191,7 @@ public class TenantActor extends RuleChainManagerActor {
169 191 if (removed) {
170 192 log.debug("[{}] Removed actor:", terminated);
171 193 } else {
172   - log.warn("Removed actor was not found in the device map!");
  194 + log.debug("Removed actor was not found in the device map!");
173 195 }
174 196 } else {
175 197 throw new IllegalStateException("Remote actors are not supported!");
... ...
... ... @@ -27,7 +27,6 @@ import org.springframework.beans.factory.annotation.Value;
27 27 import org.springframework.security.core.Authentication;
28 28 import org.springframework.security.core.context.SecurityContextHolder;
29 29 import org.springframework.web.bind.annotation.ExceptionHandler;
30   -import org.thingsboard.server.actors.service.ActorService;
31 30 import org.thingsboard.server.common.data.Customer;
32 31 import org.thingsboard.server.common.data.Dashboard;
33 32 import org.thingsboard.server.common.data.DashboardInfo;
... ... @@ -71,8 +70,6 @@ import org.thingsboard.server.common.data.widget.WidgetsBundle;
71 70 import org.thingsboard.server.common.msg.TbMsg;
72 71 import org.thingsboard.server.common.msg.TbMsgDataType;
73 72 import org.thingsboard.server.common.msg.TbMsgMetaData;
74   -import org.thingsboard.server.common.msg.cluster.SendToClusterMsg;
75   -import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg;
76 73 import org.thingsboard.server.dao.alarm.AlarmService;
77 74 import org.thingsboard.server.dao.asset.AssetService;
78 75 import org.thingsboard.server.dao.attributes.AttributesService;
... ... @@ -93,13 +90,10 @@ import org.thingsboard.server.dao.user.UserService;
93 90 import org.thingsboard.server.dao.widget.WidgetTypeService;
94 91 import org.thingsboard.server.dao.widget.WidgetsBundleService;
95 92 import org.thingsboard.server.exception.ThingsboardErrorResponseHandler;
96   -import org.thingsboard.server.gen.transport.TransportProtos;
97   -import org.thingsboard.server.queue.common.TbProtoQueueMsg;
98 93 import org.thingsboard.server.queue.discovery.PartitionService;
99   -import org.thingsboard.server.queue.discovery.ServiceType;
100   -import org.thingsboard.server.queue.discovery.TopicPartitionInfo;
101   -import org.thingsboard.server.queue.provider.TbCoreQueueProvider;
  94 +import org.thingsboard.server.queue.provider.TbQueueProducerProvider;
102 95 import org.thingsboard.server.service.component.ComponentDiscoveryService;
  96 +import org.thingsboard.server.service.queue.TbClusterService;
103 97 import org.thingsboard.server.service.security.model.SecurityUser;
104 98 import org.thingsboard.server.service.security.permission.AccessControlService;
105 99 import org.thingsboard.server.service.security.permission.Operation;
... ... @@ -168,7 +162,7 @@ public abstract class BaseController {
168 162 protected RuleChainService ruleChainService;
169 163
170 164 @Autowired
171   - protected ActorService actorService;
  165 + protected TbClusterService tbClusterService;
172 166
173 167 @Autowired
174 168 protected RelationService relationService;
... ... @@ -195,7 +189,7 @@ public abstract class BaseController {
195 189 protected PartitionService partitionService;
196 190
197 191 @Autowired
198   - protected TbCoreQueueProvider coreQueueProvider;
  192 + protected TbQueueProducerProvider producerProvider;
199 193
200 194 @Value("${server.log_controller_error_stack_trace}")
201 195 @Getter
... ... @@ -674,12 +668,7 @@ public abstract class BaseController {
674 668 TbMsg tbMsg = new TbMsg(UUIDs.timeBased(), msgType, entityId, metaData, TbMsgDataType.JSON
675 669 , json.writeValueAsString(entityNode)
676 670 , null, null, null);
677   - TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_RULE_ENGINE, user.getTenantId(), entityId);
678   - TransportProtos.ToRuleEngineMsg msg = TransportProtos.ToRuleEngineMsg.newBuilder()
679   - .setTenantIdMSB(user.getTenantId().getId().getMostSignificantBits())
680   - .setTenantIdLSB(user.getTenantId().getId().getLeastSignificantBits())
681   - .setTbMsg(TbMsg.toByteString(tbMsg)).build();
682   - coreQueueProvider.getRuleEngineMsgProducer().send(tpi, new TbProtoQueueMsg<>(tbMsg.getId(), msg), null);
  671 + tbClusterService.onToRuleEngineMsg(user.getTenantId(), entityId, tbMsg);
683 672 } catch (Exception e) {
684 673 log.warn("[{}] Failed to push entity action to rule engine: {}", entityId, actionType, e);
685 674 }
... ...
... ... @@ -30,6 +30,8 @@ import org.springframework.web.bind.annotation.ResponseBody;
30 30 import org.springframework.web.bind.annotation.ResponseStatus;
31 31 import org.springframework.web.bind.annotation.RestController;
32 32 import org.springframework.web.context.request.async.DeferredResult;
  33 +import org.thingsboard.rule.engine.api.msg.DeviceCredentialsUpdateNotificationMsg;
  34 +import org.thingsboard.rule.engine.api.msg.DeviceNameOrTypeUpdateMsg;
33 35 import org.thingsboard.server.common.data.Customer;
34 36 import org.thingsboard.server.common.data.DataConstants;
35 37 import org.thingsboard.server.common.data.Device;
... ... @@ -94,12 +96,8 @@ public class DeviceController extends BaseController {
94 96
95 97 Device savedDevice = checkNotNull(deviceService.saveDeviceWithAccessToken(device, accessToken));
96 98
97   - actorService
98   - .onDeviceNameOrTypeUpdate(
99   - savedDevice.getTenantId(),
100   - savedDevice.getId(),
101   - savedDevice.getName(),
102   - savedDevice.getType());
  99 + tbClusterService.onToCoreMsg(new DeviceNameOrTypeUpdateMsg(savedDevice.getTenantId(),
  100 + savedDevice.getId(), savedDevice.getName(), savedDevice.getType()));
103 101
104 102 logEntityAction(savedDevice.getId(), savedDevice,
105 103 savedDevice.getCustomerId(),
... ... @@ -252,7 +250,9 @@ public class DeviceController extends BaseController {
252 250 try {
253 251 Device device = checkDeviceId(deviceCredentials.getDeviceId(), Operation.WRITE_CREDENTIALS);
254 252 DeviceCredentials result = checkNotNull(deviceCredentialsService.updateDeviceCredentials(getCurrentUser().getTenantId(), deviceCredentials));
255   - actorService.onCredentialsUpdate(getCurrentUser().getTenantId(), deviceCredentials.getDeviceId());
  253 +
  254 + tbClusterService.onToCoreMsg(new DeviceCredentialsUpdateNotificationMsg(getCurrentUser().getTenantId(), deviceCredentials.getDeviceId()));
  255 +
256 256 logEntityAction(device.getId(), device,
257 257 device.getCustomerId(),
258 258 ActionType.CREDENTIALS_UPDATED, null, deviceCredentials);
... ... @@ -425,6 +425,7 @@ public class DeviceController extends BaseController {
425 425 deferredResult.setResult(new ResponseEntity<>(HttpStatus.BAD_REQUEST));
426 426 }
427 427 }
  428 +
428 429 @Override
429 430 public void onFailure(Throwable t) {
430 431 deferredResult.setErrorResult(t);
... ...
... ... @@ -20,6 +20,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
20 20 import com.google.common.util.concurrent.FutureCallback;
21 21 import lombok.extern.slf4j.Slf4j;
22 22 import org.springframework.beans.factory.annotation.Autowired;
  23 +import org.springframework.context.annotation.Lazy;
23 24 import org.springframework.http.HttpStatus;
24 25 import org.springframework.http.ResponseEntity;
25 26 import org.springframework.security.access.prepost.PreAuthorize;
... ... @@ -31,7 +32,6 @@ import org.springframework.web.bind.annotation.RequestMethod;
31 32 import org.springframework.web.bind.annotation.ResponseBody;
32 33 import org.springframework.web.bind.annotation.RestController;
33 34 import org.springframework.web.context.request.async.DeferredResult;
34   -import org.thingsboard.common.util.ThingsBoardThreadFactory;
35 35 import org.thingsboard.rule.engine.api.RpcError;
36 36 import org.thingsboard.server.common.data.audit.ActionType;
37 37 import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
... ... @@ -43,22 +43,18 @@ import org.thingsboard.server.common.data.id.UUIDBased;
43 43 import org.thingsboard.server.common.data.rpc.RpcRequest;
44 44 import org.thingsboard.server.common.data.rpc.ToDeviceRpcRequestBody;
45 45 import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest;
46   -import org.thingsboard.server.service.rpc.DeviceRpcService;
47 46 import org.thingsboard.server.service.rpc.FromDeviceRpcResponse;
48 47 import org.thingsboard.server.service.rpc.LocalRequestMetaData;
  48 +import org.thingsboard.server.service.rpc.TbCoreDeviceRpcService;
49 49 import org.thingsboard.server.service.security.AccessValidator;
50 50 import org.thingsboard.server.service.security.model.SecurityUser;
51 51 import org.thingsboard.server.service.security.permission.Operation;
52 52 import org.thingsboard.server.service.telemetry.exception.ToErrorResponseEntity;
53 53
54 54 import javax.annotation.Nullable;
55   -import javax.annotation.PostConstruct;
56   -import javax.annotation.PreDestroy;
57 55 import java.io.IOException;
58 56 import java.util.Optional;
59 57 import java.util.UUID;
60   -import java.util.concurrent.ExecutorService;
61   -import java.util.concurrent.Executors;
62 58
63 59 /**
64 60 * Created by ashvayka on 22.03.18.
... ... @@ -72,7 +68,7 @@ public class RpcController extends BaseController {
72 68 protected final ObjectMapper jsonMapper = new ObjectMapper();
73 69
74 70 @Autowired
75   - private DeviceRpcService deviceRpcService;
  71 + private TbCoreDeviceRpcService deviceRpcService;
76 72
77 73 @Autowired
78 74 private AccessValidator accessValidator;
... ... @@ -116,7 +112,7 @@ public class RpcController extends BaseController {
116 112 timeout,
117 113 body
118 114 );
119   - deviceRpcService.processRestAPIRpcRequestToRuleEngine(rpcRequest, fromDeviceRpcResponse -> reply(new LocalRequestMetaData(rpcRequest, currentUser, result), fromDeviceRpcResponse));
  115 + deviceRpcService.processRestApiRpcRequest(rpcRequest, fromDeviceRpcResponse -> reply(new LocalRequestMetaData(rpcRequest, currentUser, result), fromDeviceRpcResponse));
120 116 }
121 117
122 118 @Override
... ...
... ... @@ -131,7 +131,7 @@ public class RuleChainController extends BaseController {
131 131
132 132 RuleChain savedRuleChain = checkNotNull(ruleChainService.saveRuleChain(ruleChain));
133 133
134   - actorService.onEntityStateChange(ruleChain.getTenantId(), savedRuleChain.getId(),
  134 + tbClusterService.onEntityStateChange(ruleChain.getTenantId(), savedRuleChain.getId(),
135 135 created ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED);
136 136
137 137 logEntityAction(savedRuleChain.getId(), savedRuleChain,
... ... @@ -162,7 +162,7 @@ public class RuleChainController extends BaseController {
162 162
163 163 previousRootRuleChain = ruleChainService.findRuleChainById(getTenantId(), previousRootRuleChain.getId());
164 164
165   - actorService.onEntityStateChange(previousRootRuleChain.getTenantId(), previousRootRuleChain.getId(),
  165 + tbClusterService.onEntityStateChange(previousRootRuleChain.getTenantId(), previousRootRuleChain.getId(),
166 166 ComponentLifecycleEvent.UPDATED);
167 167
168 168 logEntityAction(previousRootRuleChain.getId(), previousRootRuleChain,
... ... @@ -170,7 +170,7 @@ public class RuleChainController extends BaseController {
170 170
171 171 ruleChain = ruleChainService.findRuleChainById(getTenantId(), ruleChainId);
172 172
173   - actorService.onEntityStateChange(ruleChain.getTenantId(), ruleChain.getId(),
  173 + tbClusterService.onEntityStateChange(ruleChain.getTenantId(), ruleChain.getId(),
174 174 ComponentLifecycleEvent.UPDATED);
175 175
176 176 logEntityAction(ruleChain.getId(), ruleChain,
... ... @@ -204,7 +204,7 @@ public class RuleChainController extends BaseController {
204 204 RuleChain ruleChain = checkRuleChain(ruleChainMetaData.getRuleChainId(), Operation.WRITE);
205 205 RuleChainMetaData savedRuleChainMetaData = checkNotNull(ruleChainService.saveRuleChainMetaData(tenantId, ruleChainMetaData));
206 206
207   - actorService.onEntityStateChange(ruleChain.getTenantId(), ruleChain.getId(), ComponentLifecycleEvent.UPDATED);
  207 + tbClusterService.onEntityStateChange(ruleChain.getTenantId(), ruleChain.getId(), ComponentLifecycleEvent.UPDATED);
208 208
209 209 logEntityAction(ruleChain.getId(), ruleChain,
210 210 null,
... ... @@ -255,9 +255,9 @@ public class RuleChainController extends BaseController {
255 255 referencingRuleChainIds.remove(ruleChain.getId());
256 256
257 257 referencingRuleChainIds.forEach(referencingRuleChainId ->
258   - actorService.onEntityStateChange(ruleChain.getTenantId(), referencingRuleChainId, ComponentLifecycleEvent.UPDATED));
  258 + tbClusterService.onEntityStateChange(ruleChain.getTenantId(), referencingRuleChainId, ComponentLifecycleEvent.UPDATED));
259 259
260   - actorService.onEntityStateChange(ruleChain.getTenantId(), ruleChain.getId(), ComponentLifecycleEvent.DELETED);
  260 + tbClusterService.onEntityStateChange(ruleChain.getTenantId(), ruleChain.getId(), ComponentLifecycleEvent.DELETED);
261 261
262 262 logEntityAction(ruleChainId, ruleChain,
263 263 null,
... ...
... ... @@ -68,7 +68,6 @@ import org.thingsboard.server.common.data.kv.LongDataEntry;
68 68 import org.thingsboard.server.common.data.kv.ReadTsKvQuery;
69 69 import org.thingsboard.server.common.data.kv.StringDataEntry;
70 70 import org.thingsboard.server.common.data.kv.TsKvEntry;
71   -import org.thingsboard.server.common.msg.cluster.SendToClusterMsg;
72 71 import org.thingsboard.server.common.transport.adaptor.JsonConverter;
73 72 import org.thingsboard.server.dao.timeseries.TimeseriesService;
74 73 import org.thingsboard.server.service.security.AccessValidator;
... ... @@ -362,9 +361,8 @@ public class TelemetryController extends BaseController {
362 361 DeviceId deviceId = new DeviceId(entityId.getId());
363 362 Set<AttributeKey> keysToNotify = new HashSet<>();
364 363 keys.forEach(key -> keysToNotify.add(new AttributeKey(scope, key)));
365   - DeviceAttributesEventNotificationMsg notificationMsg = DeviceAttributesEventNotificationMsg.onDelete(
366   - user.getTenantId(), deviceId, keysToNotify);
367   - actorService.onMsg(new SendToClusterMsg(deviceId, notificationMsg));
  364 + tbClusterService.onToCoreMsg(DeviceAttributesEventNotificationMsg.onDelete(
  365 + user.getTenantId(), deviceId, keysToNotify));
368 366 }
369 367 result.setResult(new ResponseEntity<>(HttpStatus.OK));
370 368 }
... ... @@ -398,9 +396,8 @@ public class TelemetryController extends BaseController {
398 396 logAttributesUpdated(user, entityId, scope, attributes, null);
399 397 if (entityId.getEntityType() == EntityType.DEVICE) {
400 398 DeviceId deviceId = new DeviceId(entityId.getId());
401   - DeviceAttributesEventNotificationMsg notificationMsg = DeviceAttributesEventNotificationMsg.onUpdate(
402   - user.getTenantId(), deviceId, scope, attributes);
403   - actorService.onMsg(new SendToClusterMsg(deviceId, notificationMsg));
  399 + tbClusterService.onToCoreMsg(DeviceAttributesEventNotificationMsg.onUpdate(
  400 + user.getTenantId(), deviceId, scope, attributes));
404 401 }
405 402 result.setResult(new ResponseEntity(HttpStatus.OK));
406 403 }
... ...
... ... @@ -95,7 +95,7 @@ public class TenantController extends BaseController {
95 95 checkTenantId(tenantId, Operation.DELETE);
96 96 tenantService.deleteTenant(tenantId);
97 97
98   - actorService.onEntityStateChange(tenantId, tenantId, ComponentLifecycleEvent.DELETED);
  98 + tbClusterService.onEntityStateChange(tenantId, tenantId, ComponentLifecycleEvent.DELETED);
99 99 } catch (Exception e) {
100 100 throw handleException(e);
101 101 }
... ...
... ... @@ -16,8 +16,6 @@
16 16 package org.thingsboard.server.service.encoding;
17 17
18 18 import org.thingsboard.server.common.msg.TbActorMsg;
19   -import org.thingsboard.server.common.msg.cluster.ServerAddress;
20   -import org.thingsboard.server.gen.cluster.ClusterAPIProtos;
21 19
22 20 import java.util.Optional;
23 21
... ... @@ -27,8 +25,5 @@ public interface DataDecodingEncodingService {
27 25
28 26 byte[] encode(TbActorMsg msq);
29 27
30   - ClusterAPIProtos.ClusterMessage convertToProtoDataMessage(ServerAddress serverAddress,
31   - TbActorMsg msg);
32   -
33 28 }
34 29
... ...
... ... @@ -15,25 +15,19 @@
15 15 */
16 16 package org.thingsboard.server.service.encoding;
17 17
18   -import com.google.protobuf.ByteString;
19 18 import lombok.extern.slf4j.Slf4j;
20 19 import org.nustaq.serialization.FSTConfiguration;
21 20 import org.springframework.stereotype.Service;
22 21 import org.thingsboard.server.common.msg.TbActorMsg;
23   -import org.thingsboard.server.common.msg.cluster.ServerAddress;
24   -import org.thingsboard.server.gen.cluster.ClusterAPIProtos;
25 22
26 23 import java.util.Optional;
27 24
28   -import static org.thingsboard.server.gen.cluster.ClusterAPIProtos.MessageType.CLUSTER_ACTOR_MESSAGE;
29   -
30   -
31 25 @Slf4j
32 26 @Service
33 27 public class ProtoWithFSTService implements DataDecodingEncodingService {
34 28
35   -
36 29 private final FSTConfiguration config = FSTConfiguration.createDefaultConfiguration();
  30 +
37 31 @Override
38 32 public Optional<TbActorMsg> decode(byte[] byteArray) {
39 33 try {
... ... @@ -42,7 +36,7 @@ public class ProtoWithFSTService implements DataDecodingEncodingService {
42 36
43 37 } catch (IllegalArgumentException e) {
44 38 log.error("Error during deserialization message, [{}]", e.getMessage());
45   - return Optional.empty();
  39 + return Optional.empty();
46 40 }
47 41 }
48 42
... ... @@ -51,18 +45,4 @@ public class ProtoWithFSTService implements DataDecodingEncodingService {
51 45 return config.asByteArray(msq);
52 46 }
53 47
54   - @Override
55   - public ClusterAPIProtos.ClusterMessage convertToProtoDataMessage(ServerAddress serverAddress,
56   - TbActorMsg msg) {
57   - return ClusterAPIProtos.ClusterMessage
58   - .newBuilder()
59   - .setServerAddress(ClusterAPIProtos.ServerAddress
60   - .newBuilder()
61   - .setHost(serverAddress.getHost())
62   - .setPort(serverAddress.getPort())
63   - .build())
64   - .setMessageType(CLUSTER_ACTOR_MESSAGE)
65   - .setPayload(ByteString.copyFrom(encode(msg))).build();
66   -
67   - }
68 48 }
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.service.queue;
  17 +
  18 +import com.google.protobuf.ByteString;
  19 +import lombok.extern.slf4j.Slf4j;
  20 +import org.springframework.stereotype.Service;
  21 +import org.thingsboard.rule.engine.api.msg.ToDeviceActorNotificationMsg;
  22 +import org.thingsboard.server.common.data.EntityType;
  23 +import org.thingsboard.server.common.data.id.EntityId;
  24 +import org.thingsboard.server.common.data.id.TenantId;
  25 +import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
  26 +import org.thingsboard.server.common.msg.TbMsg;
  27 +import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg;
  28 +import org.thingsboard.server.common.msg.queue.ServiceType;
  29 +import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
  30 +import org.thingsboard.server.gen.transport.TransportProtos.*;
  31 +import org.thingsboard.server.queue.TbQueueProducer;
  32 +import org.thingsboard.server.queue.common.TbProtoQueueMsg;
  33 +import org.thingsboard.server.queue.discovery.PartitionService;
  34 +import org.thingsboard.server.queue.provider.TbQueueProducerProvider;
  35 +import org.thingsboard.server.service.encoding.DataDecodingEncodingService;
  36 +import org.thingsboard.server.service.rpc.FromDeviceRpcResponse;
  37 +
  38 +import java.util.HashSet;
  39 +import java.util.Set;
  40 +
  41 +@Service
  42 +@Slf4j
  43 +public class DefaultTbClusterService implements TbClusterService {
  44 +
  45 + protected TbQueueProducerProvider producerProvider;
  46 + private final PartitionService partitionService;
  47 + private final DataDecodingEncodingService encodingService;
  48 +
  49 + public DefaultTbClusterService(TbQueueProducerProvider producerProvider, PartitionService partitionService, DataDecodingEncodingService encodingService) {
  50 + this.producerProvider = producerProvider;
  51 + this.partitionService = partitionService;
  52 + this.encodingService = encodingService;
  53 + }
  54 +
  55 + @Override
  56 + public void onToRuleEngineMsg(TenantId tenantId, EntityId entityId, TbMsg tbMsg) {
  57 + TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_RULE_ENGINE, tenantId, entityId);
  58 + ToRuleEngineMsg msg = ToRuleEngineMsg.newBuilder()
  59 + .setTenantIdMSB(tenantId.getId().getMostSignificantBits())
  60 + .setTenantIdLSB(tenantId.getId().getLeastSignificantBits())
  61 + .setTbMsg(TbMsg.toByteString(tbMsg)).build();
  62 + producerProvider.getRuleEngineMsgProducer().send(tpi, new TbProtoQueueMsg<>(tbMsg.getId(), msg), null);
  63 + }
  64 +
  65 + @Override
  66 + public void onToCoreMsg(ToDeviceActorNotificationMsg msg) {
  67 + TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_CORE, msg.getTenantId(), msg.getDeviceId());
  68 + byte[] msgBytes = encodingService.encode(msg);
  69 + ToCoreMsg toCoreMsg = ToCoreMsg.newBuilder().setToDeviceActorNotificationMsg(ByteString.copyFrom(msgBytes)).build();
  70 + producerProvider.getTbCoreMsgProducer().send(tpi, new TbProtoQueueMsg<>(msg.getDeviceId().getId(), toCoreMsg), null);
  71 + }
  72 +
  73 + @Override
  74 + public void onToCoreMsg(String serviceId, FromDeviceRpcResponse response) {
  75 + TopicPartitionInfo tpi = partitionService.getNotificationsTopic(ServiceType.TB_CORE, serviceId);
  76 + FromDeviceRPCResponseProto.Builder builder = FromDeviceRPCResponseProto.newBuilder()
  77 + .setRequestIdMSB(response.getId().getMostSignificantBits())
  78 + .setRequestIdLSB(response.getId().getLeastSignificantBits())
  79 + .setError(response.getError().isPresent() ? response.getError().get().ordinal() : -1);
  80 + response.getResponse().ifPresent(builder::setResponse);
  81 + ToCoreNotificationMsg msg = ToCoreNotificationMsg.newBuilder().setFromDeviceRpcResponse(builder).build();
  82 + producerProvider.getTbCoreNotificationsMsgProducer().send(tpi, new TbProtoQueueMsg<>(response.getId(), msg), null);
  83 + }
  84 +
  85 + @Override
  86 + public void onToRuleEngineMsg(String serviceId, FromDeviceRpcResponse response) {
  87 + TopicPartitionInfo tpi = partitionService.getNotificationsTopic(ServiceType.TB_RULE_ENGINE, serviceId);
  88 + FromDeviceRPCResponseProto.Builder builder = FromDeviceRPCResponseProto.newBuilder()
  89 + .setRequestIdMSB(response.getId().getMostSignificantBits())
  90 + .setRequestIdLSB(response.getId().getLeastSignificantBits())
  91 + .setError(response.getError().isPresent() ? response.getError().get().ordinal() : -1);
  92 + response.getResponse().ifPresent(builder::setResponse);
  93 + ToRuleEngineNotificationMsg msg = ToRuleEngineNotificationMsg.newBuilder().setFromDeviceRpcResponse(builder).build();
  94 + producerProvider.getRuleEngineNotificationsMsgProducer().send(tpi, new TbProtoQueueMsg<>(response.getId(), msg), null);
  95 +
  96 + }
  97 +
  98 + @Override
  99 + public void onEntityStateChange(TenantId tenantId, EntityId entityId, ComponentLifecycleEvent state) {
  100 + log.trace("[{}] Processing {} state change event: {}", tenantId, entityId.getEntityType(), state);
  101 + broadcast(new ComponentLifecycleMsg(tenantId, entityId, state));
  102 + }
  103 +
  104 + private void broadcast(ComponentLifecycleMsg msg) {
  105 + byte[] msgBytes = encodingService.encode(msg);
  106 + TbQueueProducer<TbProtoQueueMsg<ToRuleEngineNotificationMsg>> toRuleEngineProducer = producerProvider.getRuleEngineNotificationsMsgProducer();
  107 + Set<String> tbRuleEngineServices = new HashSet<>(partitionService.getAllServiceIds(ServiceType.TB_RULE_ENGINE));
  108 + if (msg.getEntityId().getEntityType().equals(EntityType.TENANT)) {
  109 + TbQueueProducer<TbProtoQueueMsg<ToCoreNotificationMsg>> toCoreProducer = producerProvider.getTbCoreNotificationsMsgProducer();
  110 + Set<String> tbCoreServices = partitionService.getAllServiceIds(ServiceType.TB_CORE);
  111 + for (String serviceId : tbCoreServices) {
  112 + TopicPartitionInfo tpi = partitionService.getNotificationsTopic(ServiceType.TB_CORE, serviceId);
  113 + ToCoreNotificationMsg toCoreMsg = ToCoreNotificationMsg.newBuilder().setComponentLifecycleMsg(ByteString.copyFrom(msgBytes)).build();
  114 + toCoreProducer.send(tpi, new TbProtoQueueMsg<>(msg.getEntityId().getId(), toCoreMsg), null);
  115 + }
  116 + // No need to push notifications twice
  117 + tbRuleEngineServices.removeAll(tbCoreServices);
  118 + }
  119 + for (String serviceId : tbRuleEngineServices) {
  120 + TopicPartitionInfo tpi = partitionService.getNotificationsTopic(ServiceType.TB_RULE_ENGINE, serviceId);
  121 + ToRuleEngineNotificationMsg toRuleEngineMsg = ToRuleEngineNotificationMsg.newBuilder().setComponentLifecycleMsg(ByteString.copyFrom(msgBytes)).build();
  122 + toRuleEngineProducer.send(tpi, new TbProtoQueueMsg<>(msg.getEntityId().getId(), toRuleEngineMsg), null);
  123 + }
  124 + }
  125 +}
... ...
... ... @@ -5,7 +5,7 @@
5 5 * you may not use this file except in compliance with the License.
6 6 * You may obtain a copy of the License at
7 7 *
8   - * http://www.apache.org/licenses/LICENSE-2.0
  8 + * http://www.apache.org/licenses/LICENSE-2.0
9 9 *
10 10 * Unless required by applicable law or agreed to in writing, software
11 11 * distributed under the License is distributed on an "AS IS" BASIS,
... ... @@ -24,26 +24,32 @@ import org.springframework.context.event.EventListener;
24 24 import org.springframework.scheduling.annotation.Scheduled;
25 25 import org.springframework.stereotype.Service;
26 26 import org.thingsboard.common.util.ThingsBoardThreadFactory;
  27 +import org.thingsboard.rule.engine.api.RpcError;
  28 +import org.thingsboard.server.actors.ActorSystemContext;
27 29 import org.thingsboard.server.common.data.id.TenantId;
  30 +import org.thingsboard.server.common.msg.TbActorMsg;
  31 +import org.thingsboard.server.common.msg.queue.ServiceType;
28 32 import org.thingsboard.server.common.msg.queue.TbMsgCallback;
  33 +import org.thingsboard.server.gen.transport.TransportProtos.*;
  34 +import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
  35 +import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg;
29 36 import org.thingsboard.server.queue.TbQueueConsumer;
30   -import org.thingsboard.server.actors.ActorSystemContext;
31 37 import org.thingsboard.server.queue.common.TbProtoQueueMsg;
32 38 import org.thingsboard.server.queue.discovery.PartitionChangeEvent;
33   -import org.thingsboard.server.queue.discovery.ServiceType;
34   -import org.thingsboard.server.gen.transport.TransportProtos;
35   -import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
36   -import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg;
37 39 import org.thingsboard.server.queue.provider.TbCoreQueueProvider;
  40 +import org.thingsboard.server.service.encoding.DataDecodingEncodingService;
  41 +import org.thingsboard.server.service.rpc.FromDeviceRpcResponse;
  42 +import org.thingsboard.server.service.rpc.TbCoreDeviceRpcService;
38 43 import org.thingsboard.server.service.state.DeviceStateService;
39   -import org.thingsboard.server.service.subscription.LocalSubscriptionService;
40 44 import org.thingsboard.server.service.subscription.SubscriptionManagerService;
  45 +import org.thingsboard.server.service.subscription.TbLocalSubscriptionService;
41 46 import org.thingsboard.server.service.subscription.TbSubscriptionUtils;
42 47 import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWrapper;
43 48
44 49 import javax.annotation.PostConstruct;
45 50 import javax.annotation.PreDestroy;
46 51 import java.util.List;
  52 +import java.util.Optional;
47 53 import java.util.UUID;
48 54 import java.util.concurrent.ConcurrentHashMap;
49 55 import java.util.concurrent.ConcurrentMap;
... ... @@ -68,64 +74,85 @@ public class DefaultTbCoreConsumerService implements TbCoreConsumerService {
68 74
69 75 private final ActorSystemContext actorContext;
70 76 private final DeviceStateService stateService;
71   - private final LocalSubscriptionService localSubscriptionService;
  77 + private final TbLocalSubscriptionService localSubscriptionService;
72 78 private final SubscriptionManagerService subscriptionManagerService;
73   - private final TbQueueConsumer<TbProtoQueueMsg<ToCoreMsg>> consumer;
  79 + private final DataDecodingEncodingService encodingService;
  80 + private final TbQueueConsumer<TbProtoQueueMsg<ToCoreMsg>> mainConsumer;
  81 + private final TbQueueConsumer<TbProtoQueueMsg<ToCoreNotificationMsg>> nfConsumer;
  82 + private final TbCoreDeviceRpcService tbCoreDeviceRpcService;
74 83 private final TbCoreConsumerStats stats = new TbCoreConsumerStats();
75 84 private volatile ExecutorService mainConsumerExecutor;
  85 + private volatile ExecutorService notificationsConsumerExecutor;
76 86 private volatile boolean stopped = false;
77 87
78   - public DefaultTbCoreConsumerService(TbCoreQueueProvider tbCoreQueueProvider, ActorSystemContext actorContext, DeviceStateService stateService, LocalSubscriptionService localSubscriptionService, SubscriptionManagerService subscriptionManagerService) {
79   - this.consumer = tbCoreQueueProvider.getToCoreMsgConsumer();
  88 + public DefaultTbCoreConsumerService(TbCoreQueueProvider tbCoreQueueProvider, ActorSystemContext actorContext,
  89 + DeviceStateService stateService, TbLocalSubscriptionService localSubscriptionService,
  90 + SubscriptionManagerService subscriptionManagerService, DataDecodingEncodingService encodingService,
  91 + TbCoreDeviceRpcService tbCoreDeviceRpcService) {
  92 + this.mainConsumer = tbCoreQueueProvider.getToCoreMsgConsumer();
  93 + this.nfConsumer = tbCoreQueueProvider.getToCoreNotificationsMsgConsumer();
80 94 this.actorContext = actorContext;
81 95 this.stateService = stateService;
82 96 this.localSubscriptionService = localSubscriptionService;
83 97 this.subscriptionManagerService = subscriptionManagerService;
  98 + this.encodingService = encodingService;
  99 + this.tbCoreDeviceRpcService = tbCoreDeviceRpcService;
84 100 }
85 101
86 102 @PostConstruct
87 103 public void init() {
88 104 this.mainConsumerExecutor = Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName("tb-core-consumer"));
  105 + this.notificationsConsumerExecutor = Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName("tb-core-notifications-consumer"));
89 106 }
90 107
91 108 @Override
92 109 public void onApplicationEvent(PartitionChangeEvent partitionChangeEvent) {
93 110 if (partitionChangeEvent.getServiceKey().getServiceType() == ServiceType.TB_CORE) {
94 111 log.info("Subscribing to partitions: {}", partitionChangeEvent.getPartitions());
95   - this.consumer.subscribe(partitionChangeEvent.getPartitions());
  112 + this.mainConsumer.subscribe(partitionChangeEvent.getPartitions());
96 113 }
97 114 }
98 115
99 116 @EventListener(ApplicationReadyEvent.class)
100 117 public void onApplicationEvent(ApplicationReadyEvent event) {
  118 + log.info("Subscribing to notifications: {}", mainConsumer.getTopic());
  119 + this.nfConsumer.subscribe();
  120 + launchNotificationsConsumer();
  121 + launchMainConsumer();
  122 + }
  123 +
  124 + private void launchMainConsumer() {
101 125 mainConsumerExecutor.execute(() -> {
102 126 while (!stopped) {
103 127 try {
104   - List<TbProtoQueueMsg<ToCoreMsg>> msgs = consumer.poll(pollDuration);
  128 + List<TbProtoQueueMsg<ToCoreMsg>> msgs = mainConsumer.poll(pollDuration);
105 129 if (msgs.isEmpty()) {
106 130 continue;
107 131 }
108 132 ConcurrentMap<UUID, TbProtoQueueMsg<ToCoreMsg>> pendingMap = msgs.stream().collect(
109 133 Collectors.toConcurrentMap(s -> UUID.randomUUID(), Function.identity()));
110   - ConcurrentMap<UUID, TbProtoQueueMsg<ToCoreMsg>> successMap = new ConcurrentHashMap<>();
111 134 ConcurrentMap<UUID, TbProtoQueueMsg<ToCoreMsg>> failedMap = new ConcurrentHashMap<>();
112 135 CountDownLatch processingTimeoutLatch = new CountDownLatch(1);
113 136 pendingMap.forEach((id, msg) -> {
114   - TbMsgCallback callback = new MsgPackCallback<>(id, processingTimeoutLatch, pendingMap, successMap, failedMap);
  137 + TbMsgCallback callback = new MsgPackCallback<>(id, processingTimeoutLatch, pendingMap, new ConcurrentHashMap<>(), failedMap);
115 138 try {
116 139 ToCoreMsg toCoreMsg = msg.getValue();
117   - if (toCoreMsg.hasToDeviceActorMsg()) {
  140 + if (toCoreMsg.hasToSubscriptionMgrMsg()) {
  141 + log.trace("[{}] Forwarding message to subscription manager service {}", id, toCoreMsg.getToSubscriptionMgrMsg());
  142 + forwardToSubMgrService(toCoreMsg.getToSubscriptionMgrMsg(), callback);
  143 + } else if (toCoreMsg.hasToDeviceActorMsg()) {
118 144 log.trace("[{}] Forwarding message to device actor {}", id, toCoreMsg.getToDeviceActorMsg());
119 145 forwardToDeviceActor(toCoreMsg.getToDeviceActorMsg(), callback);
120 146 } else if (toCoreMsg.hasDeviceStateServiceMsg()) {
121 147 log.trace("[{}] Forwarding message to state service {}", id, toCoreMsg.getDeviceStateServiceMsg());
122 148 forwardToStateService(toCoreMsg.getDeviceStateServiceMsg(), callback);
123   - } else if (toCoreMsg.hasToSubscriptionMgrMsg()) {
124   - log.trace("[{}] Forwarding message to subscription manager service {}", id, toCoreMsg.getToSubscriptionMgrMsg());
125   - forwardToSubMgrService(toCoreMsg.getToSubscriptionMgrMsg(), callback);
126   - } else if (toCoreMsg.hasToLocalSubscriptionServiceMsg()) {
127   - log.trace("[{}] Forwarding message to local subscription service {}", id, toCoreMsg.getToLocalSubscriptionServiceMsg());
128   - forwardToLocalSubMgrService(toCoreMsg.getToLocalSubscriptionServiceMsg(), callback);
  149 + } else if (toCoreMsg.getToDeviceActorNotificationMsg() != null && !toCoreMsg.getToDeviceActorNotificationMsg().isEmpty()) {
  150 + Optional<TbActorMsg> actorMsg = encodingService.decode(toCoreMsg.getToDeviceActorNotificationMsg().toByteArray());
  151 + if (actorMsg.isPresent()) {
  152 + log.trace("[{}] Forwarding message to App Actor {}", id, actorMsg.get());
  153 + actorContext.getAppActor().tell(actorMsg.get(), ActorRef.noSender());
  154 + }
  155 + callback.onSuccess();
129 156 }
130 157 } catch (Throwable e) {
131 158 log.warn("[{}] Failed to process message: {}", id, msg, e);
... ... @@ -136,7 +163,7 @@ public class DefaultTbCoreConsumerService implements TbCoreConsumerService {
136 163 pendingMap.forEach((id, msg) -> log.warn("[{}] Timeout to process message: {}", id, msg.getValue()));
137 164 failedMap.forEach((id, msg) -> log.warn("[{}] Failed to process message: {}", id, msg.getValue()));
138 165 }
139   - consumer.commit();
  166 + mainConsumer.commit();
140 167 } catch (Exception e) {
141 168 log.warn("Failed to obtain messages from queue.", e);
142 169 try {
... ... @@ -150,6 +177,67 @@ public class DefaultTbCoreConsumerService implements TbCoreConsumerService {
150 177 });
151 178 }
152 179
  180 + private void launchNotificationsConsumer() {
  181 + notificationsConsumerExecutor.execute(() -> {
  182 + while (!stopped) {
  183 + try {
  184 + List<TbProtoQueueMsg<ToCoreNotificationMsg>> msgs = nfConsumer.poll(pollDuration);
  185 + if (msgs.isEmpty()) {
  186 + continue;
  187 + }
  188 + ConcurrentMap<UUID, TbProtoQueueMsg<ToCoreNotificationMsg>> pendingMap = msgs.stream().collect(
  189 + Collectors.toConcurrentMap(s -> UUID.randomUUID(), Function.identity()));
  190 + ConcurrentMap<UUID, TbProtoQueueMsg<ToCoreNotificationMsg>> failedMap = new ConcurrentHashMap<>();
  191 + CountDownLatch processingTimeoutLatch = new CountDownLatch(1);
  192 + pendingMap.forEach((id, msg) -> {
  193 + TbMsgCallback callback = new MsgPackCallback<>(id, processingTimeoutLatch, pendingMap, new ConcurrentHashMap<>(), failedMap);
  194 + try {
  195 + ToCoreNotificationMsg toCoreMsg = msg.getValue();
  196 + if (toCoreMsg.hasToLocalSubscriptionServiceMsg()) {
  197 + log.trace("[{}] Forwarding message to local subscription service {}", id, toCoreMsg.getToLocalSubscriptionServiceMsg());
  198 + forwardToLocalSubMgrService(toCoreMsg.getToLocalSubscriptionServiceMsg(), callback);
  199 + } else if (toCoreMsg.hasFromDeviceRpcResponse()) {
  200 + log.trace("[{}] Forwarding message to RPC service {}", id, toCoreMsg.getFromDeviceRpcResponse());
  201 + forwardToCoreRpcService(toCoreMsg.getFromDeviceRpcResponse(), callback);
  202 + } else if (toCoreMsg.getComponentLifecycleMsg() != null && !toCoreMsg.getComponentLifecycleMsg().isEmpty()) {
  203 + Optional<TbActorMsg> actorMsg = encodingService.decode(toCoreMsg.getComponentLifecycleMsg().toByteArray());
  204 + if (actorMsg.isPresent()) {
  205 + log.trace("[{}] Forwarding message to App Actor {}", id, actorMsg.get());
  206 + actorContext.getAppActor().tell(actorMsg.get(), ActorRef.noSender());
  207 + }
  208 + callback.onSuccess();
  209 + }
  210 + } catch (Throwable e) {
  211 + log.warn("[{}] Failed to process notification: {}", id, msg, e);
  212 + callback.onFailure(e);
  213 + }
  214 + });
  215 + if (!processingTimeoutLatch.await(packProcessingTimeout, TimeUnit.MILLISECONDS)) {
  216 + pendingMap.forEach((id, msg) -> log.warn("[{}] Timeout to process notification: {}", id, msg.getValue()));
  217 + failedMap.forEach((id, msg) -> log.warn("[{}] Failed to process notification: {}", id, msg.getValue()));
  218 + }
  219 + nfConsumer.commit();
  220 + } catch (Exception e) {
  221 + log.warn("Failed to obtain notifications from queue.", e);
  222 + try {
  223 + Thread.sleep(pollDuration);
  224 + } catch (InterruptedException e2) {
  225 + log.trace("Failed to wait until the server has capacity to handle new notifications", e2);
  226 + }
  227 + }
  228 + }
  229 + log.info("Tb Core Notifications Consumer stopped.");
  230 + });
  231 + }
  232 +
  233 + private void forwardToCoreRpcService(FromDeviceRPCResponseProto proto, TbMsgCallback callback) {
  234 + RpcError error = proto.getError() > 0 ? RpcError.values()[proto.getError()] : null;
  235 + FromDeviceRpcResponse response = new FromDeviceRpcResponse(new UUID(proto.getRequestIdMSB(), proto.getRequestIdLSB())
  236 + , proto.getResponse(), error);
  237 + tbCoreDeviceRpcService.processRpcResponseFromRuleEngine(response);
  238 + callback.onSuccess();
  239 + }
  240 +
153 241 @Scheduled(fixedDelayString = "${queue.core.stats.print_interval_ms}")
154 242 public void printStats() {
155 243 if (statsEnabled) {
... ... @@ -160,15 +248,21 @@ public class DefaultTbCoreConsumerService implements TbCoreConsumerService {
160 248 @PreDestroy
161 249 public void destroy() {
162 250 stopped = true;
163   - if (consumer != null) {
164   - consumer.unsubscribe();
  251 + if (mainConsumer != null) {
  252 + mainConsumer.unsubscribe();
  253 + }
  254 + if (nfConsumer != null) {
  255 + nfConsumer.unsubscribe();
165 256 }
166 257 if (mainConsumerExecutor != null) {
167 258 mainConsumerExecutor.shutdownNow();
168 259 }
  260 + if (notificationsConsumerExecutor != null) {
  261 + notificationsConsumerExecutor.shutdownNow();
  262 + }
169 263 }
170 264
171   - private void forwardToLocalSubMgrService(TransportProtos.LocalSubscriptionServiceMsgProto msg, TbMsgCallback callback) {
  265 + private void forwardToLocalSubMgrService(LocalSubscriptionServiceMsgProto msg, TbMsgCallback callback) {
172 266 if (msg.hasSubUpdate()) {
173 267 localSubscriptionService.onSubscriptionUpdate(msg.getSubUpdate().getSessionId(), TbSubscriptionUtils.fromProto(msg.getSubUpdate()), callback);
174 268 } else {
... ... @@ -176,22 +270,22 @@ public class DefaultTbCoreConsumerService implements TbCoreConsumerService {
176 270 }
177 271 }
178 272
179   - private void forwardToSubMgrService(TransportProtos.SubscriptionMgrMsgProto msg, TbMsgCallback callback) {
  273 + private void forwardToSubMgrService(SubscriptionMgrMsgProto msg, TbMsgCallback callback) {
180 274 if (msg.hasAttributeSub()) {
181 275 subscriptionManagerService.addSubscription(TbSubscriptionUtils.fromProto(msg.getAttributeSub()), callback);
182 276 } else if (msg.hasTelemetrySub()) {
183 277 subscriptionManagerService.addSubscription(TbSubscriptionUtils.fromProto(msg.getTelemetrySub()), callback);
184 278 } else if (msg.hasSubClose()) {
185   - TransportProtos.TbSubscriptionCloseProto closeProto = msg.getSubClose();
  279 + TbSubscriptionCloseProto closeProto = msg.getSubClose();
186 280 subscriptionManagerService.cancelSubscription(closeProto.getSessionId(), closeProto.getSubscriptionId(), callback);
187 281 } else if (msg.hasTsUpdate()) {
188   - TransportProtos.TbTimeSeriesUpdateProto proto = msg.getTsUpdate();
  282 + TbTimeSeriesUpdateProto proto = msg.getTsUpdate();
189 283 subscriptionManagerService.onTimeSeriesUpdate(
190 284 new TenantId(new UUID(proto.getTenantIdMSB(), proto.getTenantIdLSB())),
191 285 TbSubscriptionUtils.toEntityId(proto.getEntityType(), proto.getEntityIdMSB(), proto.getEntityIdLSB()),
192 286 TbSubscriptionUtils.toTsKvEntityList(proto.getDataList()), callback);
193 287 } else if (msg.hasAttrUpdate()) {
194   - TransportProtos.TbAttributeUpdateProto proto = msg.getAttrUpdate();
  288 + TbAttributeUpdateProto proto = msg.getAttrUpdate();
195 289 subscriptionManagerService.onAttributesUpdate(
196 290 new TenantId(new UUID(proto.getTenantIdMSB(), proto.getTenantIdLSB())),
197 291 TbSubscriptionUtils.toEntityId(proto.getEntityType(), proto.getEntityIdMSB(), proto.getEntityIdLSB()),
... ... @@ -201,7 +295,7 @@ public class DefaultTbCoreConsumerService implements TbCoreConsumerService {
201 295 }
202 296 }
203 297
204   - private void forwardToStateService(TransportProtos.DeviceStateServiceMsgProto deviceStateServiceMsg, TbMsgCallback callback) {
  298 + private void forwardToStateService(DeviceStateServiceMsgProto deviceStateServiceMsg, TbMsgCallback callback) {
205 299 if (statsEnabled) {
206 300 stats.log(deviceStateServiceMsg);
207 301 }
... ...
... ... @@ -5,7 +5,7 @@
5 5 * you may not use this file except in compliance with the License.
6 6 * You may obtain a copy of the License at
7 7 *
8   - * http://www.apache.org/licenses/LICENSE-2.0
  8 + * http://www.apache.org/licenses/LICENSE-2.0
9 9 *
10 10 * Unless required by applicable law or agreed to in writing, software
11 11 * distributed under the License is distributed on an "AS IS" BASIS,
... ... @@ -26,16 +26,19 @@ import org.springframework.scheduling.annotation.Scheduled;
26 26 import org.springframework.stereotype.Service;
27 27 import org.thingsboard.common.util.ThingsBoardThreadFactory;
28 28 import org.thingsboard.server.common.data.id.TenantId;
  29 +import org.thingsboard.server.common.msg.TbActorMsg;
29 30 import org.thingsboard.server.common.msg.TbMsg;
30 31 import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg;
31 32 import org.thingsboard.server.common.msg.queue.TbMsgCallback;
  33 +import org.thingsboard.server.gen.transport.TransportProtos;
32 34 import org.thingsboard.server.queue.TbQueueConsumer;
33 35 import org.thingsboard.server.actors.ActorSystemContext;
34 36 import org.thingsboard.server.queue.common.TbProtoQueueMsg;
35 37 import org.thingsboard.server.queue.discovery.PartitionChangeEvent;
36   -import org.thingsboard.server.queue.discovery.ServiceType;
37   -import org.thingsboard.server.gen.transport.TransportProtos;
  38 +import org.thingsboard.server.common.msg.queue.ServiceType;
  39 +import org.thingsboard.server.gen.transport.TransportProtos.*;
38 40 import org.thingsboard.server.queue.provider.TbRuleEngineQueueProvider;
  41 +import org.thingsboard.server.service.encoding.DataDecodingEncodingService;
39 42 import org.thingsboard.server.service.queue.processing.TbRuleEngineProcessingDecision;
40 43 import org.thingsboard.server.service.queue.processing.TbRuleEngineProcessingResult;
41 44 import org.thingsboard.server.service.queue.processing.TbRuleEngineProcessingStrategy;
... ... @@ -44,6 +47,7 @@ import org.thingsboard.server.service.queue.processing.TbRuleEngineProcessingStr
44 47 import javax.annotation.PostConstruct;
45 48 import javax.annotation.PreDestroy;
46 49 import java.util.List;
  50 +import java.util.Optional;
47 51 import java.util.UUID;
48 52 import java.util.concurrent.ConcurrentHashMap;
49 53 import java.util.concurrent.ConcurrentMap;
... ... @@ -67,21 +71,28 @@ public class DefaultTbRuleEngineConsumerService implements TbRuleEngineConsumerS
67 71 private boolean statsEnabled;
68 72
69 73 private final ActorSystemContext actorContext;
70   - private final TbQueueConsumer<TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> consumer;
  74 + private final TbQueueConsumer<TbProtoQueueMsg<ToRuleEngineMsg>> mainConsumer;
  75 + private final TbQueueConsumer<TbProtoQueueMsg<ToRuleEngineNotificationMsg>> nfConsumer;
71 76 private final TbCoreConsumerStats stats = new TbCoreConsumerStats();
72 77 private final TbRuleEngineProcessingStrategyFactory factory;
  78 + private final DataDecodingEncodingService encodingService;
73 79 private volatile ExecutorService mainConsumerExecutor;
  80 + private volatile ExecutorService notificationsConsumerExecutor;
74 81 private volatile boolean stopped = false;
75 82
76   - public DefaultTbRuleEngineConsumerService(TbRuleEngineProcessingStrategyFactory factory, TbRuleEngineQueueProvider tbRuleEngineQueueProvider, ActorSystemContext actorContext) {
  83 + public DefaultTbRuleEngineConsumerService(TbRuleEngineProcessingStrategyFactory factory, TbRuleEngineQueueProvider tbRuleEngineQueueProvider, ActorSystemContext actorContext,
  84 + DataDecodingEncodingService encodingService) {
77 85 this.factory = factory;
78   - this.consumer = tbRuleEngineQueueProvider.getToRuleEngineMsgConsumer();
  86 + this.mainConsumer = tbRuleEngineQueueProvider.getToRuleEngineMsgConsumer();
  87 + this.nfConsumer = tbRuleEngineQueueProvider.getToRuleEngineNotificationsMsgConsumer();
79 88 this.actorContext = actorContext;
  89 + this.encodingService = encodingService;
80 90 }
81 91
82 92 @PostConstruct
83 93 public void init() {
84   - this.mainConsumerExecutor = Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName("tb-core-consumer"));
  94 + this.mainConsumerExecutor = Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName("tb-rule-engine-consumer"));
  95 + this.notificationsConsumerExecutor = Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName("tb-rule-engine-notifications-consumer"));
85 96 this.factory.newInstance();
86 97 }
87 98
... ... @@ -89,16 +100,70 @@ public class DefaultTbRuleEngineConsumerService implements TbRuleEngineConsumerS
89 100 public void onApplicationEvent(PartitionChangeEvent partitionChangeEvent) {
90 101 if (partitionChangeEvent.getServiceKey().getServiceType() == ServiceType.TB_RULE_ENGINE) {
91 102 log.info("Subscribing to partitions: {}", partitionChangeEvent.getPartitions());
92   - this.consumer.subscribe(partitionChangeEvent.getPartitions());
  103 + this.mainConsumer.subscribe(partitionChangeEvent.getPartitions());
93 104 }
94 105 }
95 106
96 107 @EventListener(ApplicationReadyEvent.class)
97 108 public void onApplicationEvent(ApplicationReadyEvent event) {
  109 + this.nfConsumer.subscribe();
  110 + launchNotificationsConsumer();
  111 + launchMainConsumer();
  112 + }
  113 +
  114 + private void launchNotificationsConsumer() {
  115 + notificationsConsumerExecutor.execute(() -> {
  116 + while (!stopped) {
  117 + try {
  118 + List<TbProtoQueueMsg<ToRuleEngineNotificationMsg>> msgs = nfConsumer.poll(pollDuration);
  119 + if (msgs.isEmpty()) {
  120 + continue;
  121 + }
  122 + ConcurrentMap<UUID, TbProtoQueueMsg<ToRuleEngineNotificationMsg>> pendingMap = msgs.stream().collect(
  123 + Collectors.toConcurrentMap(s -> UUID.randomUUID(), Function.identity()));
  124 + ConcurrentMap<UUID, TbProtoQueueMsg<ToRuleEngineNotificationMsg>> failedMap = new ConcurrentHashMap<>();
  125 + CountDownLatch processingTimeoutLatch = new CountDownLatch(1);
  126 + pendingMap.forEach((id, msg) -> {
  127 + TbMsgCallback callback = new MsgPackCallback<>(id, processingTimeoutLatch, pendingMap, new ConcurrentHashMap<>(), failedMap);
  128 + try {
  129 + ToRuleEngineNotificationMsg toRuleEngineMsg = msg.getValue();
  130 + if (toRuleEngineMsg.getComponentLifecycleMsg() != null && !toRuleEngineMsg.getComponentLifecycleMsg().isEmpty()) {
  131 + Optional<TbActorMsg> actorMsg = encodingService.decode(toRuleEngineMsg.getComponentLifecycleMsg().toByteArray());
  132 + if (actorMsg.isPresent()) {
  133 + log.trace("[{}] Forwarding message to App Actor {}", id, actorMsg.get());
  134 + actorContext.getAppActor().tell(actorMsg.get(), ActorRef.noSender());
  135 + }
  136 + callback.onSuccess();
  137 + } else {
  138 + callback.onSuccess();
  139 + }
  140 + } catch (Throwable e) {
  141 + log.warn("[{}] Failed to process message: {}", id, msg, e);
  142 + callback.onFailure(e);
  143 + }
  144 + });
  145 + if (!processingTimeoutLatch.await(packProcessingTimeout, TimeUnit.MILLISECONDS)) {
  146 + pendingMap.forEach((id, msg) -> log.warn("[{}] Timeout to process message: {}", id, msg.getValue()));
  147 + failedMap.forEach((id, msg) -> log.warn("[{}] Failed to process message: {}", id, msg.getValue()));
  148 + }
  149 + nfConsumer.commit();
  150 + } catch (Exception e) {
  151 + log.warn("Failed to process messages from queue.", e);
  152 + try {
  153 + Thread.sleep(pollDuration);
  154 + } catch (InterruptedException e2) {
  155 + log.trace("Failed to wait until the server has capacity to handle new requests", e2);
  156 + }
  157 + }
  158 + }
  159 + });
  160 + }
  161 +
  162 + private void launchMainConsumer() {
98 163 mainConsumerExecutor.execute(() -> {
99 164 while (!stopped) {
100 165 try {
101   - List<TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> msgs = consumer.poll(pollDuration);
  166 + List<TbProtoQueueMsg<ToRuleEngineMsg>> msgs = mainConsumer.poll(pollDuration);
102 167 if (msgs.isEmpty()) {
103 168 continue;
104 169 }
... ... @@ -106,7 +171,7 @@ public class DefaultTbRuleEngineConsumerService implements TbRuleEngineConsumerS
106 171 TbRuleEngineProcessingDecision decision = null;
107 172 boolean firstAttempt = true;
108 173 while (!stopped && (firstAttempt || !decision.isCommit())) {
109   - ConcurrentMap<UUID, TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> allMap;
  174 + ConcurrentMap<UUID, TbProtoQueueMsg<ToRuleEngineMsg>> allMap;
110 175 if (firstAttempt) {
111 176 allMap = msgs.stream().collect(
112 177 Collectors.toConcurrentMap(s -> UUID.randomUUID(), Function.identity()));
... ... @@ -114,14 +179,14 @@ public class DefaultTbRuleEngineConsumerService implements TbRuleEngineConsumerS
114 179 } else {
115 180 allMap = decision.getReprocessMap();
116 181 }
117   - ConcurrentMap<UUID, TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> successMap = new ConcurrentHashMap<>();
118   - ConcurrentMap<UUID, TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> failedMap = new ConcurrentHashMap<>();
  182 + ConcurrentMap<UUID, TbProtoQueueMsg<ToRuleEngineMsg>> successMap = new ConcurrentHashMap<>();
  183 + ConcurrentMap<UUID, TbProtoQueueMsg<ToRuleEngineMsg>> failedMap = new ConcurrentHashMap<>();
119 184
120 185 CountDownLatch processingTimeoutLatch = new CountDownLatch(1);
121 186 allMap.forEach((id, msg) -> {
122 187 TbMsgCallback callback = new MsgPackCallback<>(id, processingTimeoutLatch, allMap, successMap, failedMap);
123 188 try {
124   - TransportProtos.ToRuleEngineMsg toRuleEngineMsg = msg.getValue();
  189 + ToRuleEngineMsg toRuleEngineMsg = msg.getValue();
125 190 TenantId tenantId = new TenantId(new UUID(toRuleEngineMsg.getTenantIdMSB(), toRuleEngineMsg.getTenantIdLSB()));
126 191 if (toRuleEngineMsg.getTbMsg() != null && !toRuleEngineMsg.getTbMsg().isEmpty()) {
127 192 forwardToRuleEngineActor(tenantId, toRuleEngineMsg.getTbMsg(), callback);
... ... @@ -139,7 +204,7 @@ public class DefaultTbRuleEngineConsumerService implements TbRuleEngineConsumerS
139 204 }
140 205 decision = strategy.analyze(new TbRuleEngineProcessingResult(timeout, allMap, successMap, failedMap));
141 206 }
142   - consumer.commit();
  207 + mainConsumer.commit();
143 208 } catch (Exception e) {
144 209 log.warn("Failed to process messages from queue.", e);
145 210 try {
... ... @@ -171,11 +236,17 @@ public class DefaultTbRuleEngineConsumerService implements TbRuleEngineConsumerS
171 236 @PreDestroy
172 237 public void destroy() {
173 238 stopped = true;
174   - if (consumer != null) {
175   - consumer.unsubscribe();
  239 + if (mainConsumer != null) {
  240 + mainConsumer.unsubscribe();
  241 + }
  242 + if (nfConsumer != null) {
  243 + nfConsumer.unsubscribe();
176 244 }
177 245 if (mainConsumerExecutor != null) {
178 246 mainConsumerExecutor.shutdownNow();
179 247 }
  248 + if (notificationsConsumerExecutor != null) {
  249 + notificationsConsumerExecutor.shutdownNow();
  250 + }
180 251 }
181 252 }
... ...
... ... @@ -5,7 +5,7 @@
5 5 * you may not use this file except in compliance with the License.
6 6 * You may obtain a copy of the License at
7 7 *
8   - * http://www.apache.org/licenses/LICENSE-2.0
  8 + * http://www.apache.org/licenses/LICENSE-2.0
9 9 *
10 10 * Unless required by applicable law or agreed to in writing, software
11 11 * distributed under the License is distributed on an "AS IS" BASIS,
... ...
application/src/main/java/org/thingsboard/server/service/queue/TbClusterService.java renamed from application/src/main/java/org/thingsboard/server/service/rpc/DeviceRpcService.java
... ... @@ -13,29 +13,25 @@
13 13 * See the License for the specific language governing permissions and
14 14 * limitations under the License.
15 15 */
16   -package org.thingsboard.server.service.rpc;
  16 +package org.thingsboard.server.service.queue;
17 17
18   -import org.thingsboard.server.common.data.id.DeviceId;
  18 +import org.thingsboard.rule.engine.api.msg.ToDeviceActorNotificationMsg;
  19 +import org.thingsboard.server.common.data.id.EntityId;
19 20 import org.thingsboard.server.common.data.id.TenantId;
20   -import org.thingsboard.server.common.msg.cluster.ServerAddress;
21   -import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest;
  21 +import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
  22 +import org.thingsboard.server.common.msg.TbMsg;
  23 +import org.thingsboard.server.service.rpc.FromDeviceRpcResponse;
22 24
23   -import java.util.function.Consumer;
  25 +public interface TbClusterService {
24 26
25   -/**
26   - * Created by ashvayka on 16.04.18.
27   - */
28   -public interface DeviceRpcService {
29   -
30   - void processRestAPIRpcRequestToRuleEngine(ToDeviceRpcRequest request, Consumer<FromDeviceRpcResponse> responseConsumer);
  27 + void onToRuleEngineMsg(TenantId tenantId, EntityId entityId, TbMsg msg);
31 28
32   - void processResponseToServerSideRPCRequestFromRuleEngine(ServerAddress requestOriginAddress, FromDeviceRpcResponse response);
  29 + void onToCoreMsg(ToDeviceActorNotificationMsg msg);
33 30
34   - void forwardServerSideRPCRequestToDeviceActor(ToDeviceRpcRequest request, Consumer<FromDeviceRpcResponse> responseConsumer);
  31 + void onToCoreMsg(String targetServiceId, FromDeviceRpcResponse response);
35 32
36   - void processResponseToServerSideRPCRequestFromDeviceActor(FromDeviceRpcResponse response);
  33 + void onToRuleEngineMsg(String targetServiceId, FromDeviceRpcResponse response);
37 34
38   - void processResponseToServerSideRPCRequestFromRemoteServer(ServerAddress serverAddress, byte[] data);
  35 + void onEntityStateChange(TenantId tenantId, EntityId entityId, ComponentLifecycleEvent state);
39 36
40   - void sendReplyToRpcCallFromDevice(TenantId tenantId, DeviceId deviceId, int requestId, String body);
41 37 }
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
1 16 package org.thingsboard.server.service.queue.processing;
2 17
3 18 import lombok.Data;
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
1 16 package org.thingsboard.server.service.queue.processing;
2 17
3 18 import lombok.Getter;
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
1 16 package org.thingsboard.server.service.queue.processing;
2 17
3 18 public interface TbRuleEngineProcessingStrategy {
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
1 16 package org.thingsboard.server.service.queue.processing;
2 17
3 18 import lombok.extern.slf4j.Slf4j;
... ...
application/src/main/java/org/thingsboard/server/service/rpc/DefaultTbCoreDeviceRpcService.java renamed from application/src/main/java/org/thingsboard/server/service/rpc/DefaultDeviceRpcService.java
... ... @@ -15,36 +15,32 @@
15 15 */
16 16 package org.thingsboard.server.service.rpc;
17 17
  18 +import akka.actor.ActorRef;
18 19 import com.datastax.driver.core.utils.UUIDs;
19 20 import com.fasterxml.jackson.core.JsonProcessingException;
20 21 import com.fasterxml.jackson.databind.ObjectMapper;
21 22 import com.fasterxml.jackson.databind.node.ObjectNode;
22   -import com.google.protobuf.InvalidProtocolBufferException;
23 23 import lombok.extern.slf4j.Slf4j;
24 24 import org.springframework.beans.factory.annotation.Autowired;
  25 +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
25 26 import org.springframework.context.annotation.Lazy;
26 27 import org.springframework.stereotype.Service;
27 28 import org.thingsboard.common.util.ThingsBoardThreadFactory;
28 29 import org.thingsboard.rule.engine.api.RpcError;
29   -import org.thingsboard.rule.engine.api.msg.ToDeviceActorNotificationMsg;
30   -import org.thingsboard.server.actors.service.ActorService;
  30 +import org.thingsboard.server.actors.ActorSystemContext;
31 31 import org.thingsboard.server.common.data.DataConstants;
32 32 import org.thingsboard.server.common.data.Device;
33   -import org.thingsboard.server.common.data.id.DeviceId;
34   -import org.thingsboard.server.common.data.id.TenantId;
35 33 import org.thingsboard.server.common.msg.TbMsg;
36 34 import org.thingsboard.server.common.msg.TbMsgDataType;
37 35 import org.thingsboard.server.common.msg.TbMsgMetaData;
38   -import org.thingsboard.server.common.msg.cluster.SendToClusterMsg;
39   -import org.thingsboard.server.common.msg.cluster.ServerAddress;
40   -import org.thingsboard.server.common.msg.core.ToServerRpcResponseMsg;
41 36 import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest;
42   -import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg;
43 37 import org.thingsboard.server.dao.device.DeviceService;
44   -import org.thingsboard.server.gen.cluster.ClusterAPIProtos;
  38 +import org.thingsboard.server.queue.discovery.TbServiceInfoProvider;
  39 +import org.thingsboard.server.service.queue.TbClusterService;
45 40
46 41 import javax.annotation.PostConstruct;
47 42 import javax.annotation.PreDestroy;
  43 +import java.util.Optional;
48 44 import java.util.UUID;
49 45 import java.util.concurrent.ConcurrentHashMap;
50 46 import java.util.concurrent.ConcurrentMap;
... ... @@ -58,118 +54,109 @@ import java.util.function.Consumer;
58 54 */
59 55 @Service
60 56 @Slf4j
61   -public class DefaultDeviceRpcService implements DeviceRpcService {
  57 +@ConditionalOnExpression("'${service.type:null}'=='monolith' || '${service.type:null}'=='tb-core'")
  58 +public class DefaultTbCoreDeviceRpcService implements TbCoreDeviceRpcService {
62 59
63 60 private static final ObjectMapper json = new ObjectMapper();
64 61
65   - @Autowired
66   - private DeviceService deviceService;
67   -
68   - @Autowired
69   - @Lazy
70   - private ActorService actorService;
71   -
72   - private ScheduledExecutorService rpcCallBackExecutor;
  62 + private final DeviceService deviceService;
  63 + private final TbClusterService clusterService;
  64 + private final TbServiceInfoProvider serviceInfoProvider;
  65 + private final ActorSystemContext actorContext;
73 66
74 67 private final ConcurrentMap<UUID, Consumer<FromDeviceRpcResponse>> localToRuleEngineRpcRequests = new ConcurrentHashMap<>();
75   - private final ConcurrentMap<UUID, Consumer<FromDeviceRpcResponse>> localToDeviceRpcRequests = new ConcurrentHashMap<>();
  68 + private final ConcurrentMap<UUID, ToDeviceRpcRequestActorMsg> localToDeviceRpcRequests = new ConcurrentHashMap<>();
  69 +
  70 + private Optional<TbRuleEngineDeviceRpcService> tbRuleEngineRpcService;
  71 + private ScheduledExecutorService scheduler;
  72 + private String serviceId;
  73 +
  74 + public DefaultTbCoreDeviceRpcService(DeviceService deviceService, TbClusterService clusterService, TbServiceInfoProvider serviceInfoProvider,
  75 + ActorSystemContext actorContext) {
  76 + this.deviceService = deviceService;
  77 + this.clusterService = clusterService;
  78 + this.serviceInfoProvider = serviceInfoProvider;
  79 + this.actorContext = actorContext;
  80 + }
  81 +
  82 + @Autowired
  83 + public void setTbRuleEngineRpcService(Optional<TbRuleEngineDeviceRpcService> tbRuleEngineRpcService) {
  84 + this.tbRuleEngineRpcService = tbRuleEngineRpcService;
  85 + }
76 86
77 87 @PostConstruct
78 88 public void initExecutor() {
79   - rpcCallBackExecutor = Executors.newSingleThreadScheduledExecutor(ThingsBoardThreadFactory.forName("rpc-callback"));
  89 + scheduler = Executors.newSingleThreadScheduledExecutor(ThingsBoardThreadFactory.forName("tb-core-rpc-scheduler"));
  90 + serviceId = serviceInfoProvider.getServiceId();
80 91 }
81 92
82 93 @PreDestroy
83 94 public void shutdownExecutor() {
84   - if (rpcCallBackExecutor != null) {
85   - rpcCallBackExecutor.shutdownNow();
  95 + if (scheduler != null) {
  96 + scheduler.shutdownNow();
86 97 }
87 98 }
88 99
89 100 @Override
90   - public void processRestAPIRpcRequestToRuleEngine(ToDeviceRpcRequest request, Consumer<FromDeviceRpcResponse> responseConsumer) {
  101 + public void processRestApiRpcRequest(ToDeviceRpcRequest request, Consumer<FromDeviceRpcResponse> responseConsumer) {
91 102 log.trace("[{}][{}] Processing REST API call to rule engine [{}]", request.getTenantId(), request.getId(), request.getDeviceId());
92 103 UUID requestId = request.getId();
93 104 localToRuleEngineRpcRequests.put(requestId, responseConsumer);
94 105 sendRpcRequestToRuleEngine(request);
95   - scheduleTimeout(request, requestId, localToRuleEngineRpcRequests);
  106 + scheduleToRuleEngineTimeout(request, requestId);
96 107 }
97 108
98 109 @Override
99   - public void processResponseToServerSideRPCRequestFromRuleEngine(ServerAddress requestOriginAddress, FromDeviceRpcResponse response) {
100   - log.trace("[{}] Received response to server-side RPC request from rule engine: [{}]", response.getId(), requestOriginAddress);
101   - //TODO 2.5
102   - if (true) {//routingService.getCurrentServer().equals(requestOriginAddress)
103   - UUID requestId = response.getId();
104   - Consumer<FromDeviceRpcResponse> consumer = localToRuleEngineRpcRequests.remove(requestId);
105   - if (consumer != null) {
106   - consumer.accept(response);
107   - } else {
108   - log.trace("[{}] Unknown or stale rpc response received [{}]", requestId, response);
109   - }
  110 + public void processRpcResponseFromRuleEngine(FromDeviceRpcResponse response) {
  111 + log.trace("[{}] Received response to server-side RPC request from rule engine: [{}]", response.getId());
  112 + UUID requestId = response.getId();
  113 + Consumer<FromDeviceRpcResponse> consumer = localToRuleEngineRpcRequests.remove(requestId);
  114 + if (consumer != null) {
  115 + consumer.accept(response);
110 116 } else {
111   - ClusterAPIProtos.FromDeviceRPCResponseProto.Builder builder = ClusterAPIProtos.FromDeviceRPCResponseProto.newBuilder();
112   - builder.setRequestIdMSB(response.getId().getMostSignificantBits());
113   - builder.setRequestIdLSB(response.getId().getLeastSignificantBits());
114   - response.getResponse().ifPresent(builder::setResponse);
115   - if (response.getError().isPresent()) {
116   - builder.setError(response.getError().get().ordinal());
117   - } else {
118   - builder.setError(-1);
119   - }
120   - //TODO 2.5
121   -// rpcService.tell(requestOriginAddress, ClusterAPIProtos.MessageType.CLUSTER_RPC_FROM_DEVICE_RESPONSE_MESSAGE, builder.build().toByteArray());
  117 + log.trace("[{}] Unknown or stale rpc response received [{}]", requestId, response);
122 118 }
123 119 }
124 120
125 121 @Override
126   - public void forwardServerSideRPCRequestToDeviceActor(ToDeviceRpcRequest request, Consumer<FromDeviceRpcResponse> responseConsumer) {
  122 + public void forwardRpcRequestToDeviceActor(ToDeviceRpcRequestActorMsg rpcMsg) {
  123 + ToDeviceRpcRequest request = rpcMsg.getMsg();
127 124 log.trace("[{}][{}] Processing local rpc call to device actor [{}]", request.getTenantId(), request.getId(), request.getDeviceId());
128 125 UUID requestId = request.getId();
129   - localToDeviceRpcRequests.put(requestId, responseConsumer);
130   - sendRpcRequestToDevice(request);
131   - scheduleTimeout(request, requestId, localToDeviceRpcRequests);
  126 + localToDeviceRpcRequests.put(requestId, rpcMsg);
  127 + actorContext.getAppActor().tell(rpcMsg, ActorRef.noSender());
  128 + scheduleToDeviceTimeout(request, requestId);
132 129 }
133 130
134 131 @Override
135   - public void processResponseToServerSideRPCRequestFromDeviceActor(FromDeviceRpcResponse response) {
  132 + public void processRpcResponseFromDeviceActor(FromDeviceRpcResponse response) {
136 133 log.trace("[{}] Received response to server-side RPC request from device actor.", response.getId());
137 134 UUID requestId = response.getId();
138   - Consumer<FromDeviceRpcResponse> consumer = localToDeviceRpcRequests.remove(requestId);
139   - if (consumer != null) {
140   - consumer.accept(response);
  135 + ToDeviceRpcRequestActorMsg request = localToDeviceRpcRequests.remove(requestId);
  136 + if (request != null) {
  137 + sendRpcResponseToTbRuleEngine(request.getServiceId(), response);
141 138 } else {
142 139 log.trace("[{}] Unknown or stale rpc response received [{}]", requestId, response);
143 140 }
144 141 }
145 142
146   - @Override
147   - public void processResponseToServerSideRPCRequestFromRemoteServer(ServerAddress serverAddress, byte[] data) {
148   - ClusterAPIProtos.FromDeviceRPCResponseProto proto;
149   - try {
150   - proto = ClusterAPIProtos.FromDeviceRPCResponseProto.parseFrom(data);
151   - } catch (InvalidProtocolBufferException e) {
152   - throw new RuntimeException(e);
  143 + private void sendRpcResponseToTbRuleEngine(String originServiceId, FromDeviceRpcResponse response) {
  144 + if (serviceId.equals(originServiceId)) {
  145 + if (tbRuleEngineRpcService.isPresent()) {
  146 + tbRuleEngineRpcService.get().processRpcResponseFromDevice(response);
  147 + } else {
  148 + log.warn("Failed to find tbCoreRpcService for local service. Possible duplication of serviceIds.");
  149 + }
  150 + } else {
  151 + clusterService.onToRuleEngineMsg(originServiceId, response);
153 152 }
154   - RpcError error = proto.getError() > 0 ? RpcError.values()[proto.getError()] : null;
155   - FromDeviceRpcResponse response = new FromDeviceRpcResponse(new UUID(proto.getRequestIdMSB(), proto.getRequestIdLSB()), proto.getResponse(), error);
156   - //TODO 2.5
157   -// processResponseToServerSideRPCRequestFromRuleEngine(routingService.getCurrentServer(), response);
158   - }
159   -
160   - @Override
161   - public void sendReplyToRpcCallFromDevice(TenantId tenantId, DeviceId deviceId, int requestId, String body) {
162   - ToServerRpcResponseActorMsg rpcMsg = new ToServerRpcResponseActorMsg(tenantId, deviceId, new ToServerRpcResponseMsg(requestId, body));
163   - forward(deviceId, rpcMsg);
164 153 }
165 154
166 155 private void sendRpcRequestToRuleEngine(ToDeviceRpcRequest msg) {
167 156 ObjectNode entityNode = json.createObjectNode();
168 157 TbMsgMetaData metaData = new TbMsgMetaData();
169 158 metaData.putValue("requestUUID", msg.getId().toString());
170   - //TODO 2.5
171   -// metaData.putValue("originHost", routingService.getCurrentServer().getHost());
172   -// metaData.putValue("originPort", Integer.toString(routingService.getCurrentServer().getPort()));
  159 + metaData.putValue("originServiceId", serviceId);
173 160 metaData.putValue("expirationTime", Long.toString(msg.getExpirationTime()));
174 161 metaData.putValue("oneway", Boolean.toString(msg.isOneway()));
175 162
... ... @@ -186,34 +173,31 @@ public class DefaultDeviceRpcService implements DeviceRpcService {
186 173 TbMsg tbMsg = new TbMsg(UUIDs.timeBased(), DataConstants.RPC_CALL_FROM_SERVER_TO_DEVICE, msg.getDeviceId(), metaData, TbMsgDataType.JSON
187 174 , json.writeValueAsString(entityNode)
188 175 , null, null, null);
189   - actorService.onMsg(new SendToClusterMsg(msg.getDeviceId(), new QueueToRuleEngineMsg(msg.getTenantId(), tbMsg)));
  176 + clusterService.onToRuleEngineMsg(msg.getTenantId(), msg.getDeviceId(), tbMsg);
190 177 } catch (JsonProcessingException e) {
191 178 throw new RuntimeException(e);
192 179 }
193 180 }
194 181
195   - private void sendRpcRequestToDevice(ToDeviceRpcRequest msg) {
196   - //TODO 2.5
197   -// ToDeviceRpcRequestActorMsg rpcMsg = new ToDeviceRpcRequestActorMsg(routingService.getCurrentServer(), msg);
198   -// log.trace("[{}] Forwarding msg {} to device actor!", msg.getDeviceId(), msg);
199   -// forward(msg.getDeviceId(), rpcMsg);
200   - }
201   -
202   - private <T extends ToDeviceActorNotificationMsg> void forward(DeviceId deviceId, T msg) {
203   - actorService.onMsg(new SendToClusterMsg(deviceId, msg));
204   - }
205   -
206   - private void scheduleTimeout(ToDeviceRpcRequest request, UUID requestId, ConcurrentMap<UUID, Consumer<FromDeviceRpcResponse>> requestsMap) {
  182 + private void scheduleToRuleEngineTimeout(ToDeviceRpcRequest request, UUID requestId) {
207 183 long timeout = Math.max(0, request.getExpirationTime() - System.currentTimeMillis());
208   - log.trace("[{}] processing the request: [{}]", this.hashCode(), requestId);
209   - rpcCallBackExecutor.schedule(() -> {
210   - log.trace("[{}] timeout the request: [{}]", this.hashCode(), requestId);
211   - Consumer<FromDeviceRpcResponse> consumer = requestsMap.remove(requestId);
  184 + log.trace("[{}] processing to rule engine request: [{}]", this.hashCode(), requestId);
  185 + scheduler.schedule(() -> {
  186 + log.trace("[{}] timeout for to rule engine request: [{}]", this.hashCode(), requestId);
  187 + Consumer<FromDeviceRpcResponse> consumer = localToRuleEngineRpcRequests.remove(requestId);
212 188 if (consumer != null) {
213 189 consumer.accept(new FromDeviceRpcResponse(requestId, null, RpcError.TIMEOUT));
214 190 }
215 191 }, timeout, TimeUnit.MILLISECONDS);
216 192 }
217 193
  194 + private void scheduleToDeviceTimeout(ToDeviceRpcRequest request, UUID requestId) {
  195 + long timeout = Math.max(0, request.getExpirationTime() - System.currentTimeMillis());
  196 + log.trace("[{}] processing to device request: [{}]", this.hashCode(), requestId);
  197 + scheduler.schedule(() -> {
  198 + log.trace("[{}] timeout for to device request: [{}]", this.hashCode(), requestId);
  199 + localToDeviceRpcRequests.remove(requestId);
  200 + }, timeout, TimeUnit.MILLISECONDS);
  201 + }
218 202
219 203 }
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.service.rpc;
  17 +
  18 +import lombok.extern.slf4j.Slf4j;
  19 +import org.springframework.beans.factory.annotation.Autowired;
  20 +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
  21 +import org.springframework.context.annotation.Lazy;
  22 +import org.springframework.stereotype.Service;
  23 +import org.thingsboard.common.util.ThingsBoardThreadFactory;
  24 +import org.thingsboard.rule.engine.api.RpcError;
  25 +import org.thingsboard.rule.engine.api.RuleEngineDeviceRpcRequest;
  26 +import org.thingsboard.rule.engine.api.RuleEngineDeviceRpcResponse;
  27 +import org.thingsboard.server.common.data.id.DeviceId;
  28 +import org.thingsboard.server.common.data.rpc.ToDeviceRpcRequestBody;
  29 +import org.thingsboard.server.common.msg.queue.ServiceType;
  30 +import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
  31 +import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest;
  32 +import org.thingsboard.server.queue.discovery.PartitionService;
  33 +import org.thingsboard.server.queue.discovery.TbServiceInfoProvider;
  34 +import org.thingsboard.server.service.queue.TbClusterService;
  35 +
  36 +import javax.annotation.PostConstruct;
  37 +import javax.annotation.PreDestroy;
  38 +import java.util.Optional;
  39 +import java.util.UUID;
  40 +import java.util.concurrent.ConcurrentHashMap;
  41 +import java.util.concurrent.ConcurrentMap;
  42 +import java.util.concurrent.Executors;
  43 +import java.util.concurrent.ScheduledExecutorService;
  44 +import java.util.concurrent.TimeUnit;
  45 +import java.util.function.Consumer;
  46 +
  47 +@Service
  48 +@ConditionalOnExpression("'${service.type:null}'=='monolith' || '${service.type:null}'=='tb-rule-engine'")
  49 +@Slf4j
  50 +public class DefaultTbRuleEngineRpcService implements TbRuleEngineDeviceRpcService {
  51 +
  52 + private final PartitionService partitionService;
  53 + private final TbClusterService clusterService;
  54 + private final TbServiceInfoProvider serviceInfoProvider;
  55 +
  56 + private final ConcurrentMap<UUID, Consumer<FromDeviceRpcResponse>> toDeviceRpcRequests = new ConcurrentHashMap<>();
  57 +
  58 + private Optional<TbCoreDeviceRpcService> tbCoreRpcService;
  59 + private ScheduledExecutorService scheduler;
  60 + private String serviceId;
  61 +
  62 + public DefaultTbRuleEngineRpcService(PartitionService partitionService,
  63 + TbClusterService clusterService,
  64 + TbServiceInfoProvider serviceInfoProvider) {
  65 + this.partitionService = partitionService;
  66 + this.clusterService = clusterService;
  67 + this.serviceInfoProvider = serviceInfoProvider;
  68 + }
  69 +
  70 + @Autowired
  71 + public void setTbCoreRpcService(Optional<TbCoreDeviceRpcService> tbCoreRpcService) {
  72 + this.tbCoreRpcService = tbCoreRpcService;
  73 + }
  74 +
  75 + @PostConstruct
  76 + public void initExecutor() {
  77 + scheduler = Executors.newSingleThreadScheduledExecutor(ThingsBoardThreadFactory.forName("rule-engine-rpc-scheduler"));
  78 + serviceId = serviceInfoProvider.getServiceId();
  79 + }
  80 +
  81 + @PreDestroy
  82 + public void shutdownExecutor() {
  83 + if (scheduler != null) {
  84 + scheduler.shutdownNow();
  85 + }
  86 + }
  87 +
  88 + @Override
  89 + public void sendRpcReplyToDevice(DeviceId deviceId, int requestId, String body) {
  90 +// TODO 2.5
  91 + }
  92 +
  93 + @Override
  94 + public void sendRpcRequestToDevice(RuleEngineDeviceRpcRequest src, Consumer<RuleEngineDeviceRpcResponse> consumer) {
  95 + ToDeviceRpcRequest request = new ToDeviceRpcRequest(src.getRequestUUID(), src.getTenantId(), src.getDeviceId(),
  96 + src.isOneway(), src.getExpirationTime(), new ToDeviceRpcRequestBody(src.getMethod(), src.getBody()));
  97 + forwardRpcRequestToDeviceActor(request, response -> {
  98 + if (src.isRestApiCall()) {
  99 + sendRpcResponseToTbCore(src.getOriginServiceId(), response);
  100 + }
  101 + consumer.accept(RuleEngineDeviceRpcResponse.builder()
  102 + .deviceId(src.getDeviceId())
  103 + .requestId(src.getRequestId())
  104 + .error(response.getError())
  105 + .response(response.getResponse())
  106 + .build());
  107 + });
  108 + }
  109 +
  110 + @Override
  111 + public void processRpcResponseFromDevice(FromDeviceRpcResponse response) {
  112 + log.trace("[{}] Received response to server-side RPC request from Core RPC Service", response.getId());
  113 + UUID requestId = response.getId();
  114 + Consumer<FromDeviceRpcResponse> consumer = toDeviceRpcRequests.remove(requestId);
  115 + if (consumer != null) {
  116 + scheduler.submit(() -> consumer.accept(response));
  117 + } else {
  118 + log.trace("[{}] Unknown or stale rpc response received [{}]", requestId, response);
  119 + }
  120 + }
  121 +
  122 + private void forwardRpcRequestToDeviceActor(ToDeviceRpcRequest request, Consumer<FromDeviceRpcResponse> responseConsumer) {
  123 + log.trace("[{}][{}] Processing local rpc call to device actor [{}]", request.getTenantId(), request.getId(), request.getDeviceId());
  124 + UUID requestId = request.getId();
  125 + toDeviceRpcRequests.put(requestId, responseConsumer);
  126 + sendRpcRequestToDevice(request);
  127 + scheduleTimeout(request, requestId);
  128 + }
  129 +
  130 + private void sendRpcRequestToDevice(ToDeviceRpcRequest msg) {
  131 + TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_CORE, msg.getTenantId(), msg.getDeviceId());
  132 + ToDeviceRpcRequestActorMsg rpcMsg = new ToDeviceRpcRequestActorMsg(serviceId, msg);
  133 + if (tpi.isMyPartition()) {
  134 + log.trace("[{}] Forwarding msg {} to device actor!", msg.getDeviceId(), msg);
  135 + if (tbCoreRpcService.isPresent()) {
  136 + tbCoreRpcService.get().forwardRpcRequestToDeviceActor(rpcMsg);
  137 + } else {
  138 + log.warn("Failed to find tbCoreRpcService for local service. Possible duplication of serviceIds.");
  139 + }
  140 + } else {
  141 + log.trace("[{}] Forwarding msg {} to queue actor!", msg.getDeviceId(), msg);
  142 + clusterService.onToCoreMsg(rpcMsg);
  143 + }
  144 + }
  145 +
  146 + private void sendRpcResponseToTbCore(String originServiceId, FromDeviceRpcResponse response) {
  147 + if (serviceId.equals(originServiceId)) {
  148 + if (tbCoreRpcService.isPresent()) {
  149 + tbCoreRpcService.get().processRpcResponseFromRuleEngine(response);
  150 + } else {
  151 + log.warn("Failed to find tbCoreRpcService for local service. Possible duplication of serviceIds.");
  152 + }
  153 + } else {
  154 + clusterService.onToCoreMsg(originServiceId, response);
  155 + }
  156 + }
  157 +
  158 + private void scheduleTimeout(ToDeviceRpcRequest request, UUID requestId) {
  159 + long timeout = Math.max(0, request.getExpirationTime() - System.currentTimeMillis());
  160 + log.trace("[{}] processing the request: [{}]", this.hashCode(), requestId);
  161 + scheduler.schedule(() -> {
  162 + log.trace("[{}] timeout the request: [{}]", this.hashCode(), requestId);
  163 + Consumer<FromDeviceRpcResponse> consumer = toDeviceRpcRequests.remove(requestId);
  164 + if (consumer != null) {
  165 + scheduler.submit(() -> consumer.accept(new FromDeviceRpcResponse(requestId, null, RpcError.TIMEOUT)));
  166 + }
  167 + }, timeout, TimeUnit.MILLISECONDS);
  168 + }
  169 +}
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.service.rpc;
  17 +
  18 +import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest;
  19 +
  20 +import java.util.function.Consumer;
  21 +
  22 +/**
  23 + * Handles REST API calls that contain RPC requests to Device.
  24 + */
  25 +public interface TbCoreDeviceRpcService {
  26 +
  27 + /**
  28 + * Handles REST API calls that contain RPC requests to Device and pushes them to Rule Engine.
  29 + * Schedules the timeout for the RPC call based on the {@link ToDeviceRpcRequest}
  30 + *
  31 + * @param request the RPC request
  32 + * @param responseConsumer the consumer of the RPC response
  33 + */
  34 + void processRestApiRpcRequest(ToDeviceRpcRequest request, Consumer<FromDeviceRpcResponse> responseConsumer);
  35 +
  36 + /**
  37 + * Handles the RPC response from the Rule Engine.
  38 + *
  39 + * @param response the RPC response
  40 + */
  41 + void processRpcResponseFromRuleEngine(FromDeviceRpcResponse response);
  42 +
  43 + /**
  44 + * Forwards the RPC request from Rule Engine to Device Actor
  45 + *
  46 + * @param request the RPC request message
  47 + */
  48 + void forwardRpcRequestToDeviceActor(ToDeviceRpcRequestActorMsg request);
  49 +
  50 + /**
  51 + * Handles the RPC response from the Device Actor (Transport).
  52 + *
  53 + * @param response the RPC response
  54 + */
  55 + void processRpcResponseFromDeviceActor(FromDeviceRpcResponse response);
  56 +
  57 +}
... ...
application/src/main/java/org/thingsboard/server/service/rpc/TbRuleEngineDeviceRpcService.java renamed from common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/SessionMsgProcessor.java
... ... @@ -13,12 +13,20 @@
13 13 * See the License for the specific language governing permissions and
14 14 * limitations under the License.
15 15 */
16   -package org.thingsboard.server.common.transport;
  16 +package org.thingsboard.server.service.rpc;
17 17
18   -import org.thingsboard.server.common.data.Device;
  18 +import org.thingsboard.rule.engine.api.RuleEngineRpcService;
19 19
20   -public interface SessionMsgProcessor {
  20 +/**
  21 + * Created by ashvayka on 16.04.18.
  22 + */
  23 +public interface TbRuleEngineDeviceRpcService extends RuleEngineRpcService {
21 24
22   - void onDeviceAdded(Device device);
  25 + /**
  26 + * Handles the RPC response from the Device Actor (Transport).
  27 + *
  28 + * @param response the RPC response
  29 + */
  30 + void processRpcResponseFromDevice(FromDeviceRpcResponse response);
23 31
24 32 }
... ...
... ... @@ -35,7 +35,7 @@ import java.util.Optional;
35 35 public class ToDeviceRpcRequestActorMsg implements ToDeviceActorNotificationMsg {
36 36
37 37 @Getter
38   - private final ServerAddress serverAddress;
  38 + private final String serviceId;
39 39 @Getter
40 40 private final ToDeviceRpcRequest msg;
41 41
... ...
... ... @@ -5,7 +5,7 @@
5 5 * you may not use this file except in compliance with the License.
6 6 * You may obtain a copy of the License at
7 7 *
8   - * http://www.apache.org/licenses/LICENSE-2.0
  8 + * http://www.apache.org/licenses/LICENSE-2.0
9 9 *
10 10 * Unless required by applicable law or agreed to in writing, software
11 11 * distributed under the License is distributed on an "AS IS" BASIS,
... ... @@ -32,7 +32,6 @@ import org.springframework.stereotype.Service;
32 32 import org.springframework.util.StringUtils;
33 33 import org.thingsboard.common.util.ThingsBoardThreadFactory;
34 34 import org.thingsboard.server.actors.service.ActorService;
35   -import org.thingsboard.server.queue.TbQueueCallback;
36 35 import org.thingsboard.server.queue.common.TbProtoQueueMsg;
37 36 import org.thingsboard.server.common.data.DataConstants;
38 37 import org.thingsboard.server.common.data.Device;
... ... @@ -50,19 +49,17 @@ import org.thingsboard.server.common.data.page.TextPageLink;
50 49 import org.thingsboard.server.common.msg.TbMsg;
51 50 import org.thingsboard.server.common.msg.TbMsgDataType;
52 51 import org.thingsboard.server.common.msg.TbMsgMetaData;
53   -import org.thingsboard.server.common.msg.cluster.SendToClusterMsg;
54   -import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg;
55 52 import org.thingsboard.server.dao.attributes.AttributesService;
56 53 import org.thingsboard.server.dao.device.DeviceService;
57 54 import org.thingsboard.server.dao.tenant.TenantService;
58 55 import org.thingsboard.server.dao.timeseries.TimeseriesService;
59 56 import org.thingsboard.server.queue.discovery.PartitionChangeEvent;
60 57 import org.thingsboard.server.queue.discovery.PartitionService;
61   -import org.thingsboard.server.queue.discovery.ServiceType;
62   -import org.thingsboard.server.queue.discovery.TopicPartitionInfo;
  58 +import org.thingsboard.server.common.msg.queue.ServiceType;
  59 +import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
63 60 import org.thingsboard.server.gen.transport.TransportProtos;
64   -import org.thingsboard.server.queue.provider.TbCoreQueueProvider;
65 61 import org.thingsboard.server.common.msg.queue.TbMsgCallback;
  62 +import org.thingsboard.server.queue.provider.TbQueueProducerProvider;
66 63 import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService;
67 64
68 65 import javax.annotation.Nullable;
... ... @@ -106,30 +103,13 @@ public class DefaultDeviceStateService implements DeviceStateService {
106 103 public static final List<String> PERSISTENT_ATTRIBUTES = Arrays.asList(ACTIVITY_STATE, LAST_CONNECT_TIME,
107 104 LAST_DISCONNECT_TIME, LAST_ACTIVITY_TIME, INACTIVITY_ALARM_TIME, INACTIVITY_TIMEOUT);
108 105
109   - @Autowired
110   - private TenantService tenantService;
111   -
112   - @Autowired
113   - private DeviceService deviceService;
114   -
115   - @Autowired
116   - private AttributesService attributesService;
117   -
118   - @Autowired
119   - private TimeseriesService tsService;
120   -
121   - @Autowired
122   - @Lazy
123   - private ActorService actorService;
124   -
125   - @Autowired
126   - private TbCoreQueueProvider queueProvider;
127   -
128   - @Autowired
129   - private PartitionService partitionService;
130   -
131   - @Autowired
132   - private TelemetrySubscriptionService tsSubService;
  106 + private final TenantService tenantService;
  107 + private final DeviceService deviceService;
  108 + private final AttributesService attributesService;
  109 + private final TimeseriesService tsService;
  110 + private final TbQueueProducerProvider producerProvider;
  111 + private final PartitionService partitionService;
  112 + private final TelemetrySubscriptionService tsSubService;
133 113
134 114 @Value("${state.defaultInactivityTimeoutInSec}")
135 115 @Getter
... ... @@ -155,6 +135,18 @@ public class DefaultDeviceStateService implements DeviceStateService {
155 135 private ConcurrentMap<DeviceId, Long> deviceLastReportedActivity = new ConcurrentHashMap<>();
156 136 private ConcurrentMap<DeviceId, Long> deviceLastSavedActivity = new ConcurrentHashMap<>();
157 137
  138 + public DefaultDeviceStateService(TenantService tenantService, DeviceService deviceService,
  139 + AttributesService attributesService, TimeseriesService tsService,
  140 + TbQueueProducerProvider producerProvider, PartitionService partitionService, TelemetrySubscriptionService tsSubService) {
  141 + this.tenantService = tenantService;
  142 + this.deviceService = deviceService;
  143 + this.attributesService = attributesService;
  144 + this.tsService = tsService;
  145 + this.producerProvider = producerProvider;
  146 + this.partitionService = partitionService;
  147 + this.tsSubService = tsSubService;
  148 + }
  149 +
158 150 @PostConstruct
159 151 public void init() {
160 152 // Should be always single threaded due to absence of locks.
... ... @@ -429,7 +421,7 @@ public class DefaultDeviceStateService implements DeviceStateService {
429 421 builder.setUpdated(updated);
430 422 builder.setDeleted(deleted);
431 423 TransportProtos.DeviceStateServiceMsgProto msg = builder.build();
432   - queueProvider.getTbCoreMsgProducer().send(tpi, new TbProtoQueueMsg<>(deviceId.getId(),
  424 + producerProvider.getTbCoreMsgProducer().send(tpi, new TbProtoQueueMsg<>(deviceId.getId(),
433 425 TransportProtos.ToCoreMsg.newBuilder().setDeviceStateServiceMsg(msg).build()), null);
434 426 }
435 427
... ... @@ -508,7 +500,7 @@ public class DefaultDeviceStateService implements DeviceStateService {
508 500 .setTenantIdMSB(stateData.getTenantId().getId().getMostSignificantBits())
509 501 .setTenantIdLSB(stateData.getTenantId().getId().getLeastSignificantBits())
510 502 .setTbMsg(TbMsg.toByteString(tbMsg)).build();
511   - queueProvider.getRuleEngineMsgProducer().send(tpi, new TbProtoQueueMsg<>(tbMsg.getId(), msg), null);
  503 + producerProvider.getRuleEngineMsgProducer().send(tpi, new TbProtoQueueMsg<>(tbMsg.getId(), msg), null);
512 504 } catch (Exception e) {
513 505 log.warn("[{}] Failed to push inactivity alarm: {}", stateData.getDeviceId(), state, e);
514 506 }
... ...
... ... @@ -22,7 +22,6 @@ import org.springframework.util.StringUtils;
22 22 import org.thingsboard.common.util.DonAsynchron;
23 23 import org.thingsboard.common.util.ThingsBoardThreadFactory;
24 24 import org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg;
25   -import org.thingsboard.server.actors.service.ActorService;
26 25 import org.thingsboard.server.common.data.DataConstants;
27 26 import org.thingsboard.server.common.data.EntityType;
28 27 import org.thingsboard.server.common.data.id.DeviceId;
... ... @@ -34,21 +33,22 @@ import org.thingsboard.server.common.data.kv.BaseReadTsKvQuery;
34 33 import org.thingsboard.server.common.data.kv.BasicTsKvEntry;
35 34 import org.thingsboard.server.common.data.kv.ReadTsKvQuery;
36 35 import org.thingsboard.server.common.data.kv.TsKvEntry;
  36 +import org.thingsboard.server.common.msg.queue.ServiceType;
  37 +import org.thingsboard.server.common.msg.queue.TbMsgCallback;
  38 +import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
37 39 import org.thingsboard.server.dao.attributes.AttributesService;
38 40 import org.thingsboard.server.dao.timeseries.TimeseriesService;
  41 +import org.thingsboard.server.gen.transport.TransportProtos.*;
39 42 import org.thingsboard.server.gen.transport.TransportProtos.LocalSubscriptionServiceMsgProto;
40 43 import org.thingsboard.server.gen.transport.TransportProtos.TbSubscriptionUpdateProto;
41 44 import org.thingsboard.server.gen.transport.TransportProtos.TbSubscriptionUpdateValueListProto;
42   -import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
43 45 import org.thingsboard.server.queue.TbQueueProducer;
44 46 import org.thingsboard.server.queue.common.TbProtoQueueMsg;
45 47 import org.thingsboard.server.queue.discovery.PartitionChangeEvent;
46 48 import org.thingsboard.server.queue.discovery.PartitionService;
47   -import org.thingsboard.server.queue.discovery.ServiceType;
48 49 import org.thingsboard.server.queue.discovery.TbServiceInfoProvider;
49   -import org.thingsboard.server.queue.discovery.TopicPartitionInfo;
50   -import org.thingsboard.server.queue.provider.TbCoreQueueProvider;
51   -import org.thingsboard.server.common.msg.queue.TbMsgCallback;
  50 +import org.thingsboard.server.queue.provider.TbQueueProducerProvider;
  51 +import org.thingsboard.server.service.queue.TbClusterService;
52 52 import org.thingsboard.server.service.state.DefaultDeviceStateService;
53 53 import org.thingsboard.server.service.state.DeviceStateService;
54 54 import org.thingsboard.server.service.telemetry.sub.SubscriptionUpdate;
... ... @@ -86,16 +86,16 @@ public class DefaultSubscriptionManagerService implements SubscriptionManagerSer
86 86 private TbServiceInfoProvider serviceInfoProvider;
87 87
88 88 @Autowired
89   - private TbCoreQueueProvider coreQueueProvider;
  89 + private TbQueueProducerProvider producerProvider;
90 90
91 91 @Autowired
92   - private LocalSubscriptionService localSubscriptionService;
  92 + private TbLocalSubscriptionService localSubscriptionService;
93 93
94 94 @Autowired
95 95 private DeviceStateService deviceStateService;
96 96
97 97 @Autowired
98   - private ActorService actorService;
  98 + private TbClusterService clusterService;
99 99
100 100 private final Map<EntityId, Set<TbSubscription>> subscriptionsByEntityId = new ConcurrentHashMap<>();
101 101 private final Map<String, Map<Integer, TbSubscription>> subscriptionsByWsSessionId = new ConcurrentHashMap<>();
... ... @@ -104,13 +104,13 @@ public class DefaultSubscriptionManagerService implements SubscriptionManagerSer
104 104
105 105 private ExecutorService tsCallBackExecutor;
106 106 private String serviceId;
107   - private TbQueueProducer<TbProtoQueueMsg<ToCoreMsg>> toCoreProducer;
  107 + private TbQueueProducer<TbProtoQueueMsg<ToCoreNotificationMsg>> toCoreNotificationsProducer;
108 108
109 109 @PostConstruct
110 110 public void initExecutor() {
111 111 tsCallBackExecutor = Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName("ts-sub-callback"));
112 112 serviceId = serviceInfoProvider.getServiceId();
113   - toCoreProducer = coreQueueProvider.getTbCoreMsgProducer();
  113 + toCoreNotificationsProducer = producerProvider.getTbCoreNotificationsMsgProducer();
114 114 }
115 115
116 116 @PreDestroy
... ... @@ -241,9 +241,8 @@ public class DefaultSubscriptionManagerService implements SubscriptionManagerSer
241 241 }
242 242 }
243 243 } else if (TbAttributeSubscriptionScope.SHARED_SCOPE.name().equalsIgnoreCase(scope)) {
244   - DeviceAttributesEventNotificationMsg notificationMsg = DeviceAttributesEventNotificationMsg.onUpdate(tenantId,
245   - new DeviceId(entityId.getId()), DataConstants.SHARED_SCOPE, new ArrayList<>(attributes));
246   - actorService.onMsg(notificationMsg);
  244 + clusterService.onToCoreMsg(DeviceAttributesEventNotificationMsg.onUpdate(tenantId,
  245 + new DeviceId(entityId.getId()), DataConstants.SHARED_SCOPE, new ArrayList<>(attributes)));
247 246 }
248 247 }
249 248 callback.onSuccess();
... ... @@ -263,7 +262,7 @@ public class DefaultSubscriptionManagerService implements SubscriptionManagerSer
263 262 localSubscriptionService.onSubscriptionUpdate(s.getSessionId(), update, TbMsgCallback.EMPTY);
264 263 } else {
265 264 TopicPartitionInfo tpi = partitionService.getNotificationsTopic(ServiceType.TB_CORE, s.getServiceId());
266   - toCoreProducer.send(tpi, toProto(s, subscriptionUpdate), null);
  265 + toCoreNotificationsProducer.send(tpi, toProto(s, subscriptionUpdate), null);
267 266 }
268 267 }
269 268 });
... ... @@ -309,7 +308,7 @@ public class DefaultSubscriptionManagerService implements SubscriptionManagerSer
309 308 });
310 309 if (!missedUpdates.isEmpty()) {
311 310 TopicPartitionInfo tpi = partitionService.getNotificationsTopic(ServiceType.TB_CORE, subscription.getServiceId());
312   - toCoreProducer.send(tpi, toProto(subscription, missedUpdates), null);
  311 + toCoreNotificationsProducer.send(tpi, toProto(subscription, missedUpdates), null);
313 312 }
314 313 },
315 314 e -> log.error("Failed to fetch missed updates.", e), tsCallBackExecutor);
... ... @@ -333,7 +332,7 @@ public class DefaultSubscriptionManagerService implements SubscriptionManagerSer
333 332 missedUpdates -> {
334 333 if (missedUpdates != null && !missedUpdates.isEmpty()) {
335 334 TopicPartitionInfo tpi = partitionService.getNotificationsTopic(ServiceType.TB_CORE, subscription.getServiceId());
336   - toCoreProducer.send(tpi, toProto(subscription, missedUpdates), null);
  335 + toCoreNotificationsProducer.send(tpi, toProto(subscription, missedUpdates), null);
337 336 }
338 337 },
339 338 e -> log.error("Failed to fetch missed updates.", e),
... ... @@ -341,7 +340,7 @@ public class DefaultSubscriptionManagerService implements SubscriptionManagerSer
341 340 }
342 341 }
343 342
344   - private TbProtoQueueMsg<ToCoreMsg> toProto(TbSubscription subscription, List<TsKvEntry> updates) {
  343 + private TbProtoQueueMsg<ToCoreNotificationMsg> toProto(TbSubscription subscription, List<TsKvEntry> updates) {
345 344 TbSubscriptionUpdateProto.Builder builder = TbSubscriptionUpdateProto.newBuilder();
346 345
347 346 builder.setSessionId(subscription.getSessionId());
... ... @@ -367,7 +366,7 @@ public class DefaultSubscriptionManagerService implements SubscriptionManagerSer
367 366 builder.addData(dataBuilder.build());
368 367 });
369 368
370   - ToCoreMsg toCoreMsg = ToCoreMsg.newBuilder().setToLocalSubscriptionServiceMsg(
  369 + ToCoreNotificationMsg toCoreMsg = ToCoreNotificationMsg.newBuilder().setToLocalSubscriptionServiceMsg(
371 370 LocalSubscriptionServiceMsgProto.newBuilder().setSubUpdate(builder.build()).build())
372 371 .build();
373 372 return new TbProtoQueueMsg<>(subscription.getEntityId().getId(), toCoreMsg);
... ...
application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbLocalSubscriptionService.java renamed from application/src/main/java/org/thingsboard/server/service/subscription/DefaultLocalSubscriptionService.java
... ... @@ -33,10 +33,10 @@ import org.thingsboard.server.queue.common.TbProtoQueueMsg;
33 33 import org.thingsboard.server.queue.discovery.ClusterTopologyChangeEvent;
34 34 import org.thingsboard.server.queue.discovery.PartitionChangeEvent;
35 35 import org.thingsboard.server.queue.discovery.PartitionService;
36   -import org.thingsboard.server.queue.discovery.ServiceType;
37   -import org.thingsboard.server.queue.discovery.TopicPartitionInfo;
38   -import org.thingsboard.server.queue.provider.TbCoreQueueProvider;
  36 +import org.thingsboard.server.common.msg.queue.ServiceType;
  37 +import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
39 38 import org.thingsboard.server.common.msg.queue.TbMsgCallback;
  39 +import org.thingsboard.server.queue.provider.TbQueueProducerProvider;
40 40 import org.thingsboard.server.service.telemetry.TelemetryWebSocketService;
41 41 import org.thingsboard.server.service.telemetry.sub.SubscriptionUpdate;
42 42
... ... @@ -53,7 +53,7 @@ import java.util.stream.Collectors;
53 53
54 54 @Slf4j
55 55 @Service
56   -public class DefaultLocalSubscriptionService implements LocalSubscriptionService {
  56 +public class DefaultTbLocalSubscriptionService implements TbLocalSubscriptionService {
57 57
58 58 private final Set<TopicPartitionInfo> currentPartitions = ConcurrentHashMap.newKeySet();
59 59 private final Map<String, Map<Integer, TbSubscription>> subscriptionsBySessionId = new ConcurrentHashMap<>();
... ... @@ -68,7 +68,7 @@ public class DefaultLocalSubscriptionService implements LocalSubscriptionService
68 68 private PartitionService partitionService;
69 69
70 70 @Autowired
71   - private TbCoreQueueProvider coreQueueProvider;
  71 + private TbQueueProducerProvider producerProvider;
72 72
73 73 @Autowired
74 74 @Lazy
... ... @@ -80,7 +80,7 @@ public class DefaultLocalSubscriptionService implements LocalSubscriptionService
80 80 @PostConstruct
81 81 public void initExecutor() {
82 82 wsCallBackExecutor = Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName("ws-sub-callback"));
83   - toCoreProducer = coreQueueProvider.getTbCoreMsgProducer();
  83 + toCoreProducer = producerProvider.getTbCoreMsgProducer();
84 84 }
85 85
86 86 @PreDestroy
... ...
application/src/main/java/org/thingsboard/server/service/subscription/TbLocalSubscriptionService.java renamed from application/src/main/java/org/thingsboard/server/service/subscription/LocalSubscriptionService.java
... ... @@ -20,7 +20,7 @@ import org.thingsboard.server.queue.discovery.PartitionChangeEvent;
20 20 import org.thingsboard.server.common.msg.queue.TbMsgCallback;
21 21 import org.thingsboard.server.service.telemetry.sub.SubscriptionUpdate;
22 22
23   -public interface LocalSubscriptionService {
  23 +public interface TbLocalSubscriptionService {
24 24
25 25 void addSubscription(TbSubscription subscription);
26 26
... ...
... ... @@ -39,10 +39,10 @@ import org.thingsboard.server.queue.TbQueueProducer;
39 39 import org.thingsboard.server.queue.common.TbProtoQueueMsg;
40 40 import org.thingsboard.server.queue.discovery.PartitionChangeEvent;
41 41 import org.thingsboard.server.queue.discovery.PartitionService;
42   -import org.thingsboard.server.queue.discovery.ServiceType;
43   -import org.thingsboard.server.queue.discovery.TopicPartitionInfo;
44   -import org.thingsboard.server.queue.provider.TbCoreQueueProvider;
  42 +import org.thingsboard.server.common.msg.queue.ServiceType;
  43 +import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
45 44 import org.thingsboard.server.common.msg.queue.TbMsgCallback;
  45 +import org.thingsboard.server.queue.provider.TbQueueProducerProvider;
46 46 import org.thingsboard.server.service.subscription.SubscriptionManagerService;
47 47 import org.thingsboard.server.service.subscription.TbSubscriptionUtils;
48 48
... ... @@ -73,7 +73,7 @@ public class DefaultTelemetrySubscriptionService implements TelemetrySubscriptio
73 73 private TimeseriesService tsService;
74 74
75 75 @Autowired
76   - private TbCoreQueueProvider coreQueueProvider;
  76 + private TbQueueProducerProvider producerProvider;
77 77
78 78 @Autowired
79 79 private PartitionService partitionService;
... ... @@ -90,7 +90,7 @@ public class DefaultTelemetrySubscriptionService implements TelemetrySubscriptio
90 90 public void initExecutor() {
91 91 tsCallBackExecutor = Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName("ts-service-ts-callback"));
92 92 wsCallBackExecutor = Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName("ts-service-ws-callback"));
93   - toCoreProducer = coreQueueProvider.getTbCoreMsgProducer();
  93 + toCoreProducer = producerProvider.getTbCoreMsgProducer();
94 94 }
95 95
96 96 @PreDestroy
... ...
... ... @@ -49,7 +49,7 @@ import org.thingsboard.server.service.security.ValidationResult;
49 49 import org.thingsboard.server.service.security.ValidationResultCode;
50 50 import org.thingsboard.server.service.security.model.UserPrincipal;
51 51 import org.thingsboard.server.service.security.permission.Operation;
52   -import org.thingsboard.server.service.subscription.LocalSubscriptionService;
  52 +import org.thingsboard.server.service.subscription.TbLocalSubscriptionService;
53 53 import org.thingsboard.server.service.subscription.TbAttributeSubscriptionScope;
54 54 import org.thingsboard.server.service.subscription.TbAttributeSubscription;
55 55 import org.thingsboard.server.service.subscription.TbTimeseriesSubscription;
... ... @@ -98,7 +98,7 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi
98 98 private final ConcurrentMap<String, WsSessionMetaData> wsSessionsMap = new ConcurrentHashMap<>();
99 99
100 100 @Autowired
101   - private LocalSubscriptionService subService;
  101 + private TbLocalSubscriptionService subService;
102 102
103 103 @Autowired
104 104 private TelemetryWebSocketMsgEndpoint msgEndpoint;
... ...
... ... @@ -23,10 +23,10 @@ import org.thingsboard.server.queue.TbQueueCallback;
23 23 import org.thingsboard.server.queue.TbQueueMsgMetadata;
24 24 import org.thingsboard.server.queue.TbQueueProducer;
25 25 import org.thingsboard.server.queue.common.TbProtoQueueMsg;
26   -import org.thingsboard.server.queue.discovery.TopicPartitionInfo;
  26 +import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
27 27 import org.thingsboard.server.gen.transport.TransportProtos.DeviceActorToTransportMsg;
28 28 import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
29   -import org.thingsboard.server.queue.provider.TbCoreQueueProvider;
  29 +import org.thingsboard.server.queue.provider.TbQueueProducerProvider;
30 30
31 31 import java.util.UUID;
32 32 import java.util.function.Consumer;
... ... @@ -43,8 +43,8 @@ public class DefaultTbCoreToTransportService implements TbCoreToTransportService
43 43 @Value("${queue.transport.notifications_topic}")
44 44 private String notificationsTopic;
45 45
46   - public DefaultTbCoreToTransportService(TbCoreQueueProvider tbCoreQueueProvider) {
47   - this.tbTransportProducer = tbCoreQueueProvider.getTransportNotificationsMsgProducer();
  46 + public DefaultTbCoreToTransportService(TbQueueProducerProvider tbQueueProducerProvider) {
  47 + this.tbTransportProducer = tbQueueProducerProvider.getTransportNotificationsMsgProducer();
48 48 }
49 49
50 50 @Override
... ...
1   -/**
2   - * Copyright © 2016-2020 The Thingsboard Authors
3   - *
4   - * Licensed under the Apache License, Version 2.0 (the "License");
5   - * you may not use this file except in compliance with the License.
6   - * You may obtain a copy of the License at
7   - *
8   - * http://www.apache.org/licenses/LICENSE-2.0
9   - *
10   - * Unless required by applicable law or agreed to in writing, software
11   - * distributed under the License is distributed on an "AS IS" BASIS,
12   - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   - * See the License for the specific language governing permissions and
14   - * limitations under the License.
15   - */
16   -syntax = "proto3";
17   -package cluster;
18   -
19   -option java_package = "org.thingsboard.server.gen.cluster";
20   -option java_outer_classname = "ClusterAPIProtos";
21   -
22   -service ClusterRpcService {
23   - rpc handleMsgs(stream ClusterMessage) returns (stream ClusterMessage) {}
24   -}
25   -
26   -message ClusterMessage {
27   - MessageType messageType = 1;
28   - MessageMataInfo messageMetaInfo = 2;
29   - ServerAddress serverAddress = 3;
30   - bytes payload = 4;
31   -}
32   -
33   -message ServerAddress {
34   - string host = 1;
35   - int32 port = 2;
36   -}
37   -
38   -message MessageMataInfo {
39   - string payloadMetaInfo = 1;
40   - repeated string tags = 2;
41   -}
42   -
43   -enum MessageType {
44   -
45   - //Cluster control messages
46   - RPC_SESSION_CREATE_REQUEST_MSG = 0;
47   - TO_ALL_NODES_MSG = 1;
48   - RPC_SESSION_TELL_MSG = 2;
49   - RPC_BROADCAST_MSG = 3;
50   - CONNECT_RPC_MESSAGE =4;
51   -
52   - CLUSTER_ACTOR_MESSAGE = 5;
53   - // Messages related to TelemetrySubscriptionService
54   - CLUSTER_TELEMETRY_SUBSCRIPTION_CREATE_MESSAGE = 6;
55   - CLUSTER_TELEMETRY_SUBSCRIPTION_UPDATE_MESSAGE = 7;
56   - CLUSTER_TELEMETRY_SUBSCRIPTION_CLOSE_MESSAGE = 8;
57   - CLUSTER_TELEMETRY_SESSION_CLOSE_MESSAGE = 9;
58   - CLUSTER_TELEMETRY_ATTR_UPDATE_MESSAGE = 10;
59   - CLUSTER_TELEMETRY_TS_UPDATE_MESSAGE = 11;
60   - CLUSTER_RPC_FROM_DEVICE_RESPONSE_MESSAGE = 12;
61   -
62   - CLUSTER_DEVICE_STATE_SERVICE_MESSAGE = 13;
63   - CLUSTER_TRANSACTION_SERVICE_MESSAGE = 14;
64   -}
65   -
66   -// Messages related to CLUSTER_TELEMETRY_MESSAGE
67   -
68   -
69   -message FromDeviceRPCResponseProto {
70   - int64 requestIdMSB = 1;
71   - int64 requestIdLSB = 2;
72   - string response = 3;
73   - int32 error = 4;
74   -}
... ... @@ -540,6 +540,8 @@ queue:
540 540 response_poll_interval: "${TB_QUEUE_TRANSPORT_RESPONSE_POLL_INTERVAL_MS:25}"
541 541 core:
542 542 topic: "${TB_QUEUE_CORE_TOPIC:tb.core}"
  543 + # For high priority notifications that require minimum latency and processing time
  544 + notifications_topic: "${TB_QUEUE_CORE_NOTIFICATIONS_TOPIC:tb.rule-engine.notifications}"
543 545 poll_interval: "${TB_QUEUE_CORE_POLL_INTERVAL_MS:25}"
544 546 partitions: "${TB_QUEUE_CORE_PARTITIONS:10}"
545 547 pack_processing_timeout: "${TB_QUEUE_CORE_PACK_PROCESSING_TIMEOUT_MS:60000}"
... ... @@ -548,6 +550,8 @@ queue:
548 550 print_interval_ms: "${TB_QUEUE_CORE_STATS_PRINT_INTERVAL_MS:10000}"
549 551 rule_engine:
550 552 topic: "${TB_QUEUE_RULE_ENGINE_TOPIC:tb.rule-engine}"
  553 + # For high priority notifications that require minimum latency and processing time
  554 + notifications_topic: "${TB_QUEUE_RULE_ENGINE_NOTIFICATIONS_TOPIC:tb.rule-engine.notifications}"
551 555 poll_interval: "${TB_QUEUE_RULE_ENGINE_POLL_INTERVAL_MS:25}"
552 556 partitions: "${TB_QUEUE_RULE_ENGINE_PARTITIONS:10}"
553 557 pack_processing_timeout: "${TB_QUEUE_RULE_ENGINE_PACK_PROCESSING_TIMEOUT_MS:60000}"
... ... @@ -561,6 +565,7 @@ queue:
561 565 enabled: "${TB_QUEUE_RULE_ENGINE_STATS_ENABLED:false}"
562 566 print_interval_ms: "${TB_QUEUE_RULE_ENGINE_STATS_PRINT_INTERVAL_MS:10000}"
563 567 transport:
  568 + # For high priority notifications that require minimum latency and processing time
564 569 notifications_topic: "${TB_QUEUE_TRANSPORT_NOTIFICATIONS_TOPIC:tb.transport.notifications}"
565 570 poll_interval: "${TB_QUEUE_CORE_POLL_INTERVAL_MS:25}"
566 571
... ...
... ... @@ -150,7 +150,8 @@ public abstract class AbstractRuleEngineFlowIntegrationTest extends AbstractRule
150 150 device.getId(),
151 151 new TbMsgMetaData(), TbMsgDataType.JSON,
152 152 "{}", null, null, null);
153   - actorService.onMsg(new SendToClusterMsg(device.getId(), new QueueToRuleEngineMsg(savedTenant.getId(), tbMsg)));
  153 + //TODO 2.5
  154 +// actorService.onMsg(new SendToClusterMsg(device.getId(), new QueueToRuleEngineMsg(savedTenant.getId(), tbMsg)));
154 155
155 156 Thread.sleep(3000);
156 157
... ... @@ -266,7 +267,8 @@ public abstract class AbstractRuleEngineFlowIntegrationTest extends AbstractRule
266 267 new TbMsgMetaData(),
267 268 TbMsgDataType.JSON,
268 269 "{}", null, null, null);
269   - actorService.onMsg(new SendToClusterMsg(device.getId(), new QueueToRuleEngineMsg(savedTenant.getId(), tbMsg)));
  270 + //TODO 2.5
  271 +// actorService.onMsg(new SendToClusterMsg(device.getId(), new QueueToRuleEngineMsg(savedTenant.getId(), tbMsg)));
270 272
271 273 Thread.sleep(3000);
272 274
... ...
... ... @@ -143,7 +143,8 @@ public abstract class AbstractRuleEngineLifecycleIntegrationTest extends Abstrac
143 143 TbMsgDataType.JSON,
144 144 "{}",
145 145 null, null, null);
146   - actorService.onMsg(new SendToClusterMsg(device.getId(), new QueueToRuleEngineMsg(savedTenant.getId(), tbMsg)));
  146 + //TODO 2.5
  147 +// actorService.onMsg(new SendToClusterMsg(device.getId(), new QueueToRuleEngineMsg(savedTenant.getId(), tbMsg)));
147 148
148 149 Thread.sleep(3000);
149 150
... ...
... ... @@ -26,9 +26,9 @@ import org.springframework.test.util.ReflectionTestUtils;
26 26 import org.thingsboard.server.common.data.id.DeviceId;
27 27 import org.thingsboard.server.common.data.id.TenantId;
28 28 import org.thingsboard.server.queue.discovery.ConsistentHashPartitionService;
29   -import org.thingsboard.server.queue.discovery.ServiceType;
  29 +import org.thingsboard.server.common.msg.queue.ServiceType;
30 30 import org.thingsboard.server.queue.discovery.TbServiceInfoProvider;
31   -import org.thingsboard.server.queue.discovery.TopicPartitionInfo;
  31 +import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
32 32 import org.thingsboard.server.gen.transport.TransportProtos;
33 33
34 34 import java.util.ArrayList;
... ...
... ... @@ -15,6 +15,7 @@
15 15 */
16 16 package org.thingsboard.server.common.msg;
17 17
  18 +import org.thingsboard.server.common.msg.queue.PartitionChangeMsg;
18 19 import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg;
19 20
20 21 /**
... ... @@ -26,9 +27,9 @@ public enum MsgType {
26 27 /**
27 28 * ADDED/UPDATED/DELETED events for server nodes.
28 29 *
29   - * See {@link org.thingsboard.server.common.msg.cluster.ClusterEventMsg}
  30 + * See {@link PartitionChangeMsg}
30 31 */
31   - CLUSTER_EVENT_MSG,
  32 + PARTITION_CHANGE_MSG,
32 33
33 34 APP_INIT_MSG,
34 35
... ...
... ... @@ -5,7 +5,7 @@
5 5 * you may not use this file except in compliance with the License.
6 6 * You may obtain a copy of the License at
7 7 *
8   - * http://www.apache.org/licenses/LICENSE-2.0
  8 + * http://www.apache.org/licenses/LICENSE-2.0
9 9 *
10 10 * Unless required by applicable law or agreed to in writing, software
11 11 * distributed under the License is distributed on an "AS IS" BASIS,
... ...
... ... @@ -33,7 +33,7 @@ import java.util.Optional;
33 33 * @author Andrew Shvayka
34 34 */
35 35 @ToString
36   -public class ComponentLifecycleMsg implements TbActorMsg, TenantAwareMsg, ToAllNodesMsg {
  36 +public class ComponentLifecycleMsg implements TenantAwareMsg, ToAllNodesMsg {
37 37 @Getter
38 38 private final TenantId tenantId;
39 39 @Getter
... ...
common/message/src/main/java/org/thingsboard/server/common/msg/queue/PartitionChangeMsg.java renamed from common/message/src/main/java/org/thingsboard/server/common/msg/cluster/ClusterEventMsg.java
... ... @@ -13,23 +13,28 @@
13 13 * See the License for the specific language governing permissions and
14 14 * limitations under the License.
15 15 */
16   -package org.thingsboard.server.common.msg.cluster;
  16 +package org.thingsboard.server.common.msg.queue;
17 17
18 18 import lombok.Data;
  19 +import lombok.Getter;
19 20 import org.thingsboard.server.common.msg.MsgType;
20 21 import org.thingsboard.server.common.msg.TbActorMsg;
21 22
  23 +import java.util.Set;
  24 +
22 25 /**
23 26 * @author Andrew Shvayka
24 27 */
25 28 @Data
26   -public final class ClusterEventMsg implements TbActorMsg {
  29 +public final class PartitionChangeMsg implements TbActorMsg {
27 30
28   - private final ServerAddress serverAddress;
29   - private final boolean added;
  31 + @Getter
  32 + private final ServiceKey serviceKey;
  33 + @Getter
  34 + private final Set<TopicPartitionInfo> partitions;
30 35
31 36 @Override
32 37 public MsgType getMsgType() {
33   - return MsgType.CLUSTER_EVENT_MSG;
  38 + return MsgType.PARTITION_CHANGE_MSG;
34 39 }
35 40 }
... ...
common/message/src/main/java/org/thingsboard/server/common/msg/queue/ServiceKey.java renamed from common/queue/src/main/java/org/thingsboard/server/queue/discovery/ServiceKey.java
... ... @@ -13,7 +13,7 @@
13 13 * See the License for the specific language governing permissions and
14 14 * limitations under the License.
15 15 */
16   -package org.thingsboard.server.queue.discovery;
  16 +package org.thingsboard.server.common.msg.queue;
17 17
18 18 import lombok.Getter;
19 19 import org.thingsboard.server.common.data.id.TenantId;
... ...
common/message/src/main/java/org/thingsboard/server/common/msg/queue/ServiceType.java renamed from common/queue/src/main/java/org/thingsboard/server/queue/discovery/ServiceType.java
... ... @@ -13,7 +13,7 @@
13 13 * See the License for the specific language governing permissions and
14 14 * limitations under the License.
15 15 */
16   -package org.thingsboard.server.queue.discovery;
  16 +package org.thingsboard.server.common.msg.queue;
17 17
18 18 public enum ServiceType {
19 19 TB_CORE, TB_RULE_ENGINE, TB_TRANSPORT, JS_EXECUTOR;
... ...
common/message/src/main/java/org/thingsboard/server/common/msg/queue/TopicPartitionInfo.java renamed from common/queue/src/main/java/org/thingsboard/server/queue/discovery/TopicPartitionInfo.java
... ... @@ -13,7 +13,7 @@
13 13 * See the License for the specific language governing permissions and
14 14 * limitations under the License.
15 15 */
16   -package org.thingsboard.server.queue.discovery;
  16 +package org.thingsboard.server.common.msg.queue;
17 17
18 18 import lombok.Builder;
19 19 import lombok.Getter;
... ...
... ... @@ -15,7 +15,7 @@
15 15 */
16 16 package org.thingsboard.server.queue;
17 17
18   -import org.thingsboard.server.queue.discovery.TopicPartitionInfo;
  18 +import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
19 19
20 20 import java.util.List;
21 21 import java.util.Set;
... ...
... ... @@ -15,7 +15,7 @@
15 15 */
16 16 package org.thingsboard.server.queue;
17 17
18   -import org.thingsboard.server.queue.discovery.TopicPartitionInfo;
  18 +import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
19 19
20 20 public interface TbQueueProducer<T extends TbQueueMsg> {
21 21
... ...
... ... @@ -28,7 +28,7 @@ import org.thingsboard.server.queue.TbQueueMsg;
28 28 import org.thingsboard.server.queue.TbQueueMsgMetadata;
29 29 import org.thingsboard.server.queue.TbQueueProducer;
30 30 import org.thingsboard.server.queue.TbQueueRequestTemplate;
31   -import org.thingsboard.server.queue.discovery.TopicPartitionInfo;
  31 +import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
32 32
33 33 import java.util.List;
34 34 import java.util.UUID;
... ...
... ... @@ -23,7 +23,7 @@ import org.thingsboard.server.queue.TbQueueHandler;
23 23 import org.thingsboard.server.queue.TbQueueMsg;
24 24 import org.thingsboard.server.queue.TbQueueProducer;
25 25 import org.thingsboard.server.queue.TbQueueResponseTemplate;
26   -import org.thingsboard.server.queue.discovery.TopicPartitionInfo;
  26 +import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
27 27
28 28 import java.util.List;
29 29 import java.util.UUID;
... ...
... ... @@ -17,6 +17,7 @@ package org.thingsboard.server.queue.discovery;
17 17
18 18 import lombok.Getter;
19 19 import org.springframework.context.ApplicationEvent;
  20 +import org.thingsboard.server.common.msg.queue.ServiceKey;
20 21
21 22 import java.util.Set;
22 23
... ...
... ... @@ -24,6 +24,9 @@ import org.springframework.context.ApplicationEventPublisher;
24 24 import org.springframework.stereotype.Service;
25 25 import org.thingsboard.server.common.data.id.EntityId;
26 26 import org.thingsboard.server.common.data.id.TenantId;
  27 +import org.thingsboard.server.common.msg.queue.ServiceKey;
  28 +import org.thingsboard.server.common.msg.queue.ServiceType;
  29 +import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
27 30 import org.thingsboard.server.gen.transport.TransportProtos;
28 31 import org.thingsboard.server.gen.transport.TransportProtos.ServiceInfo;
29 32
... ... @@ -156,8 +159,6 @@ public class ConsistentHashPartitionService implements PartitionService {
156 159 Set<TopicPartitionInfo> tpiList = partitions.stream()
157 160 .map(partition -> buildTopicPartitionInfo(serviceKey, partition))
158 161 .collect(Collectors.toSet());
159   - // Adding notifications topic for every @TopicPartitionInfo list
160   - tpiList.add(getNotificationsTopic(serviceKey.getServiceType(), serviceInfoProvider.getServiceId()));
161 162 applicationEventPublisher.publishEvent(new PartitionChangeEvent(this, serviceKey, tpiList));
162 163 }
163 164 });
... ... @@ -184,16 +185,19 @@ public class ConsistentHashPartitionService implements PartitionService {
184 185 }
185 186 }
186 187
187   - private Map<ServiceKey, List<ServiceInfo>> getServiceKeyListMap(List<ServiceInfo> services) {
188   - final Map<ServiceKey, List<ServiceInfo>> currentMap = new HashMap<>();
189   - services.forEach(serviceInfo -> {
190   - for (String serviceTypeStr : serviceInfo.getServiceTypesList()) {
191   - ServiceType serviceType = ServiceType.valueOf(serviceTypeStr.toUpperCase());
192   - ServiceKey serviceKey = new ServiceKey(serviceType, getSystemOrIsolatedTenantId(serviceInfo));
193   - currentMap.computeIfAbsent(serviceKey, key -> new ArrayList<>()).add(serviceInfo);
  188 + @Override
  189 + public Set<String> getAllServiceIds(ServiceType serviceType) {
  190 + Set<String> result = new HashSet<>();
  191 + ServiceInfo current = serviceInfoProvider.getServiceInfo();
  192 + if (current.getServiceTypesList().contains(serviceType.name())) {
  193 + result.add(current.getServiceId());
  194 + }
  195 + for (ServiceInfo serviceInfo : currentOtherServices) {
  196 + if (serviceInfo.getServiceTypesList().contains(serviceType.name())) {
  197 + result.add(serviceInfo.getServiceId());
194 198 }
195   - });
196   - return currentMap;
  199 + }
  200 + return result;
197 201 }
198 202
199 203 @Override
... ... @@ -201,17 +205,29 @@ public class ConsistentHashPartitionService implements PartitionService {
201 205 switch (serviceType) {
202 206 case TB_CORE:
203 207 return tbCoreNotificationTopics.computeIfAbsent(serviceId,
204   - id -> buildTopicPartitionInfo(serviceType, serviceId));
  208 + id -> buildNotificationsTopicPartitionInfo(serviceType, serviceId));
205 209 case TB_RULE_ENGINE:
206 210 return tbRuleEngineNotificationTopics.computeIfAbsent(serviceId,
207   - id -> buildTopicPartitionInfo(serviceType, serviceId));
  211 + id -> buildNotificationsTopicPartitionInfo(serviceType, serviceId));
208 212 default:
209   - return buildTopicPartitionInfo(serviceType, serviceId);
  213 + return buildNotificationsTopicPartitionInfo(serviceType, serviceId);
210 214 }
211 215 }
212 216
213   - private TopicPartitionInfo buildTopicPartitionInfo(ServiceType serviceType, String serviceId) {
214   - return new TopicPartitionInfo(serviceType.name().toLowerCase() + "." + serviceId, null, null, false);
  217 + private Map<ServiceKey, List<ServiceInfo>> getServiceKeyListMap(List<ServiceInfo> services) {
  218 + final Map<ServiceKey, List<ServiceInfo>> currentMap = new HashMap<>();
  219 + services.forEach(serviceInfo -> {
  220 + for (String serviceTypeStr : serviceInfo.getServiceTypesList()) {
  221 + ServiceType serviceType = ServiceType.valueOf(serviceTypeStr.toUpperCase());
  222 + ServiceKey serviceKey = new ServiceKey(serviceType, getSystemOrIsolatedTenantId(serviceInfo));
  223 + currentMap.computeIfAbsent(serviceKey, key -> new ArrayList<>()).add(serviceInfo);
  224 + }
  225 + });
  226 + return currentMap;
  227 + }
  228 +
  229 + private TopicPartitionInfo buildNotificationsTopicPartitionInfo(ServiceType serviceType, String serviceId) {
  230 + return new TopicPartitionInfo(serviceType.name().toLowerCase() + ".notifications." + serviceId, null, null, false);
215 231 }
216 232
217 233 private TopicPartitionInfo buildTopicPartitionInfo(ServiceKey serviceKey, int partition) {
... ...
... ... @@ -21,6 +21,7 @@ import org.springframework.beans.factory.annotation.Value;
21 21 import org.springframework.stereotype.Component;
22 22 import org.springframework.util.StringUtils;
23 23 import org.thingsboard.server.common.data.id.TenantId;
  24 +import org.thingsboard.server.common.msg.queue.ServiceType;
24 25 import org.thingsboard.server.gen.transport.TransportProtos.ServiceInfo;
25 26
26 27 import javax.annotation.PostConstruct;
... ...
... ... @@ -17,6 +17,8 @@ package org.thingsboard.server.queue.discovery;
17 17
18 18 import lombok.Getter;
19 19 import org.springframework.context.ApplicationEvent;
  20 +import org.thingsboard.server.common.msg.queue.ServiceKey;
  21 +import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
20 22
21 23 import java.util.Set;
22 24
... ...
... ... @@ -17,6 +17,8 @@ package org.thingsboard.server.queue.discovery;
17 17
18 18 import org.thingsboard.server.common.data.id.EntityId;
19 19 import org.thingsboard.server.common.data.id.TenantId;
  20 +import org.thingsboard.server.common.msg.queue.ServiceType;
  21 +import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
20 22 import org.thingsboard.server.gen.transport.TransportProtos;
21 23
22 24 import java.util.List;
... ... @@ -39,11 +41,18 @@ public interface PartitionService {
39 41 void recalculatePartitions(TransportProtos.ServiceInfo currentService, List<TransportProtos.ServiceInfo> otherServices);
40 42
41 43 /**
  44 + * Get all active service ids by service type
  45 + * @param serviceType to filter the list of services
  46 + * @return list of all active services
  47 + */
  48 + Set<String> getAllServiceIds(ServiceType serviceType);
  49 +
  50 + /**
42 51 * Each Service should start a consumer for messages that target individual service instance based on serviceId.
43 52 * This topic is likely to have single partition, and is always assigned to the service.
44   - * @param tbCore
  53 + * @param serviceType
45 54 * @param serviceId
46 55 * @return
47 56 */
48   - TopicPartitionInfo getNotificationsTopic(ServiceType tbCore, String serviceId);
  57 + TopicPartitionInfo getNotificationsTopic(ServiceType serviceType, String serviceId);
49 58 }
... ...
... ... @@ -15,6 +15,7 @@
15 15 */
16 16 package org.thingsboard.server.queue.discovery;
17 17
  18 +import org.thingsboard.server.common.msg.queue.ServiceType;
18 19 import org.thingsboard.server.gen.transport.TransportProtos.ServiceInfo;
19 20
20 21 import java.util.List;
... ...
... ... @@ -17,6 +17,7 @@ package org.thingsboard.server.queue.discovery;
17 17
18 18 import lombok.AllArgsConstructor;
19 19 import org.thingsboard.server.common.data.id.TenantId;
  20 +import org.thingsboard.server.common.msg.queue.ServiceType;
20 21
21 22 import java.util.Objects;
22 23
... ...
... ... @@ -24,7 +24,7 @@ import org.apache.kafka.clients.consumer.ConsumerRecords;
24 24 import org.apache.kafka.clients.consumer.KafkaConsumer;
25 25 import org.thingsboard.server.queue.TbQueueConsumer;
26 26 import org.thingsboard.server.queue.TbQueueMsg;
27   -import org.thingsboard.server.queue.discovery.TopicPartitionInfo;
  27 +import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
28 28
29 29 import java.io.IOException;
30 30 import java.time.Duration;
... ...
... ... @@ -27,7 +27,7 @@ import org.springframework.util.StringUtils;
27 27 import org.thingsboard.server.queue.TbQueueCallback;
28 28 import org.thingsboard.server.queue.TbQueueMsg;
29 29 import org.thingsboard.server.queue.TbQueueProducer;
30   -import org.thingsboard.server.queue.discovery.TopicPartitionInfo;
  30 +import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
31 31
32 32 import java.util.Properties;
33 33 import java.util.stream.Collectors;
... ...
... ... @@ -17,7 +17,7 @@ package org.thingsboard.server.queue.memory;
17 17
18 18 import org.thingsboard.server.queue.TbQueueConsumer;
19 19 import org.thingsboard.server.queue.TbQueueMsg;
20   -import org.thingsboard.server.queue.discovery.TopicPartitionInfo;
  20 +import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
21 21
22 22 import java.util.List;
23 23 import java.util.Set;
... ...
... ... @@ -19,7 +19,7 @@ import lombok.Data;
19 19 import org.thingsboard.server.queue.TbQueueCallback;
20 20 import org.thingsboard.server.queue.TbQueueMsg;
21 21 import org.thingsboard.server.queue.TbQueueProducer;
22   -import org.thingsboard.server.queue.discovery.TopicPartitionInfo;
  22 +import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
23 23
24 24 @Data
25 25 public class InMemoryTbQueueProducer<T extends TbQueueMsg> implements TbQueueProducer<T> {
... ...
... ... @@ -18,6 +18,13 @@ package org.thingsboard.server.queue.provider;
18 18 import lombok.extern.slf4j.Slf4j;
19 19 import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
20 20 import org.springframework.stereotype.Component;
  21 +import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
  22 +import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
  23 +import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
  24 +import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg;
  25 +import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
  26 +import org.thingsboard.server.gen.transport.TransportProtos.TransportApiRequestMsg;
  27 +import org.thingsboard.server.gen.transport.TransportProtos.TransportApiResponseMsg;
21 28 import org.thingsboard.server.queue.TbQueueConsumer;
22 29 import org.thingsboard.server.queue.TbQueueCoreSettings;
23 30 import org.thingsboard.server.queue.TbQueueProducer;
... ... @@ -25,11 +32,6 @@ import org.thingsboard.server.queue.TbQueueRuleEngineSettings;
25 32 import org.thingsboard.server.queue.TbQueueTransportApiSettings;
26 33 import org.thingsboard.server.queue.TbQueueTransportNotificationSettings;
27 34 import org.thingsboard.server.queue.common.TbProtoQueueMsg;
28   -import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
29   -import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
30   -import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
31   -import org.thingsboard.server.gen.transport.TransportProtos.TransportApiRequestMsg;
32   -import org.thingsboard.server.gen.transport.TransportProtos.TransportApiResponseMsg;
33 35 import org.thingsboard.server.queue.memory.InMemoryTbQueueConsumer;
34 36 import org.thingsboard.server.queue.memory.InMemoryTbQueueProducer;
35 37
... ... @@ -87,4 +89,24 @@ public class InMemoryMonolithQueueProvider implements TbCoreQueueProvider, TbRul
87 89 public TbQueueProducer<TbProtoQueueMsg<TransportApiResponseMsg>> getTransportApiResponseProducer() {
88 90 return new InMemoryTbQueueProducer<>(transportApiSettings.getResponsesTopic());
89 91 }
  92 +
  93 + @Override
  94 + public TbQueueProducer<TbProtoQueueMsg<ToRuleEngineNotificationMsg>> getRuleEngineNotificationsMsgProducer() {
  95 + return new InMemoryTbQueueProducer<>(ruleEngineSettings.getTopic() + ".notifications");
  96 + }
  97 +
  98 + @Override
  99 + public TbQueueProducer<TbProtoQueueMsg<ToCoreNotificationMsg>> getTbCoreNotificationsMsgProducer() {
  100 + return new InMemoryTbQueueProducer<>(coreSettings.getTopic() + ".notifications");
  101 + }
  102 +
  103 + @Override
  104 + public TbQueueConsumer<TbProtoQueueMsg<ToCoreNotificationMsg>> getToCoreNotificationsMsgConsumer() {
  105 + return new InMemoryTbQueueConsumer<>(coreSettings.getTopic() + ".notifications");
  106 + }
  107 +
  108 + @Override
  109 + public TbQueueConsumer<TbProtoQueueMsg<ToRuleEngineNotificationMsg>> getToRuleEngineNotificationsMsgConsumer() {
  110 + return new InMemoryTbQueueConsumer<>(ruleEngineSettings.getTopic() + ".notifications");
  111 + }
90 112 }
... ...
common/queue/src/main/java/org/thingsboard/server/queue/provider/InMemoryTbTransportQueueProvider.java renamed from common/queue/src/main/java/org/thingsboard/server/queue/provider/InMemoryTransportQueueProvider.java
... ... @@ -39,17 +39,17 @@ import org.thingsboard.server.queue.memory.InMemoryTbQueueProducer;
39 39 @Component
40 40 @ConditionalOnExpression("'${queue.type:null}'=='in-memory' && ('${service.type:null}'=='monolith' || '${service.type:null}'=='tb-transport')")
41 41 @Slf4j
42   -public class InMemoryTransportQueueProvider implements TransportQueueProvider {
  42 +public class InMemoryTbTransportQueueProvider implements TbTransportQueueProvider {
43 43
44 44 private final TbQueueCoreSettings coreSettings;
45 45 private final TbQueueRuleEngineSettings ruleEngineSettings;
46 46 private final TbQueueTransportApiSettings transportApiSettings;
47 47 private final TbQueueTransportNotificationSettings notificationSettings;
48 48
49   - public InMemoryTransportQueueProvider(TbQueueCoreSettings coreSettings,
50   - TbQueueRuleEngineSettings ruleEngineSettings,
51   - TbQueueTransportApiSettings transportApiSettings,
52   - TbQueueTransportNotificationSettings notificationSettings) {
  49 + public InMemoryTbTransportQueueProvider(TbQueueCoreSettings coreSettings,
  50 + TbQueueRuleEngineSettings ruleEngineSettings,
  51 + TbQueueTransportApiSettings transportApiSettings,
  52 + TbQueueTransportNotificationSettings notificationSettings) {
53 53 this.coreSettings = coreSettings;
54 54 this.ruleEngineSettings = ruleEngineSettings;
55 55 this.transportApiSettings = transportApiSettings;
... ...
... ... @@ -17,8 +17,11 @@ package org.thingsboard.server.queue.provider;
17 17
18 18 import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
19 19 import org.springframework.stereotype.Component;
  20 +import org.thingsboard.server.common.msg.queue.ServiceType;
20 21 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
  22 +import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
21 23 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
  24 +import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg;
22 25 import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
23 26 import org.thingsboard.server.gen.transport.TransportProtos.TransportApiRequestMsg;
24 27 import org.thingsboard.server.gen.transport.TransportProtos.TransportApiResponseMsg;
... ... @@ -29,6 +32,7 @@ import org.thingsboard.server.queue.TbQueueRuleEngineSettings;
29 32 import org.thingsboard.server.queue.TbQueueTransportApiSettings;
30 33 import org.thingsboard.server.queue.TbQueueTransportNotificationSettings;
31 34 import org.thingsboard.server.queue.common.TbProtoQueueMsg;
  35 +import org.thingsboard.server.queue.discovery.PartitionService;
32 36 import org.thingsboard.server.queue.discovery.TbServiceInfoProvider;
33 37 import org.thingsboard.server.queue.kafka.TBKafkaConsumerTemplate;
34 38 import org.thingsboard.server.queue.kafka.TBKafkaProducerTemplate;
... ... @@ -38,6 +42,7 @@ import org.thingsboard.server.queue.kafka.TbKafkaSettings;
38 42 @ConditionalOnExpression("'${queue.type:null}'=='kafka' && '${service.type:null}'=='monolith'")
39 43 public class KafkaMonolithQueueProvider implements TbCoreQueueProvider, TbRuleEngineQueueProvider {
40 44
  45 + private final PartitionService partitionService;
41 46 private final TbKafkaSettings kafkaSettings;
42 47 private final TbServiceInfoProvider serviceInfoProvider;
43 48 private final TbQueueCoreSettings coreSettings;
... ... @@ -45,14 +50,13 @@ public class KafkaMonolithQueueProvider implements TbCoreQueueProvider, TbRuleEn
45 50 private final TbQueueTransportApiSettings transportApiSettings;
46 51 private final TbQueueTransportNotificationSettings transportNotificationSettings;
47 52
48   - private TbQueueProducer<TbProtoQueueMsg<ToCoreMsg>> tbCoreProducer;
49   -
50   - public KafkaMonolithQueueProvider(TbKafkaSettings kafkaSettings,
  53 + public KafkaMonolithQueueProvider(PartitionService partitionService, TbKafkaSettings kafkaSettings,
51 54 TbServiceInfoProvider serviceInfoProvider,
52 55 TbQueueCoreSettings coreSettings,
53 56 TbQueueRuleEngineSettings ruleEngineSettings,
54 57 TbQueueTransportApiSettings transportApiSettings,
55 58 TbQueueTransportNotificationSettings transportNotificationSettings) {
  59 + this.partitionService = partitionService;
56 60 this.kafkaSettings = kafkaSettings;
57 61 this.serviceInfoProvider = serviceInfoProvider;
58 62 this.coreSettings = coreSettings;
... ... @@ -79,21 +83,31 @@ public class KafkaMonolithQueueProvider implements TbCoreQueueProvider, TbRuleEn
79 83 return requestBuilder.build();
80 84 }
81 85
82   - //TODO 2.5 Singleton
  86 + @Override
  87 + public TbQueueProducer<TbProtoQueueMsg<ToRuleEngineNotificationMsg>> getRuleEngineNotificationsMsgProducer() {
  88 + TBKafkaProducerTemplate.TBKafkaProducerTemplateBuilder<TbProtoQueueMsg<ToRuleEngineNotificationMsg>> requestBuilder = TBKafkaProducerTemplate.builder();
  89 + requestBuilder.settings(kafkaSettings);
  90 + requestBuilder.clientId("monolith-rule-engine-notifications-" + serviceInfoProvider.getServiceId());
  91 + requestBuilder.defaultTopic(ruleEngineSettings.getTopic());
  92 + return requestBuilder.build();
  93 + }
  94 +
83 95 @Override
84 96 public TbQueueProducer<TbProtoQueueMsg<ToCoreMsg>> getTbCoreMsgProducer() {
85   - if (tbCoreProducer == null) {
86   - synchronized (this) {
87   - if (tbCoreProducer == null) {
88   - TBKafkaProducerTemplate.TBKafkaProducerTemplateBuilder<TbProtoQueueMsg<ToCoreMsg>> requestBuilder = TBKafkaProducerTemplate.builder();
89   - requestBuilder.settings(kafkaSettings);
90   - requestBuilder.clientId("monolith-core-" + serviceInfoProvider.getServiceId());
91   - requestBuilder.defaultTopic(coreSettings.getTopic());
92   - tbCoreProducer = requestBuilder.build();
93   - }
94   - }
95   - }
96   - return tbCoreProducer;
  97 + TBKafkaProducerTemplate.TBKafkaProducerTemplateBuilder<TbProtoQueueMsg<ToCoreMsg>> requestBuilder = TBKafkaProducerTemplate.builder();
  98 + requestBuilder.settings(kafkaSettings);
  99 + requestBuilder.clientId("monolith-core-" + serviceInfoProvider.getServiceId());
  100 + requestBuilder.defaultTopic(coreSettings.getTopic());
  101 + return requestBuilder.build();
  102 + }
  103 +
  104 + @Override
  105 + public TbQueueProducer<TbProtoQueueMsg<ToCoreNotificationMsg>> getTbCoreNotificationsMsgProducer() {
  106 + TBKafkaProducerTemplate.TBKafkaProducerTemplateBuilder<TbProtoQueueMsg<ToCoreNotificationMsg>> requestBuilder = TBKafkaProducerTemplate.builder();
  107 + requestBuilder.settings(kafkaSettings);
  108 + requestBuilder.clientId("monolith-core-notifications-" + serviceInfoProvider.getServiceId());
  109 + requestBuilder.defaultTopic(coreSettings.getTopic());
  110 + return requestBuilder.build();
97 111 }
98 112
99 113 @Override
... ... @@ -108,6 +122,17 @@ public class KafkaMonolithQueueProvider implements TbCoreQueueProvider, TbRuleEn
108 122 }
109 123
110 124 @Override
  125 + public TbQueueConsumer<TbProtoQueueMsg<ToRuleEngineNotificationMsg>> getToRuleEngineNotificationsMsgConsumer() {
  126 + TBKafkaConsumerTemplate.TBKafkaConsumerTemplateBuilder<TbProtoQueueMsg<ToRuleEngineNotificationMsg>> consumerBuilder = TBKafkaConsumerTemplate.builder();
  127 + consumerBuilder.settings(kafkaSettings);
  128 + consumerBuilder.topic(partitionService.getNotificationsTopic(ServiceType.TB_RULE_ENGINE, serviceInfoProvider.getServiceId()).getFullTopicName());
  129 + consumerBuilder.clientId("monolith-rule-engine-notifications-consumer-" + serviceInfoProvider.getServiceId());
  130 + consumerBuilder.groupId("monolith-rule-engine-notifications-consumer-" + serviceInfoProvider.getServiceId());
  131 + consumerBuilder.decoder(msg -> new TbProtoQueueMsg<>(msg.getKey(), ToRuleEngineNotificationMsg.parseFrom(msg.getData()), msg.getHeaders()));
  132 + return consumerBuilder.build();
  133 + }
  134 +
  135 + @Override
111 136 public TbQueueConsumer<TbProtoQueueMsg<ToCoreMsg>> getToCoreMsgConsumer() {
112 137 TBKafkaConsumerTemplate.TBKafkaConsumerTemplateBuilder<TbProtoQueueMsg<ToCoreMsg>> consumerBuilder = TBKafkaConsumerTemplate.builder();
113 138 consumerBuilder.settings(kafkaSettings);
... ... @@ -119,6 +144,17 @@ public class KafkaMonolithQueueProvider implements TbCoreQueueProvider, TbRuleEn
119 144 }
120 145
121 146 @Override
  147 + public TbQueueConsumer<TbProtoQueueMsg<ToCoreNotificationMsg>> getToCoreNotificationsMsgConsumer() {
  148 + TBKafkaConsumerTemplate.TBKafkaConsumerTemplateBuilder<TbProtoQueueMsg<ToCoreNotificationMsg>> consumerBuilder = TBKafkaConsumerTemplate.builder();
  149 + consumerBuilder.settings(kafkaSettings);
  150 + consumerBuilder.topic(partitionService.getNotificationsTopic(ServiceType.TB_CORE, serviceInfoProvider.getServiceId()).getFullTopicName());
  151 + consumerBuilder.clientId("monolith-core-notifications-consumer-" + serviceInfoProvider.getServiceId());
  152 + consumerBuilder.groupId("monolith-core-notifications-consumer-" + serviceInfoProvider.getServiceId());
  153 + consumerBuilder.decoder(msg -> new TbProtoQueueMsg<>(msg.getKey(), ToCoreNotificationMsg.parseFrom(msg.getData()), msg.getHeaders()));
  154 + return consumerBuilder.build();
  155 + }
  156 +
  157 + @Override
122 158 public TbQueueConsumer<TbProtoQueueMsg<TransportApiRequestMsg>> getTransportApiRequestConsumer() {
123 159 TBKafkaConsumerTemplate.TBKafkaConsumerTemplateBuilder<TbProtoQueueMsg<TransportApiRequestMsg>> consumerBuilder = TBKafkaConsumerTemplate.builder();
124 160 consumerBuilder.settings(kafkaSettings);
... ...
... ... @@ -17,6 +17,14 @@ package org.thingsboard.server.queue.provider;
17 17
18 18 import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
19 19 import org.springframework.stereotype.Component;
  20 +import org.thingsboard.server.common.msg.queue.ServiceType;
  21 +import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
  22 +import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
  23 +import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
  24 +import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg;
  25 +import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
  26 +import org.thingsboard.server.gen.transport.TransportProtos.TransportApiRequestMsg;
  27 +import org.thingsboard.server.gen.transport.TransportProtos.TransportApiResponseMsg;
20 28 import org.thingsboard.server.queue.TbQueueConsumer;
21 29 import org.thingsboard.server.queue.TbQueueCoreSettings;
22 30 import org.thingsboard.server.queue.TbQueueProducer;
... ... @@ -24,11 +32,7 @@ import org.thingsboard.server.queue.TbQueueRuleEngineSettings;
24 32 import org.thingsboard.server.queue.TbQueueTransportApiSettings;
25 33 import org.thingsboard.server.queue.TbQueueTransportNotificationSettings;
26 34 import org.thingsboard.server.queue.common.TbProtoQueueMsg;
27   -import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
28   -import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
29   -import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
30   -import org.thingsboard.server.gen.transport.TransportProtos.TransportApiRequestMsg;
31   -import org.thingsboard.server.gen.transport.TransportProtos.TransportApiResponseMsg;
  35 +import org.thingsboard.server.queue.discovery.PartitionService;
32 36 import org.thingsboard.server.queue.discovery.TbServiceInfoProvider;
33 37 import org.thingsboard.server.queue.kafka.TBKafkaConsumerTemplate;
34 38 import org.thingsboard.server.queue.kafka.TBKafkaProducerTemplate;
... ... @@ -38,6 +42,7 @@ import org.thingsboard.server.queue.kafka.TbKafkaSettings;
38 42 @ConditionalOnExpression("'${queue.type:null}'=='kafka' && '${service.type:null}'=='tb-core'")
39 43 public class KafkaTbCoreQueueProvider implements TbCoreQueueProvider {
40 44
  45 + private final PartitionService partitionService;
41 46 private final TbKafkaSettings kafkaSettings;
42 47 private final TbServiceInfoProvider serviceInfoProvider;
43 48 private final TbQueueCoreSettings coreSettings;
... ... @@ -45,14 +50,13 @@ public class KafkaTbCoreQueueProvider implements TbCoreQueueProvider {
45 50 private final TbQueueTransportApiSettings transportApiSettings;
46 51 private final TbQueueTransportNotificationSettings transportNotificationSettings;
47 52
48   - private TbQueueProducer<TbProtoQueueMsg<ToCoreMsg>> tbCoreProducer;
49   -
50   - public KafkaTbCoreQueueProvider(TbKafkaSettings kafkaSettings,
51   - TbServiceInfoProvider serviceInfoProvider,
52   - TbQueueCoreSettings coreSettings,
53   - TbQueueRuleEngineSettings ruleEngineSettings,
54   - TbQueueTransportApiSettings transportApiSettings,
55   - TbQueueTransportNotificationSettings transportNotificationSettings) {
  53 + public KafkaTbCoreQueueProvider(PartitionService partitionService, TbKafkaSettings kafkaSettings,
  54 + TbServiceInfoProvider serviceInfoProvider,
  55 + TbQueueCoreSettings coreSettings,
  56 + TbQueueRuleEngineSettings ruleEngineSettings,
  57 + TbQueueTransportApiSettings transportApiSettings,
  58 + TbQueueTransportNotificationSettings transportNotificationSettings) {
  59 + this.partitionService = partitionService;
56 60 this.kafkaSettings = kafkaSettings;
57 61 this.serviceInfoProvider = serviceInfoProvider;
58 62 this.coreSettings = coreSettings;
... ... @@ -80,19 +84,30 @@ public class KafkaTbCoreQueueProvider implements TbCoreQueueProvider {
80 84 }
81 85
82 86 @Override
  87 + public TbQueueProducer<TbProtoQueueMsg<ToRuleEngineNotificationMsg>> getRuleEngineNotificationsMsgProducer() {
  88 + TBKafkaProducerTemplate.TBKafkaProducerTemplateBuilder<TbProtoQueueMsg<ToRuleEngineNotificationMsg>> requestBuilder = TBKafkaProducerTemplate.builder();
  89 + requestBuilder.settings(kafkaSettings);
  90 + requestBuilder.clientId("tb-core-rule-engine-notifications-" + serviceInfoProvider.getServiceId());
  91 + requestBuilder.defaultTopic(ruleEngineSettings.getTopic());
  92 + return requestBuilder.build();
  93 + }
  94 +
  95 + @Override
83 96 public TbQueueProducer<TbProtoQueueMsg<ToCoreMsg>> getTbCoreMsgProducer() {
84   - if (tbCoreProducer == null) {
85   - synchronized (this) {
86   - if (tbCoreProducer == null) {
87   - TBKafkaProducerTemplate.TBKafkaProducerTemplateBuilder<TbProtoQueueMsg<ToCoreMsg>> requestBuilder = TBKafkaProducerTemplate.builder();
88   - requestBuilder.settings(kafkaSettings);
89   - requestBuilder.clientId("tb-core-to-core-" + serviceInfoProvider.getServiceId());
90   - requestBuilder.defaultTopic(coreSettings.getTopic());
91   - tbCoreProducer = requestBuilder.build();
92   - }
93   - }
94   - }
95   - return tbCoreProducer;
  97 + TBKafkaProducerTemplate.TBKafkaProducerTemplateBuilder<TbProtoQueueMsg<ToCoreMsg>> requestBuilder = TBKafkaProducerTemplate.builder();
  98 + requestBuilder.settings(kafkaSettings);
  99 + requestBuilder.clientId("tb-core-to-core-" + serviceInfoProvider.getServiceId());
  100 + requestBuilder.defaultTopic(coreSettings.getTopic());
  101 + return requestBuilder.build();
  102 + }
  103 +
  104 + @Override
  105 + public TbQueueProducer<TbProtoQueueMsg<ToCoreNotificationMsg>> getTbCoreNotificationsMsgProducer() {
  106 + TBKafkaProducerTemplate.TBKafkaProducerTemplateBuilder<TbProtoQueueMsg<ToCoreNotificationMsg>> requestBuilder = TBKafkaProducerTemplate.builder();
  107 + requestBuilder.settings(kafkaSettings);
  108 + requestBuilder.clientId("tb-core-to-core-notifications-" + serviceInfoProvider.getServiceId());
  109 + requestBuilder.defaultTopic(coreSettings.getTopic());
  110 + return requestBuilder.build();
96 111 }
97 112
98 113 @Override
... ... @@ -107,6 +122,17 @@ public class KafkaTbCoreQueueProvider implements TbCoreQueueProvider {
107 122 }
108 123
109 124 @Override
  125 + public TbQueueConsumer<TbProtoQueueMsg<ToCoreNotificationMsg>> getToCoreNotificationsMsgConsumer() {
  126 + TBKafkaConsumerTemplate.TBKafkaConsumerTemplateBuilder<TbProtoQueueMsg<ToCoreNotificationMsg>> consumerBuilder = TBKafkaConsumerTemplate.builder();
  127 + consumerBuilder.settings(kafkaSettings);
  128 + consumerBuilder.topic(partitionService.getNotificationsTopic(ServiceType.TB_CORE, serviceInfoProvider.getServiceId()).getFullTopicName());
  129 + consumerBuilder.clientId("tb-core-notifications-consumer-" + serviceInfoProvider.getServiceId());
  130 + consumerBuilder.groupId("tb-core-notifications-node-" + serviceInfoProvider.getServiceId());
  131 + consumerBuilder.decoder(msg -> new TbProtoQueueMsg<>(msg.getKey(), ToCoreNotificationMsg.parseFrom(msg.getData()), msg.getHeaders()));
  132 + return consumerBuilder.build();
  133 + }
  134 +
  135 + @Override
110 136 public TbQueueConsumer<TbProtoQueueMsg<TransportApiRequestMsg>> getTransportApiRequestConsumer() {
111 137 TBKafkaConsumerTemplate.TBKafkaConsumerTemplateBuilder<TbProtoQueueMsg<TransportApiRequestMsg>> consumerBuilder = TBKafkaConsumerTemplate.builder();
112 138 consumerBuilder.settings(kafkaSettings);
... ... @@ -125,4 +151,5 @@ public class KafkaTbCoreQueueProvider implements TbCoreQueueProvider {
125 151 requestBuilder.defaultTopic(coreSettings.getTopic());
126 152 return requestBuilder.build();
127 153 }
  154 +
128 155 }
... ...
... ... @@ -17,6 +17,12 @@ package org.thingsboard.server.queue.provider;
17 17
18 18 import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
19 19 import org.springframework.stereotype.Component;
  20 +import org.thingsboard.server.common.msg.queue.ServiceType;
  21 +import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
  22 +import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
  23 +import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
  24 +import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg;
  25 +import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
20 26 import org.thingsboard.server.queue.TbQueueConsumer;
21 27 import org.thingsboard.server.queue.TbQueueCoreSettings;
22 28 import org.thingsboard.server.queue.TbQueueProducer;
... ... @@ -24,9 +30,7 @@ import org.thingsboard.server.queue.TbQueueRuleEngineSettings;
24 30 import org.thingsboard.server.queue.TbQueueTransportApiSettings;
25 31 import org.thingsboard.server.queue.TbQueueTransportNotificationSettings;
26 32 import org.thingsboard.server.queue.common.TbProtoQueueMsg;
27   -import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
28   -import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
29   -import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
  33 +import org.thingsboard.server.queue.discovery.PartitionService;
30 34 import org.thingsboard.server.queue.discovery.TbServiceInfoProvider;
31 35 import org.thingsboard.server.queue.kafka.TBKafkaConsumerTemplate;
32 36 import org.thingsboard.server.queue.kafka.TBKafkaProducerTemplate;
... ... @@ -36,6 +40,7 @@ import org.thingsboard.server.queue.kafka.TbKafkaSettings;
36 40 @ConditionalOnExpression("'${queue.type:null}'=='kafka' && '${service.type:null}'=='tb-rule-engine'")
37 41 public class KafkaTbRuleEngineQueueProvider implements TbRuleEngineQueueProvider {
38 42
  43 + private final PartitionService partitionService;
39 44 private final TbKafkaSettings kafkaSettings;
40 45 private final TbServiceInfoProvider serviceInfoProvider;
41 46 private final TbQueueCoreSettings coreSettings;
... ... @@ -43,12 +48,13 @@ public class KafkaTbRuleEngineQueueProvider implements TbRuleEngineQueueProvider
43 48 private final TbQueueTransportApiSettings transportApiSettings;
44 49 private final TbQueueTransportNotificationSettings transportNotificationSettings;
45 50
46   - public KafkaTbRuleEngineQueueProvider(TbKafkaSettings kafkaSettings,
47   - TbServiceInfoProvider serviceInfoProvider,
48   - TbQueueCoreSettings coreSettings,
49   - TbQueueRuleEngineSettings ruleEngineSettings,
50   - TbQueueTransportApiSettings transportApiSettings,
51   - TbQueueTransportNotificationSettings transportNotificationSettings) {
  51 + public KafkaTbRuleEngineQueueProvider(PartitionService partitionService, TbKafkaSettings kafkaSettings,
  52 + TbServiceInfoProvider serviceInfoProvider,
  53 + TbQueueCoreSettings coreSettings,
  54 + TbQueueRuleEngineSettings ruleEngineSettings,
  55 + TbQueueTransportApiSettings transportApiSettings,
  56 + TbQueueTransportNotificationSettings transportNotificationSettings) {
  57 + this.partitionService = partitionService;
52 58 this.kafkaSettings = kafkaSettings;
53 59 this.serviceInfoProvider = serviceInfoProvider;
54 60 this.coreSettings = coreSettings;
... ... @@ -56,6 +62,7 @@ public class KafkaTbRuleEngineQueueProvider implements TbRuleEngineQueueProvider
56 62 this.transportApiSettings = transportApiSettings;
57 63 this.transportNotificationSettings = transportNotificationSettings;
58 64 }
  65 +
59 66 @Override
60 67 public TbQueueProducer<TbProtoQueueMsg<ToTransportMsg>> getTransportNotificationsMsgProducer() {
61 68 TBKafkaProducerTemplate.TBKafkaProducerTemplateBuilder<TbProtoQueueMsg<ToTransportMsg>> requestBuilder = TBKafkaProducerTemplate.builder();
... ... @@ -73,6 +80,17 @@ public class KafkaTbRuleEngineQueueProvider implements TbRuleEngineQueueProvider
73 80 requestBuilder.defaultTopic(coreSettings.getTopic());
74 81 return requestBuilder.build();
75 82 }
  83 +
  84 + @Override
  85 + public TbQueueProducer<TbProtoQueueMsg<ToRuleEngineNotificationMsg>> getRuleEngineNotificationsMsgProducer() {
  86 + TBKafkaProducerTemplate.TBKafkaProducerTemplateBuilder<TbProtoQueueMsg<ToRuleEngineNotificationMsg>> requestBuilder = TBKafkaProducerTemplate.builder();
  87 + requestBuilder.settings(kafkaSettings);
  88 + requestBuilder.clientId("tb-rule-engine-to-rule-engine-notifications-" + serviceInfoProvider.getServiceId());
  89 + requestBuilder.defaultTopic(ruleEngineSettings.getTopic());
  90 + return requestBuilder.build();
  91 + }
  92 +
  93 +
76 94 @Override
77 95 public TbQueueProducer<TbProtoQueueMsg<ToCoreMsg>> getTbCoreMsgProducer() {
78 96 TBKafkaProducerTemplate.TBKafkaProducerTemplateBuilder<TbProtoQueueMsg<ToCoreMsg>> requestBuilder = TBKafkaProducerTemplate.builder();
... ... @@ -83,13 +101,33 @@ public class KafkaTbRuleEngineQueueProvider implements TbRuleEngineQueueProvider
83 101 }
84 102
85 103 @Override
  104 + public TbQueueProducer<TbProtoQueueMsg<ToCoreNotificationMsg>> getTbCoreNotificationsMsgProducer() {
  105 + TBKafkaProducerTemplate.TBKafkaProducerTemplateBuilder<TbProtoQueueMsg<ToCoreNotificationMsg>> requestBuilder = TBKafkaProducerTemplate.builder();
  106 + requestBuilder.settings(kafkaSettings);
  107 + requestBuilder.clientId("tb-rule-engine-to-core-notifications-" + serviceInfoProvider.getServiceId());
  108 + requestBuilder.defaultTopic(coreSettings.getTopic());
  109 + return requestBuilder.build();
  110 + }
  111 +
  112 + @Override
86 113 public TbQueueConsumer<TbProtoQueueMsg<ToRuleEngineMsg>> getToRuleEngineMsgConsumer() {
87 114 TBKafkaConsumerTemplate.TBKafkaConsumerTemplateBuilder<TbProtoQueueMsg<ToRuleEngineMsg>> consumerBuilder = TBKafkaConsumerTemplate.builder();
88 115 consumerBuilder.settings(kafkaSettings);
89 116 consumerBuilder.topic(ruleEngineSettings.getTopic());
90   - consumerBuilder.clientId("tb-rule-engine-rule-engine-consumer-" + serviceInfoProvider.getServiceId());
91   - consumerBuilder.groupId("tb-rule-engine-rule-engine-consumer-" + serviceInfoProvider.getServiceId());
  117 + consumerBuilder.clientId("tb-rule-engine-consumer-" + serviceInfoProvider.getServiceId());
  118 + consumerBuilder.groupId("tb-rule-engine-node-" + serviceInfoProvider.getServiceId());
92 119 consumerBuilder.decoder(msg -> new TbProtoQueueMsg<>(msg.getKey(), ToRuleEngineMsg.parseFrom(msg.getData()), msg.getHeaders()));
93 120 return consumerBuilder.build();
94 121 }
  122 +
  123 + @Override
  124 + public TbQueueConsumer<TbProtoQueueMsg<ToRuleEngineNotificationMsg>> getToRuleEngineNotificationsMsgConsumer() {
  125 + TBKafkaConsumerTemplate.TBKafkaConsumerTemplateBuilder<TbProtoQueueMsg<ToRuleEngineNotificationMsg>> consumerBuilder = TBKafkaConsumerTemplate.builder();
  126 + consumerBuilder.settings(kafkaSettings);
  127 + consumerBuilder.topic(partitionService.getNotificationsTopic(ServiceType.TB_RULE_ENGINE, serviceInfoProvider.getServiceId()).getFullTopicName());
  128 + consumerBuilder.clientId("tb-rule-engine-notifications-consumer-" + serviceInfoProvider.getServiceId());
  129 + consumerBuilder.groupId("tb-rule-engine-notifications-node-" + serviceInfoProvider.getServiceId());
  130 + consumerBuilder.decoder(msg -> new TbProtoQueueMsg<>(msg.getKey(), ToRuleEngineNotificationMsg.parseFrom(msg.getData()), msg.getHeaders()));
  131 + return consumerBuilder.build();
  132 + }
95 133 }
... ...
common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbTransportQueueProvider.java renamed from common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTransportQueueProvider.java
... ... @@ -41,7 +41,7 @@ import org.thingsboard.server.queue.kafka.TbKafkaSettings;
41 41 @Component
42 42 @ConditionalOnExpression("'${queue.type:null}'=='kafka' && ('${service.type:null}'=='monolith' || '${service.type:null}'=='tb-transport')")
43 43 @Slf4j
44   -public class KafkaTransportQueueProvider implements TransportQueueProvider {
  44 +public class KafkaTbTransportQueueProvider implements TbTransportQueueProvider {
45 45
46 46 private final TbKafkaSettings kafkaSettings;
47 47 private final TbServiceInfoProvider serviceInfoProvider;
... ... @@ -50,12 +50,12 @@ public class KafkaTransportQueueProvider implements TransportQueueProvider {
50 50 private final TbQueueTransportApiSettings transportApiSettings;
51 51 private final TbQueueTransportNotificationSettings transportNotificationSettings;
52 52
53   - public KafkaTransportQueueProvider(TbKafkaSettings kafkaSettings,
54   - TbServiceInfoProvider serviceInfoProvider,
55   - TbQueueCoreSettings coreSettings,
56   - TbQueueRuleEngineSettings ruleEngineSettings,
57   - TbQueueTransportApiSettings transportApiSettings,
58   - TbQueueTransportNotificationSettings transportNotificationSettings) {
  53 + public KafkaTbTransportQueueProvider(TbKafkaSettings kafkaSettings,
  54 + TbServiceInfoProvider serviceInfoProvider,
  55 + TbQueueCoreSettings coreSettings,
  56 + TbQueueRuleEngineSettings ruleEngineSettings,
  57 + TbQueueTransportApiSettings transportApiSettings,
  58 + TbQueueTransportNotificationSettings transportNotificationSettings) {
59 59 this.kafkaSettings = kafkaSettings;
60 60 this.serviceInfoProvider = serviceInfoProvider;
61 61 this.coreSettings = coreSettings;
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.queue.provider;
  17 +
  18 +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
  19 +import org.springframework.stereotype.Service;
  20 +import org.thingsboard.server.gen.transport.TransportProtos;
  21 +import org.thingsboard.server.queue.TbQueueProducer;
  22 +import org.thingsboard.server.queue.common.TbProtoQueueMsg;
  23 +
  24 +import javax.annotation.PostConstruct;
  25 +
  26 +@Service
  27 +@ConditionalOnExpression("'${service.type:null}'=='monolith' || '${service.type:null}'=='tb-core'")
  28 +public class TbCoreQueueProducerProvider implements TbQueueProducerProvider {
  29 +
  30 + private final TbCoreQueueProvider tbQueueProvider;
  31 + private TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToTransportMsg>> toTransport;
  32 + private TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> toRuleEngine;
  33 + private TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToCoreMsg>> toTbCore;
  34 + private TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToRuleEngineNotificationMsg>> toRuleEngineNotifications;
  35 + private TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToCoreNotificationMsg>> toTbCoreNotifications;
  36 +
  37 + public TbCoreQueueProducerProvider(TbCoreQueueProvider tbQueueProvider) {
  38 + this.tbQueueProvider = tbQueueProvider;
  39 + }
  40 +
  41 + @PostConstruct
  42 + public void init() {
  43 + this.toTbCore = tbQueueProvider.getTbCoreMsgProducer();
  44 + this.toTransport = tbQueueProvider.getTransportNotificationsMsgProducer();
  45 + this.toRuleEngine = tbQueueProvider.getRuleEngineMsgProducer();
  46 + this.toRuleEngineNotifications = tbQueueProvider.getRuleEngineNotificationsMsgProducer();
  47 + this.toTbCoreNotifications = tbQueueProvider.getTbCoreNotificationsMsgProducer();
  48 + }
  49 +
  50 + @Override
  51 + public TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToTransportMsg>> getTransportNotificationsMsgProducer() {
  52 + return toTransport;
  53 + }
  54 +
  55 + @Override
  56 + public TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> getRuleEngineMsgProducer() {
  57 + return toRuleEngine;
  58 + }
  59 +
  60 + @Override
  61 + public TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToRuleEngineNotificationMsg>> getRuleEngineNotificationsMsgProducer() {
  62 + return toRuleEngineNotifications;
  63 + }
  64 +
  65 + @Override
  66 + public TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToCoreMsg>> getTbCoreMsgProducer() {
  67 + return toTbCore;
  68 + }
  69 +
  70 + @Override
  71 + public TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToCoreNotificationMsg>> getTbCoreNotificationsMsgProducer() {
  72 + return toTbCoreNotifications;
  73 + }
  74 +}
... ...
... ... @@ -15,6 +15,7 @@
15 15 */
16 16 package org.thingsboard.server.queue.provider;
17 17
  18 +import org.thingsboard.server.gen.transport.TransportProtos;
18 19 import org.thingsboard.server.queue.TbQueueConsumer;
19 20 import org.thingsboard.server.queue.TbQueueProducer;
20 21 import org.thingsboard.server.queue.common.TbProtoQueueMsg;
... ... @@ -45,6 +46,13 @@ public interface TbCoreQueueProvider {
45 46 TbQueueProducer<TbProtoQueueMsg<ToRuleEngineMsg>> getRuleEngineMsgProducer();
46 47
47 48 /**
  49 + * Used to push notifications to instances of TB RuleEngine Service
  50 + *
  51 + * @return
  52 + */
  53 + TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToRuleEngineNotificationMsg>> getRuleEngineNotificationsMsgProducer();
  54 +
  55 + /**
48 56 * Used to push messages to other instances of TB Core Service
49 57 *
50 58 * @return
... ... @@ -52,6 +60,13 @@ public interface TbCoreQueueProvider {
52 60 TbQueueProducer<TbProtoQueueMsg<ToCoreMsg>> getTbCoreMsgProducer();
53 61
54 62 /**
  63 + * Used to push notifications to other instances of TB Core Service
  64 + *
  65 + * @return
  66 + */
  67 + TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToCoreNotificationMsg>> getTbCoreNotificationsMsgProducer();
  68 +
  69 + /**
55 70 * Used to consume messages by TB Core Service
56 71 *
57 72 * @return
... ... @@ -59,6 +74,13 @@ public interface TbCoreQueueProvider {
59 74 TbQueueConsumer<TbProtoQueueMsg<ToCoreMsg>> getToCoreMsgConsumer();
60 75
61 76 /**
  77 + * Used to consume high priority messages by TB Core Service
  78 + *
  79 + * @return
  80 + */
  81 + TbQueueConsumer<TbProtoQueueMsg<TransportProtos.ToCoreNotificationMsg>> getToCoreNotificationsMsgConsumer();
  82 +
  83 + /**
62 84 * Used to consume Transport API Calls
63 85 *
64 86 * @return
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.queue.provider;
  17 +
  18 +import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
  19 +import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
  20 +import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
  21 +import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg;
  22 +import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
  23 +import org.thingsboard.server.queue.TbQueueProducer;
  24 +import org.thingsboard.server.queue.common.TbProtoQueueMsg;
  25 +
  26 +/**
  27 + * Responsible for providing various Producers to other services.
  28 + */
  29 +public interface TbQueueProducerProvider {
  30 +
  31 + /**
  32 + * Used to push messages to instances of TB Transport Service
  33 + *
  34 + * @return
  35 + */
  36 + TbQueueProducer<TbProtoQueueMsg<ToTransportMsg>> getTransportNotificationsMsgProducer();
  37 +
  38 + /**
  39 + * Used to push messages to instances of TB RuleEngine Service
  40 + *
  41 + * @return
  42 + */
  43 + TbQueueProducer<TbProtoQueueMsg<ToRuleEngineMsg>> getRuleEngineMsgProducer();
  44 +
  45 + /**
  46 + * Used to push notifications to instances of TB RuleEngine Service
  47 + *
  48 + * @return
  49 + */
  50 + TbQueueProducer<TbProtoQueueMsg<ToRuleEngineNotificationMsg>> getRuleEngineNotificationsMsgProducer();
  51 +
  52 + /**
  53 + * Used to push messages to other instances of TB Core Service
  54 + *
  55 + * @return
  56 + */
  57 + TbQueueProducer<TbProtoQueueMsg<ToCoreMsg>> getTbCoreMsgProducer();
  58 +
  59 + /**
  60 + * Used to push messages to other instances of TB Core Service
  61 + *
  62 + * @return
  63 + */
  64 + TbQueueProducer<TbProtoQueueMsg<ToCoreNotificationMsg>> getTbCoreNotificationsMsgProducer();
  65 +
  66 +}
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.queue.provider;
  17 +
  18 +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
  19 +import org.springframework.stereotype.Service;
  20 +import org.thingsboard.server.gen.transport.TransportProtos;
  21 +import org.thingsboard.server.queue.TbQueueProducer;
  22 +import org.thingsboard.server.queue.common.TbProtoQueueMsg;
  23 +
  24 +import javax.annotation.PostConstruct;
  25 +
  26 +@Service
  27 +@ConditionalOnExpression("'${service.type:null}'=='tb-rule-engine'")
  28 +public class TbRuleEngineProducerProvider implements TbQueueProducerProvider {
  29 +
  30 + private final TbRuleEngineQueueProvider tbQueueProvider;
  31 + private TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToTransportMsg>> toTransport;
  32 + private TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> toRuleEngine;
  33 + private TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToCoreMsg>> toTbCore;
  34 + private TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToRuleEngineNotificationMsg>> toRuleEngineNotifications;
  35 + private TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToCoreNotificationMsg>> toTbCoreNotifications;
  36 +
  37 +
  38 + public TbRuleEngineProducerProvider(TbRuleEngineQueueProvider tbQueueProvider) {
  39 + this.tbQueueProvider = tbQueueProvider;
  40 + }
  41 +
  42 + @PostConstruct
  43 + public void init() {
  44 + this.toTbCore = tbQueueProvider.getTbCoreMsgProducer();
  45 + this.toTransport = tbQueueProvider.getTransportNotificationsMsgProducer();
  46 + this.toRuleEngine = tbQueueProvider.getRuleEngineMsgProducer();
  47 + this.toRuleEngineNotifications = tbQueueProvider.getRuleEngineNotificationsMsgProducer();
  48 + this.toTbCoreNotifications = tbQueueProvider.getTbCoreNotificationsMsgProducer();
  49 + }
  50 +
  51 + @Override
  52 + public TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToTransportMsg>> getTransportNotificationsMsgProducer() {
  53 + return toTransport;
  54 + }
  55 +
  56 + @Override
  57 + public TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> getRuleEngineMsgProducer() {
  58 + return toRuleEngine;
  59 + }
  60 +
  61 + @Override
  62 + public TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToRuleEngineNotificationMsg>> getRuleEngineNotificationsMsgProducer() {
  63 + return toRuleEngineNotifications;
  64 + }
  65 +
  66 + @Override
  67 + public TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToCoreMsg>> getTbCoreMsgProducer() {
  68 + return toTbCore;
  69 + }
  70 +
  71 + @Override
  72 + public TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToCoreNotificationMsg>> getTbCoreNotificationsMsgProducer() {
  73 + return toTbCoreNotifications;
  74 + }
  75 +}
... ...
... ... @@ -15,12 +15,14 @@
15 15 */
16 16 package org.thingsboard.server.queue.provider;
17 17
  18 +import org.thingsboard.server.gen.transport.TransportProtos;
18 19 import org.thingsboard.server.queue.TbQueueConsumer;
19 20 import org.thingsboard.server.queue.TbQueueProducer;
20 21 import org.thingsboard.server.queue.common.TbProtoQueueMsg;
21 22 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
22 23 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
23 24 import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
  25 +import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg;
24 26
25 27 /**
26 28 * Responsible for initialization of various Producers and Consumers used by TB Core Node.
... ... @@ -43,6 +45,13 @@ public interface TbRuleEngineQueueProvider {
43 45 TbQueueProducer<TbProtoQueueMsg<ToRuleEngineMsg>> getRuleEngineMsgProducer();
44 46
45 47 /**
  48 + * Used to push notifications to instances of TB RuleEngine Service
  49 + *
  50 + * @return
  51 + */
  52 + TbQueueProducer<TbProtoQueueMsg<ToRuleEngineNotificationMsg>> getRuleEngineNotificationsMsgProducer();
  53 +
  54 + /**
46 55 * Used to push messages to other instances of TB Core Service
47 56 *
48 57 * @return
... ... @@ -50,10 +59,24 @@ public interface TbRuleEngineQueueProvider {
50 59 TbQueueProducer<TbProtoQueueMsg<ToCoreMsg>> getTbCoreMsgProducer();
51 60
52 61 /**
  62 + * Used to push notifications to other instances of TB Core Service
  63 + *
  64 + * @return
  65 + */
  66 + TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToCoreNotificationMsg>> getTbCoreNotificationsMsgProducer();
  67 +
  68 + /**
53 69 * Used to consume messages by TB Core Service
54 70 *
55 71 * @return
56 72 */
57 73 TbQueueConsumer<TbProtoQueueMsg<ToRuleEngineMsg>> getToRuleEngineMsgConsumer();
58 74
  75 + /**
  76 + * Used to consume high priority messages by TB Core Service
  77 + *
  78 + * @return
  79 + */
  80 + TbQueueConsumer<TbProtoQueueMsg<ToRuleEngineNotificationMsg>> getToRuleEngineNotificationsMsgConsumer();
  81 +
59 82 }
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.queue.provider;
  17 +
  18 +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
  19 +import org.springframework.stereotype.Service;
  20 +import org.thingsboard.server.gen.transport.TransportProtos;
  21 +import org.thingsboard.server.queue.TbQueueProducer;
  22 +import org.thingsboard.server.queue.common.TbProtoQueueMsg;
  23 +
  24 +import javax.annotation.PostConstruct;
  25 +
  26 +//TODO 2.5 Maybe remove this service if it is not used.
  27 +@Service
  28 +@ConditionalOnExpression("'${service.type:null}'=='tb-transport'")
  29 +public class TbTransportQueueProducerProvider implements TbQueueProducerProvider {
  30 +
  31 + private final TbTransportQueueProvider tbQueueProvider;
  32 + private TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToTransportMsg>> toTransport;
  33 + private TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> toRuleEngine;
  34 + private TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToCoreMsg>> toTbCore;
  35 +
  36 + public TbTransportQueueProducerProvider(TbTransportQueueProvider tbQueueProvider) {
  37 + this.tbQueueProvider = tbQueueProvider;
  38 + }
  39 +
  40 + @PostConstruct
  41 + public void init() {
  42 + this.toTbCore = tbQueueProvider.getTbCoreMsgProducer();
  43 + this.toRuleEngine = tbQueueProvider.getRuleEngineMsgProducer();
  44 + }
  45 +
  46 + @Override
  47 + public TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToTransportMsg>> getTransportNotificationsMsgProducer() {
  48 + throw new RuntimeException("Not Implemented! Should not be used by Transport!");
  49 + }
  50 +
  51 + @Override
  52 + public TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> getRuleEngineMsgProducer() {
  53 + return toRuleEngine;
  54 + }
  55 +
  56 + @Override
  57 + public TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToCoreMsg>> getTbCoreMsgProducer() {
  58 + return toTbCore;
  59 + }
  60 +
  61 + @Override
  62 + public TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToRuleEngineNotificationMsg>> getRuleEngineNotificationsMsgProducer() {
  63 + throw new RuntimeException("Not Implemented! Should not be used by Transport!");
  64 + }
  65 +
  66 + @Override
  67 + public TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToCoreNotificationMsg>> getTbCoreNotificationsMsgProducer() {
  68 + throw new RuntimeException("Not Implemented! Should not be used by Transport!");
  69 + }
  70 +}
... ...
common/queue/src/main/java/org/thingsboard/server/queue/provider/TbTransportQueueProvider.java renamed from common/queue/src/main/java/org/thingsboard/server/queue/provider/TransportQueueProvider.java
... ... @@ -25,7 +25,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
25 25 import org.thingsboard.server.gen.transport.TransportProtos.TransportApiRequestMsg;
26 26 import org.thingsboard.server.gen.transport.TransportProtos.TransportApiResponseMsg;
27 27
28   -public interface TransportQueueProvider {
  28 +public interface TbTransportQueueProvider {
29 29
30 30 TbQueueRequestTemplate<TbProtoQueueMsg<TransportApiRequestMsg>, TbProtoQueueMsg<TransportApiResponseMsg>> getTransportApiRequestTemplate();
31 31
... ...
... ... @@ -337,6 +337,12 @@ message LocalSubscriptionServiceMsgProto {
337 337 TbSubscriptionUpdateProto subUpdate = 1;
338 338 }
339 339
  340 +message FromDeviceRPCResponseProto {
  341 + int64 requestIdMSB = 1;
  342 + int64 requestIdLSB = 2;
  343 + string response = 3;
  344 + int32 error = 4;
  345 +}
340 346 /**
341 347 * Main messages;
342 348 */
... ... @@ -359,7 +365,14 @@ message ToCoreMsg {
359 365 TransportToDeviceActorMsg toDeviceActorMsg = 1;
360 366 DeviceStateServiceMsgProto deviceStateServiceMsg = 2;
361 367 SubscriptionMgrMsgProto toSubscriptionMgrMsg = 3;
362   - LocalSubscriptionServiceMsgProto toLocalSubscriptionServiceMsg = 4;
  368 + bytes toDeviceActorNotificationMsg = 4;
  369 +}
  370 +
  371 +/* High priority messages with low latency are handled by ThingsBoard Core Service separately */
  372 +message ToCoreNotificationMsg {
  373 + LocalSubscriptionServiceMsgProto toLocalSubscriptionServiceMsg = 1;
  374 + FromDeviceRPCResponseProto fromDeviceRpcResponse = 2;
  375 + bytes componentLifecycleMsg = 3;
363 376 }
364 377
365 378 /* Messages that are handled by ThingsBoard RuleEngine Service */
... ... @@ -369,6 +382,11 @@ message ToRuleEngineMsg {
369 382 bytes tbMsg = 3;
370 383 }
371 384
  385 +message ToRuleEngineNotificationMsg {
  386 + bytes componentLifecycleMsg = 1;
  387 + FromDeviceRPCResponseProto fromDeviceRpcResponse = 2;
  388 +}
  389 +
372 390 /* Messages that are handled by ThingsBoard Transport Service */
373 391 message ToTransportMsg {
374 392 DeviceActorToTransportMsg toDeviceSessionMsg = 1;
... ...
... ... @@ -20,14 +20,8 @@ import org.eclipse.californium.core.CoapResource;
20 20 import org.eclipse.californium.core.CoapServer;
21 21 import org.eclipse.californium.core.network.CoapEndpoint;
22 22 import org.springframework.beans.factory.annotation.Autowired;
23   -import org.springframework.beans.factory.annotation.Value;
24 23 import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
25   -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
26   -import org.springframework.context.ApplicationContext;
27 24 import org.springframework.stereotype.Service;
28   -import org.thingsboard.server.common.transport.SessionMsgProcessor;
29   -import org.thingsboard.server.common.transport.auth.DeviceAuthService;
30   -import org.thingsboard.server.transport.coap.adaptors.CoapTransportAdaptor;
31 25
32 26 import javax.annotation.PostConstruct;
33 27 import javax.annotation.PreDestroy;
... ...
... ... @@ -5,7 +5,7 @@
5 5 * you may not use this file except in compliance with the License.
6 6 * You may obtain a copy of the License at
7 7 *
8   - * http://www.apache.org/licenses/LICENSE-2.0
  8 + * http://www.apache.org/licenses/LICENSE-2.0
9 9 *
10 10 * Unless required by applicable law or agreed to in writing, software
11 11 * distributed under the License is distributed on an "AS IS" BASIS,
... ... @@ -17,7 +17,6 @@ package org.thingsboard.server.common.transport.service;
17 17
18 18 import com.google.gson.Gson;
19 19 import com.google.gson.JsonObject;
20   -import com.google.protobuf.ByteString;
21 20 import lombok.extern.slf4j.Slf4j;
22 21 import org.springframework.beans.factory.annotation.Value;
23 22 import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
... ... @@ -44,9 +43,9 @@ import org.thingsboard.server.common.transport.SessionMsgListener;
44 43 import org.thingsboard.server.common.transport.TransportService;
45 44 import org.thingsboard.server.common.transport.TransportServiceCallback;
46 45 import org.thingsboard.server.queue.discovery.PartitionService;
47   -import org.thingsboard.server.queue.discovery.ServiceType;
48   -import org.thingsboard.server.queue.discovery.TopicPartitionInfo;
49   -import org.thingsboard.server.queue.provider.TransportQueueProvider;
  46 +import org.thingsboard.server.common.msg.queue.ServiceType;
  47 +import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
  48 +import org.thingsboard.server.queue.provider.TbTransportQueueProvider;
50 49 import org.thingsboard.server.gen.transport.TransportProtos;
51 50 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
52 51 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
... ... @@ -54,18 +53,15 @@ import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
54 53 import org.thingsboard.server.gen.transport.TransportProtos.TransportApiRequestMsg;
55 54 import org.thingsboard.server.gen.transport.TransportProtos.TransportApiResponseMsg;
56 55 import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg;
57   -import org.thingsboard.server.gen.transport.TransportProtos.TransportToRuleEngineMsg;
58 56 import org.thingsboard.server.queue.common.AsyncCallbackTemplate;
59 57
60 58 import javax.annotation.PostConstruct;
61 59 import javax.annotation.PreDestroy;
62   -import java.util.ArrayList;
63 60 import java.util.List;
64 61 import java.util.Random;
65 62 import java.util.UUID;
66 63 import java.util.concurrent.ConcurrentHashMap;
67 64 import java.util.concurrent.ConcurrentMap;
68   -import java.util.concurrent.CountDownLatch;
69 65 import java.util.concurrent.ExecutorService;
70 66 import java.util.concurrent.Executors;
71 67 import java.util.concurrent.ScheduledExecutorService;
... ... @@ -95,7 +91,7 @@ public class DefaultTransportService implements TransportService {
95 91 private int notificationsPollDuration;
96 92
97 93 private final Gson gson = new Gson();
98   - private final TransportQueueProvider queueProvider;
  94 + private final TbTransportQueueProvider queueProvider;
99 95 private final PartitionService partitionService;
100 96
101 97 protected TbQueueRequestTemplate<TbProtoQueueMsg<TransportApiRequestMsg>, TbProtoQueueMsg<TransportApiResponseMsg>> transportApiRequestTemplate;
... ... @@ -114,7 +110,7 @@ public class DefaultTransportService implements TransportService {
114 110 private ExecutorService mainConsumerExecutor = Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName("transport-consumer"));
115 111 private volatile boolean stopped = false;
116 112
117   - public DefaultTransportService(TransportQueueProvider queueProvider, PartitionService partitionService) {
  113 + public DefaultTransportService(TbTransportQueueProvider queueProvider, PartitionService partitionService) {
118 114 this.queueProvider = queueProvider;
119 115 this.partitionService = partitionService;
120 116 }
... ...
... ... @@ -18,6 +18,7 @@ package org.thingsboard.rule.engine.api;
18 18 import lombok.Builder;
19 19 import lombok.Data;
20 20 import org.thingsboard.server.common.data.id.DeviceId;
  21 +import org.thingsboard.server.common.data.id.TenantId;
21 22
22 23 import java.util.UUID;
23 24
... ... @@ -28,11 +29,11 @@ import java.util.UUID;
28 29 @Builder
29 30 public final class RuleEngineDeviceRpcRequest {
30 31
  32 + private final TenantId tenantId;
31 33 private final DeviceId deviceId;
32 34 private final int requestId;
33 35 private final UUID requestUUID;
34   - private final String originHost;
35   - private final int originPort;
  36 + private final String originServiceId;
36 37 private final boolean oneway;
37 38 private final String method;
38 39 private final String body;
... ...
... ... @@ -23,8 +23,8 @@ import java.util.function.Consumer;
23 23 */
24 24 public interface RuleEngineRpcService {
25 25
26   - void sendRpcReply(DeviceId deviceId, int requestId, String body);
  26 + void sendRpcReplyToDevice(DeviceId deviceId, int requestId, String body);
27 27
28   - void sendRpcRequest(RuleEngineDeviceRpcRequest request, Consumer<RuleEngineDeviceRpcResponse> consumer);
  28 + void sendRpcRequestToDevice(RuleEngineDeviceRpcRequest request, Consumer<RuleEngineDeviceRpcResponse> consumer);
29 29
30 30 }
... ...
... ... @@ -16,7 +16,7 @@
16 16 package org.thingsboard.rule.engine.api;
17 17
18 18 import org.thingsboard.server.common.msg.TbMsg;
19   -import org.thingsboard.server.common.msg.cluster.ClusterEventMsg;
  19 +import org.thingsboard.server.common.msg.queue.PartitionChangeMsg;
20 20
21 21 import java.util.concurrent.ExecutionException;
22 22
... ... @@ -31,6 +31,6 @@ public interface TbNode {
31 31
32 32 void destroy();
33 33
34   - default void onClusterEventMsg(TbContext ctx, ClusterEventMsg msg) {}
  34 + default void onPartitionChangeMsg(TbContext ctx, PartitionChangeMsg msg) {}
35 35
36 36 }
... ...
... ... @@ -25,7 +25,7 @@ import org.thingsboard.server.common.data.id.EntityIdFactory;
25 25 import org.thingsboard.server.common.data.plugin.ComponentType;
26 26 import org.thingsboard.server.common.msg.TbMsg;
27 27 import org.thingsboard.server.common.msg.TbMsgMetaData;
28   -import org.thingsboard.server.common.msg.cluster.ClusterEventMsg;
  28 +import org.thingsboard.server.common.msg.queue.PartitionChangeMsg;
29 29
30 30 import java.util.UUID;
31 31 import java.util.concurrent.TimeUnit;
... ... @@ -74,7 +74,7 @@ public class TbMsgGeneratorNode implements TbNode {
74 74 }
75 75
76 76 @Override
77   - public void onClusterEventMsg(TbContext ctx, ClusterEventMsg msg) {
  77 + public void onPartitionChangeMsg(TbContext ctx, PartitionChangeMsg msg) {
78 78 updateGeneratorState(ctx);
79 79 }
80 80
... ...
... ... @@ -58,7 +58,7 @@ public class TbSendRPCReplyNode implements TbNode {
58 58 } else if (StringUtils.isEmpty(msg.getData())) {
59 59 ctx.tellFailure(msg, new RuntimeException("Request body is empty!"));
60 60 } else {
61   - ctx.getRpcService().sendRpcReply(new DeviceId(msg.getOriginator().getId()), Integer.parseInt(requestIdStr), msg.getData());
  61 + ctx.getRpcService().sendRpcReplyToDevice(new DeviceId(msg.getOriginator().getId()), Integer.parseInt(requestIdStr), msg.getData());
62 62 }
63 63 }
64 64
... ...
... ... @@ -16,8 +16,6 @@
16 16 package org.thingsboard.rule.engine.rpc;
17 17
18 18 import com.datastax.driver.core.utils.UUIDs;
19   -import com.fasterxml.jackson.databind.ObjectMapper;
20   -import com.fasterxml.jackson.databind.JsonNode;
21 19 import com.google.gson.Gson;
22 20 import com.google.gson.JsonElement;
23 21 import com.google.gson.JsonObject;
... ... @@ -38,7 +36,6 @@ import org.thingsboard.server.common.data.id.DeviceId;
38 36 import org.thingsboard.server.common.data.plugin.ComponentType;
39 37 import org.thingsboard.server.common.msg.TbMsg;
40 38
41   -import java.io.IOException;
42 39 import java.util.Random;
43 40 import java.util.UUID;
44 41 import java.util.concurrent.TimeUnit;
... ... @@ -86,10 +83,8 @@ public class TbSendRPCRequestNode implements TbNode {
86 83
87 84 tmp = msg.getMetaData().getValue("requestUUID");
88 85 UUID requestUUID = !StringUtils.isEmpty(tmp) ? UUID.fromString(tmp) : UUIDs.timeBased();
89   - tmp = msg.getMetaData().getValue("originHost");
90   - String originHost = !StringUtils.isEmpty(tmp) ? tmp : null;
91   - tmp = msg.getMetaData().getValue("originPort");
92   - int originPort = !StringUtils.isEmpty(tmp) ? Integer.parseInt(tmp) : 0;
  86 + tmp = msg.getMetaData().getValue("originServiceId");
  87 + String originServiceId = !StringUtils.isEmpty(tmp) ? tmp : null;
93 88
94 89 tmp = msg.getMetaData().getValue("expirationTime");
95 90 long expirationTime = !StringUtils.isEmpty(tmp) ? Long.parseLong(tmp) : (System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(config.getTimeoutInSeconds()));
... ... @@ -106,16 +101,16 @@ public class TbSendRPCRequestNode implements TbNode {
106 101 .oneway(oneway)
107 102 .method(json.get("method").getAsString())
108 103 .body(params)
  104 + .tenantId(ctx.getTenantId())
109 105 .deviceId(new DeviceId(msg.getOriginator().getId()))
110 106 .requestId(requestId)
111 107 .requestUUID(requestUUID)
112   - .originHost(originHost)
113   - .originPort(originPort)
  108 + .originServiceId(originServiceId)
114 109 .expirationTime(expirationTime)
115 110 .restApiCall(restApiCall)
116 111 .build();
117 112
118   - ctx.getRpcService().sendRpcRequest(request, ruleEngineDeviceRpcResponse -> {
  113 + ctx.getRpcService().sendRpcRequestToDevice(request, ruleEngineDeviceRpcResponse -> {
119 114 if (!ruleEngineDeviceRpcResponse.getError().isPresent()) {
120 115 TbMsg next = ctx.transformMsg(msg, msg.getType(), msg.getOriginator(), msg.getMetaData(), ruleEngineDeviceRpcResponse.getResponse().orElse("{}"));
121 116 ctx.tellNext(next, TbRelationTypes.SUCCESS);
... ...