Commit 7531a26e617092c437b9df6c8d13b22511eac1ab
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) { | ... | ... |
application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleNodeActorMessageProcessor.java
... | ... | @@ -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 | } | ... | ... |
application/src/main/java/org/thingsboard/server/service/queue/DefaultTbClusterService.java
0 → 100644
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 | } | ... | ... |
application/src/main/java/org/thingsboard/server/service/rpc/DefaultTbRuleEngineRpcService.java
0 → 100644
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 | ... | ... |
application/src/main/proto/cluster.proto
deleted
100644 → 0
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 | 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; | ... | ... |
... | ... | @@ -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 | } | ... | ... |
... | ... | @@ -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 | } | ... | ... |
common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbRuleEngineQueueProvider.java
... | ... | @@ -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; | ... | ... |
common/queue/src/main/java/org/thingsboard/server/queue/provider/TbCoreQueueProducerProvider.java
0 → 100644
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 | ... | ... |
common/queue/src/main/java/org/thingsboard/server/queue/provider/TbQueueProducerProvider.java
0 → 100644
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 | +} | ... | ... |
common/queue/src/main/java/org/thingsboard/server/queue/provider/TbRuleEngineProducerProvider.java
0 → 100644
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); | ... | ... |