Showing
64 changed files
with
976 additions
and
720 deletions
@@ -24,10 +24,9 @@ import akka.actor.Terminated; | @@ -24,10 +24,9 @@ import akka.actor.Terminated; | ||
24 | import com.google.common.collect.BiMap; | 24 | import com.google.common.collect.BiMap; |
25 | import com.google.common.collect.HashBiMap; | 25 | import com.google.common.collect.HashBiMap; |
26 | import org.thingsboard.server.actors.ActorSystemContext; | 26 | import org.thingsboard.server.actors.ActorSystemContext; |
27 | -import org.thingsboard.server.actors.ruleChain.RuleChainManagerActor; | 27 | +import org.thingsboard.server.actors.service.ContextAwareActor; |
28 | import org.thingsboard.server.actors.service.ContextBasedCreator; | 28 | import org.thingsboard.server.actors.service.ContextBasedCreator; |
29 | import org.thingsboard.server.actors.service.DefaultActorService; | 29 | import org.thingsboard.server.actors.service.DefaultActorService; |
30 | -import org.thingsboard.server.actors.shared.rulechain.SystemRuleChainManager; | ||
31 | import org.thingsboard.server.actors.tenant.TenantActor; | 30 | import org.thingsboard.server.actors.tenant.TenantActor; |
32 | import org.thingsboard.server.common.data.EntityType; | 31 | import org.thingsboard.server.common.data.EntityType; |
33 | import org.thingsboard.server.common.data.Tenant; | 32 | import org.thingsboard.server.common.data.Tenant; |
@@ -37,16 +36,14 @@ import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; | @@ -37,16 +36,14 @@ import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; | ||
37 | import org.thingsboard.server.common.msg.MsgType; | 36 | import org.thingsboard.server.common.msg.MsgType; |
38 | import org.thingsboard.server.common.msg.TbActorMsg; | 37 | import org.thingsboard.server.common.msg.TbActorMsg; |
39 | import org.thingsboard.server.common.msg.aware.TenantAwareMsg; | 38 | import org.thingsboard.server.common.msg.aware.TenantAwareMsg; |
40 | -import org.thingsboard.server.common.msg.cluster.SendToClusterMsg; | ||
41 | import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; | 39 | import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; |
42 | -import org.thingsboard.server.common.msg.queue.PartitionChangeMsg; | ||
43 | import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg; | 40 | import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg; |
44 | -import org.thingsboard.server.common.msg.queue.ServiceType; | 41 | +import org.thingsboard.server.common.msg.queue.RuleEngineException; |
45 | import org.thingsboard.server.dao.model.ModelConstants; | 42 | import org.thingsboard.server.dao.model.ModelConstants; |
46 | import org.thingsboard.server.dao.tenant.TenantService; | 43 | import org.thingsboard.server.dao.tenant.TenantService; |
47 | import scala.concurrent.duration.Duration; | 44 | import scala.concurrent.duration.Duration; |
48 | 45 | ||
49 | -public class AppActor extends RuleChainManagerActor { | 46 | +public class AppActor extends ContextAwareActor { |
50 | 47 | ||
51 | private static final TenantId SYSTEM_TENANT = new TenantId(ModelConstants.NULL_UUID); | 48 | private static final TenantId SYSTEM_TENANT = new TenantId(ModelConstants.NULL_UUID); |
52 | private final TenantService tenantService; | 49 | private final TenantService tenantService; |
@@ -54,7 +51,7 @@ public class AppActor extends RuleChainManagerActor { | @@ -54,7 +51,7 @@ public class AppActor extends RuleChainManagerActor { | ||
54 | private boolean ruleChainsInitialized; | 51 | private boolean ruleChainsInitialized; |
55 | 52 | ||
56 | private AppActor(ActorSystemContext systemContext) { | 53 | private AppActor(ActorSystemContext systemContext) { |
57 | - super(systemContext, new SystemRuleChainManager(systemContext)); | 54 | + super(systemContext); |
58 | this.tenantService = systemContext.getTenantService(); | 55 | this.tenantService = systemContext.getTenantService(); |
59 | this.tenantActors = HashBiMap.create(); | 56 | this.tenantActors = HashBiMap.create(); |
60 | } | 57 | } |
@@ -80,9 +77,6 @@ public class AppActor extends RuleChainManagerActor { | @@ -80,9 +77,6 @@ public class AppActor extends RuleChainManagerActor { | ||
80 | switch (msg.getMsgType()) { | 77 | switch (msg.getMsgType()) { |
81 | case APP_INIT_MSG: | 78 | case APP_INIT_MSG: |
82 | break; | 79 | break; |
83 | - case SEND_TO_CLUSTER_MSG: | ||
84 | - onPossibleClusterMsg((SendToClusterMsg) msg); | ||
85 | - break; | ||
86 | case PARTITION_CHANGE_MSG: | 80 | case PARTITION_CHANGE_MSG: |
87 | broadcast(msg); | 81 | broadcast(msg); |
88 | break; | 82 | break; |
@@ -98,7 +92,6 @@ public class AppActor extends RuleChainManagerActor { | @@ -98,7 +92,6 @@ public class AppActor extends RuleChainManagerActor { | ||
98 | case DEVICE_NAME_OR_TYPE_UPDATE_TO_DEVICE_ACTOR_MSG: | 92 | case DEVICE_NAME_OR_TYPE_UPDATE_TO_DEVICE_ACTOR_MSG: |
99 | case DEVICE_RPC_REQUEST_TO_DEVICE_ACTOR_MSG: | 93 | case DEVICE_RPC_REQUEST_TO_DEVICE_ACTOR_MSG: |
100 | case SERVER_RPC_RESPONSE_TO_DEVICE_ACTOR_MSG: | 94 | case SERVER_RPC_RESPONSE_TO_DEVICE_ACTOR_MSG: |
101 | - case REMOTE_TO_RULE_CHAIN_TELL_NEXT_MSG: | ||
102 | onToDeviceActorMsg((TenantAwareMsg) msg); | 95 | onToDeviceActorMsg((TenantAwareMsg) msg); |
103 | break; | 96 | break; |
104 | default: | 97 | default: |
@@ -110,7 +103,6 @@ public class AppActor extends RuleChainManagerActor { | @@ -110,7 +103,6 @@ public class AppActor extends RuleChainManagerActor { | ||
110 | private void initRuleChainsAndTenantActors() { | 103 | private void initRuleChainsAndTenantActors() { |
111 | log.info("Starting main system actor."); | 104 | log.info("Starting main system actor."); |
112 | try { | 105 | try { |
113 | - initRuleChains(); | ||
114 | if (systemContext.isTenantComponentsInitEnabled()) { | 106 | if (systemContext.isTenantComponentsInitEnabled()) { |
115 | PageDataIterable<Tenant> tenantIterator = new PageDataIterable<>(tenantService::findTenants, ENTITY_PACK_LIMIT); | 107 | PageDataIterable<Tenant> tenantIterator = new PageDataIterable<>(tenantService::findTenants, ENTITY_PACK_LIMIT); |
116 | for (Tenant tenant : tenantIterator) { | 108 | for (Tenant tenant : tenantIterator) { |
@@ -125,37 +117,22 @@ public class AppActor extends RuleChainManagerActor { | @@ -125,37 +117,22 @@ public class AppActor extends RuleChainManagerActor { | ||
125 | } | 117 | } |
126 | } | 118 | } |
127 | 119 | ||
128 | - private void onPossibleClusterMsg(SendToClusterMsg msg) { | ||
129 | - //TODO 2.5 | ||
130 | -// Optional<ServerAddress> address = systemContext.getRoutingService().resolveById(msg.getEntityId()); | ||
131 | -// if (address.isPresent()) { | ||
132 | - | ||
133 | -// systemContext.getRpcService().tell( | ||
134 | -// systemContext.getEncodingService().convertToProtoDataMessage(address.get(), msg.getMsg())); | ||
135 | -// } else { | ||
136 | - self().tell(msg.getMsg(), ActorRef.noSender()); | ||
137 | -// } | ||
138 | - } | ||
139 | - | ||
140 | private void onQueueToRuleEngineMsg(QueueToRuleEngineMsg msg) { | 120 | private void onQueueToRuleEngineMsg(QueueToRuleEngineMsg msg) { |
141 | if (SYSTEM_TENANT.equals(msg.getTenantId())) { | 121 | if (SYSTEM_TENANT.equals(msg.getTenantId())) { |
142 | -// this may be a notification about system entities created. | ||
143 | -// log.warn("[{}] Invalid service to rule engine msg called. System messages are not supported yet: {}", SYSTEM_TENANT, msg); | 122 | + msg.getTbMsg().getCallback().onFailure(new RuleEngineException("Message has system tenant id!")); |
144 | } else { | 123 | } else { |
145 | getOrCreateTenantActor(msg.getTenantId()).tell(msg, self()); | 124 | getOrCreateTenantActor(msg.getTenantId()).tell(msg, self()); |
146 | } | 125 | } |
147 | } | 126 | } |
148 | 127 | ||
149 | - @Override | ||
150 | protected void broadcast(Object msg) { | 128 | protected void broadcast(Object msg) { |
151 | - super.broadcast(msg); | ||
152 | tenantActors.values().forEach(actorRef -> actorRef.tell(msg, ActorRef.noSender())); | 129 | tenantActors.values().forEach(actorRef -> actorRef.tell(msg, ActorRef.noSender())); |
153 | } | 130 | } |
154 | 131 | ||
155 | private void onComponentLifecycleMsg(ComponentLifecycleMsg msg) { | 132 | private void onComponentLifecycleMsg(ComponentLifecycleMsg msg) { |
156 | ActorRef target = null; | 133 | ActorRef target = null; |
157 | if (SYSTEM_TENANT.equals(msg.getTenantId())) { | 134 | if (SYSTEM_TENANT.equals(msg.getTenantId())) { |
158 | - target = getEntityActorRef(msg.getEntityId()); | 135 | + log.warn("Message has system tenant id: {}", msg); |
159 | } else { | 136 | } else { |
160 | if (msg.getEntityId().getEntityType() == EntityType.TENANT | 137 | if (msg.getEntityId().getEntityType() == EntityType.TENANT |
161 | && msg.getEvent() == ComponentLifecycleEvent.DELETED) { | 138 | && msg.getEvent() == ComponentLifecycleEvent.DELETED) { |
@@ -56,7 +56,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.ToDeviceRpcRequestMs | @@ -56,7 +56,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.ToDeviceRpcRequestMs | ||
56 | import org.thingsboard.server.gen.transport.TransportProtos.ToDeviceRpcResponseMsg; | 56 | import org.thingsboard.server.gen.transport.TransportProtos.ToDeviceRpcResponseMsg; |
57 | import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg; | 57 | import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg; |
58 | import org.thingsboard.server.gen.transport.TransportProtos.TsKvProto; | 58 | import org.thingsboard.server.gen.transport.TransportProtos.TsKvProto; |
59 | -import org.thingsboard.server.common.msg.queue.TbMsgCallback; | 59 | +import org.thingsboard.server.common.msg.queue.TbCallback; |
60 | import org.thingsboard.server.service.rpc.FromDeviceRpcResponse; | 60 | import org.thingsboard.server.service.rpc.FromDeviceRpcResponse; |
61 | import org.thingsboard.server.service.rpc.ToDeviceRpcRequestActorMsg; | 61 | import org.thingsboard.server.service.rpc.ToDeviceRpcRequestActorMsg; |
62 | import org.thingsboard.server.service.rpc.ToServerRpcResponseActorMsg; | 62 | import org.thingsboard.server.service.rpc.ToServerRpcResponseActorMsg; |
@@ -213,7 +213,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | @@ -213,7 +213,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | ||
213 | 213 | ||
214 | void process(ActorContext context, TransportToDeviceActorMsgWrapper wrapper) { | 214 | void process(ActorContext context, TransportToDeviceActorMsgWrapper wrapper) { |
215 | TransportToDeviceActorMsg msg = wrapper.getMsg(); | 215 | TransportToDeviceActorMsg msg = wrapper.getMsg(); |
216 | - TbMsgCallback callback = wrapper.getCallback(); | 216 | + TbCallback callback = wrapper.getCallback(); |
217 | if (msg.hasSessionEvent()) { | 217 | if (msg.hasSessionEvent()) { |
218 | processSessionStateMsgs(msg.getSessionInfo(), msg.getSessionEvent()); | 218 | processSessionStateMsgs(msg.getSessionInfo(), msg.getSessionEvent()); |
219 | } | 219 | } |
@@ -5,7 +5,7 @@ | @@ -5,7 +5,7 @@ | ||
5 | * you may not use this file except in compliance with 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 | 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 | * Unless required by applicable law or agreed to in writing, software | 10 | * Unless required by applicable law or agreed to in writing, software |
11 | * distributed under the License is distributed on an "AS IS" BASIS, | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
@@ -110,7 +110,7 @@ class DefaultTbContext implements TbContext { | @@ -110,7 +110,7 @@ class DefaultTbContext implements TbContext { | ||
110 | if (nodeCtx.getSelf().isDebugMode()) { | 110 | if (nodeCtx.getSelf().isDebugMode()) { |
111 | relationTypes.forEach(relationType -> mainCtx.persistDebugOutput(nodeCtx.getTenantId(), nodeCtx.getSelf().getId(), msg, relationType, th)); | 111 | relationTypes.forEach(relationType -> mainCtx.persistDebugOutput(nodeCtx.getTenantId(), nodeCtx.getSelf().getId(), msg, relationType, th)); |
112 | } | 112 | } |
113 | - nodeCtx.getChainActor().tell(new RuleNodeToRuleChainTellNextMsg(nodeCtx.getSelf().getId(), relationTypes, msg), nodeCtx.getSelfActor()); | 113 | + nodeCtx.getChainActor().tell(new RuleNodeToRuleChainTellNextMsg(nodeCtx.getSelf().getId(), relationTypes, msg, th != null ? th.getMessage() : null), nodeCtx.getSelfActor()); |
114 | } | 114 | } |
115 | 115 | ||
116 | @Override | 116 | @Override |
@@ -140,52 +140,60 @@ class DefaultTbContext implements TbContext { | @@ -140,52 +140,60 @@ class DefaultTbContext implements TbContext { | ||
140 | } | 140 | } |
141 | 141 | ||
142 | @Override | 142 | @Override |
143 | + public void enqueueForTellFailure(TbMsg tbMsg, String failureMessage) { | ||
144 | + TopicPartitionInfo tpi = mainCtx.resolve(ServiceType.TB_RULE_ENGINE, getTenantId(), tbMsg.getOriginator()); | ||
145 | + enqueueForTellNext(tpi, tbMsg, Collections.singleton(TbRelationTypes.FAILURE), failureMessage, null, null); | ||
146 | + } | ||
147 | + | ||
148 | + @Override | ||
143 | public void enqueueForTellNext(TbMsg tbMsg, String relationType) { | 149 | public void enqueueForTellNext(TbMsg tbMsg, String relationType) { |
144 | TopicPartitionInfo tpi = mainCtx.resolve(ServiceType.TB_RULE_ENGINE, getTenantId(), tbMsg.getOriginator()); | 150 | TopicPartitionInfo tpi = mainCtx.resolve(ServiceType.TB_RULE_ENGINE, getTenantId(), tbMsg.getOriginator()); |
145 | - enqueueForTellNext(tpi, tbMsg, Collections.singleton(relationType), null, null); | 151 | + enqueueForTellNext(tpi, tbMsg, Collections.singleton(relationType), null, null, null); |
146 | } | 152 | } |
147 | 153 | ||
148 | @Override | 154 | @Override |
149 | public void enqueueForTellNext(TbMsg tbMsg, Set<String> relationTypes) { | 155 | public void enqueueForTellNext(TbMsg tbMsg, Set<String> relationTypes) { |
150 | TopicPartitionInfo tpi = mainCtx.resolve(ServiceType.TB_RULE_ENGINE, getTenantId(), tbMsg.getOriginator()); | 156 | TopicPartitionInfo tpi = mainCtx.resolve(ServiceType.TB_RULE_ENGINE, getTenantId(), tbMsg.getOriginator()); |
151 | - enqueueForTellNext(tpi, tbMsg, relationTypes, null, null); | 157 | + enqueueForTellNext(tpi, tbMsg, relationTypes, null, null, null); |
152 | } | 158 | } |
153 | 159 | ||
154 | @Override | 160 | @Override |
155 | public void enqueueForTellNext(TbMsg tbMsg, String relationType, Runnable onSuccess, Consumer<Throwable> onFailure) { | 161 | public void enqueueForTellNext(TbMsg tbMsg, String relationType, Runnable onSuccess, Consumer<Throwable> onFailure) { |
156 | TopicPartitionInfo tpi = mainCtx.resolve(ServiceType.TB_RULE_ENGINE, getTenantId(), tbMsg.getOriginator()); | 162 | TopicPartitionInfo tpi = mainCtx.resolve(ServiceType.TB_RULE_ENGINE, getTenantId(), tbMsg.getOriginator()); |
157 | - enqueueForTellNext(tpi, tbMsg, Collections.singleton(relationType), onSuccess, onFailure); | 163 | + enqueueForTellNext(tpi, tbMsg, Collections.singleton(relationType), null, onSuccess, onFailure); |
158 | } | 164 | } |
159 | 165 | ||
160 | @Override | 166 | @Override |
161 | public void enqueueForTellNext(TbMsg tbMsg, Set<String> relationTypes, Runnable onSuccess, Consumer<Throwable> onFailure) { | 167 | public void enqueueForTellNext(TbMsg tbMsg, Set<String> relationTypes, Runnable onSuccess, Consumer<Throwable> onFailure) { |
162 | TopicPartitionInfo tpi = mainCtx.resolve(ServiceType.TB_RULE_ENGINE, getTenantId(), tbMsg.getOriginator()); | 168 | TopicPartitionInfo tpi = mainCtx.resolve(ServiceType.TB_RULE_ENGINE, getTenantId(), tbMsg.getOriginator()); |
163 | - enqueueForTellNext(tpi, tbMsg, relationTypes, onSuccess, onFailure); | 169 | + enqueueForTellNext(tpi, tbMsg, relationTypes, null, onSuccess, onFailure); |
164 | } | 170 | } |
165 | 171 | ||
166 | @Override | 172 | @Override |
167 | public void enqueueForTellNext(TbMsg tbMsg, String queueName, String relationType, Runnable onSuccess, Consumer<Throwable> onFailure) { | 173 | public void enqueueForTellNext(TbMsg tbMsg, String queueName, String relationType, Runnable onSuccess, Consumer<Throwable> onFailure) { |
168 | - TopicPartitionInfo tpi = mainCtx.resolve(ServiceType.TB_RULE_ENGINE, getTenantId(), tbMsg.getOriginator()); | ||
169 | - enqueueForTellNext(tpi, tbMsg, Collections.singleton(relationType), onSuccess, onFailure); | 174 | + TopicPartitionInfo tpi = mainCtx.resolve(ServiceType.TB_RULE_ENGINE, queueName, getTenantId(), tbMsg.getOriginator()); |
175 | + enqueueForTellNext(tpi, tbMsg, Collections.singleton(relationType), null, onSuccess, onFailure); | ||
170 | } | 176 | } |
171 | 177 | ||
172 | @Override | 178 | @Override |
173 | public void enqueueForTellNext(TbMsg tbMsg, String queueName, Set<String> relationTypes, Runnable onSuccess, Consumer<Throwable> onFailure) { | 179 | public void enqueueForTellNext(TbMsg tbMsg, String queueName, Set<String> relationTypes, Runnable onSuccess, Consumer<Throwable> onFailure) { |
174 | TopicPartitionInfo tpi = mainCtx.resolve(ServiceType.TB_RULE_ENGINE, queueName, getTenantId(), tbMsg.getOriginator()); | 180 | TopicPartitionInfo tpi = mainCtx.resolve(ServiceType.TB_RULE_ENGINE, queueName, getTenantId(), tbMsg.getOriginator()); |
175 | - enqueueForTellNext(tpi, tbMsg, relationTypes, onSuccess, onFailure); | 181 | + enqueueForTellNext(tpi, tbMsg, relationTypes, null, onSuccess, onFailure); |
176 | } | 182 | } |
177 | 183 | ||
178 | - private void enqueueForTellNext(TopicPartitionInfo tpi, TbMsg tbMsg, Set<String> relationTypes, Runnable onSuccess, Consumer<Throwable> onFailure) { | 184 | + private void enqueueForTellNext(TopicPartitionInfo tpi, TbMsg tbMsg, Set<String> relationTypes, String failureMessage, Runnable onSuccess, Consumer<Throwable> onFailure) { |
179 | RuleChainId ruleChainId = nodeCtx.getSelf().getRuleChainId(); | 185 | RuleChainId ruleChainId = nodeCtx.getSelf().getRuleChainId(); |
180 | RuleNodeId ruleNodeId = nodeCtx.getSelf().getId(); | 186 | RuleNodeId ruleNodeId = nodeCtx.getSelf().getId(); |
181 | tbMsg = TbMsg.newMsg(tbMsg, ruleChainId, ruleNodeId); | 187 | tbMsg = TbMsg.newMsg(tbMsg, ruleChainId, ruleNodeId); |
182 | - TransportProtos.ToRuleEngineMsg msg = TransportProtos.ToRuleEngineMsg.newBuilder() | 188 | + TransportProtos.ToRuleEngineMsg.Builder msg = TransportProtos.ToRuleEngineMsg.newBuilder() |
183 | .setTenantIdMSB(getTenantId().getId().getMostSignificantBits()) | 189 | .setTenantIdMSB(getTenantId().getId().getMostSignificantBits()) |
184 | .setTenantIdLSB(getTenantId().getId().getLeastSignificantBits()) | 190 | .setTenantIdLSB(getTenantId().getId().getLeastSignificantBits()) |
185 | .setTbMsg(TbMsg.toByteString(tbMsg)) | 191 | .setTbMsg(TbMsg.toByteString(tbMsg)) |
186 | - .addAllRelationTypes(relationTypes) | ||
187 | - .build(); | ||
188 | - mainCtx.getProducerProvider().getRuleEngineMsgProducer().send(tpi, new TbProtoQueueMsg<>(tbMsg.getId(), msg), new SimpleTbQueueCallback(onSuccess, onFailure)); | 192 | + .addAllRelationTypes(relationTypes); |
193 | + if (failureMessage != null) { | ||
194 | + msg.setFailureMessage(failureMessage); | ||
195 | + } | ||
196 | + mainCtx.getProducerProvider().getRuleEngineMsgProducer().send(tpi, new TbProtoQueueMsg<>(tbMsg.getId(), msg.build()), new SimpleTbQueueCallback(onSuccess, onFailure)); | ||
189 | } | 197 | } |
190 | 198 | ||
191 | @Override | 199 | @Override |
@@ -207,7 +215,8 @@ class DefaultTbContext implements TbContext { | @@ -207,7 +215,8 @@ class DefaultTbContext implements TbContext { | ||
207 | if (nodeCtx.getSelf().isDebugMode()) { | 215 | if (nodeCtx.getSelf().isDebugMode()) { |
208 | mainCtx.persistDebugOutput(nodeCtx.getTenantId(), nodeCtx.getSelf().getId(), msg, TbRelationTypes.FAILURE, th); | 216 | mainCtx.persistDebugOutput(nodeCtx.getTenantId(), nodeCtx.getSelf().getId(), msg, TbRelationTypes.FAILURE, th); |
209 | } | 217 | } |
210 | - nodeCtx.getChainActor().tell(new RuleNodeToRuleChainTellNextMsg(nodeCtx.getSelf().getId(), Collections.singleton(TbRelationTypes.FAILURE), msg), nodeCtx.getSelfActor()); | 218 | + nodeCtx.getChainActor().tell(new RuleNodeToRuleChainTellNextMsg(nodeCtx.getSelf().getId(), Collections.singleton(TbRelationTypes.FAILURE), |
219 | + msg, th != null ? th.getMessage() : null), nodeCtx.getSelfActor()); | ||
211 | } | 220 | } |
212 | 221 | ||
213 | public void updateSelf(RuleNode self) { | 222 | public void updateSelf(RuleNode self) { |
application/src/main/java/org/thingsboard/server/actors/ruleChain/RemoteToRuleChainTellNextMsg.java
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 | -package org.thingsboard.server.actors.ruleChain; | ||
17 | - | ||
18 | -import lombok.Data; | ||
19 | -import org.thingsboard.server.common.data.id.RuleChainId; | ||
20 | -import org.thingsboard.server.common.data.id.TenantId; | ||
21 | -import org.thingsboard.server.common.msg.MsgType; | ||
22 | -import org.thingsboard.server.common.msg.aware.RuleChainAwareMsg; | ||
23 | -import org.thingsboard.server.common.msg.aware.TenantAwareMsg; | ||
24 | - | ||
25 | -import java.io.Serializable; | ||
26 | - | ||
27 | -/** | ||
28 | - * Created by ashvayka on 19.03.18. | ||
29 | - */ | ||
30 | -@Data | ||
31 | -final class RemoteToRuleChainTellNextMsg extends RuleNodeToRuleChainTellNextMsg implements TenantAwareMsg, RuleChainAwareMsg { | ||
32 | - | ||
33 | - private static final long serialVersionUID = 2459605482321657447L; | ||
34 | - private final TenantId tenantId; | ||
35 | - private final RuleChainId ruleChainId; | ||
36 | - | ||
37 | - public RemoteToRuleChainTellNextMsg(RuleNodeToRuleChainTellNextMsg original, TenantId tenantId, RuleChainId ruleChainId) { | ||
38 | - super(original.getOriginator(), original.getRelationTypes(), original.getMsg()); | ||
39 | - this.tenantId = tenantId; | ||
40 | - this.ruleChainId = ruleChainId; | ||
41 | - } | ||
42 | - | ||
43 | - @Override | ||
44 | - public MsgType getMsgType() { | ||
45 | - return MsgType.REMOTE_TO_RULE_CHAIN_TELL_NEXT_MSG; | ||
46 | - } | ||
47 | - | ||
48 | -} |
@@ -22,6 +22,7 @@ import org.thingsboard.server.actors.service.ComponentActor; | @@ -22,6 +22,7 @@ import org.thingsboard.server.actors.service.ComponentActor; | ||
22 | import org.thingsboard.server.actors.service.ContextBasedCreator; | 22 | import org.thingsboard.server.actors.service.ContextBasedCreator; |
23 | import org.thingsboard.server.common.data.id.RuleChainId; | 23 | import org.thingsboard.server.common.data.id.RuleChainId; |
24 | import org.thingsboard.server.common.data.id.TenantId; | 24 | import org.thingsboard.server.common.data.id.TenantId; |
25 | +import org.thingsboard.server.common.data.rule.RuleChain; | ||
25 | import org.thingsboard.server.common.msg.TbActorMsg; | 26 | import org.thingsboard.server.common.msg.TbActorMsg; |
26 | import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; | 27 | import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; |
27 | import org.thingsboard.server.common.msg.queue.PartitionChangeMsg; | 28 | import org.thingsboard.server.common.msg.queue.PartitionChangeMsg; |
@@ -30,9 +31,9 @@ import scala.concurrent.duration.Duration; | @@ -30,9 +31,9 @@ import scala.concurrent.duration.Duration; | ||
30 | 31 | ||
31 | public class RuleChainActor extends ComponentActor<RuleChainId, RuleChainActorMessageProcessor> { | 32 | public class RuleChainActor extends ComponentActor<RuleChainId, RuleChainActorMessageProcessor> { |
32 | 33 | ||
33 | - private RuleChainActor(ActorSystemContext systemContext, TenantId tenantId, RuleChainId ruleChainId) { | ||
34 | - super(systemContext, tenantId, ruleChainId); | ||
35 | - setProcessor(new RuleChainActorMessageProcessor(tenantId, ruleChainId, systemContext, | 34 | + private RuleChainActor(ActorSystemContext systemContext, TenantId tenantId, RuleChain ruleChain) { |
35 | + super(systemContext, tenantId, ruleChain.getId()); | ||
36 | + setProcessor(new RuleChainActorMessageProcessor(tenantId, ruleChain, systemContext, | ||
36 | context().parent(), context().self())); | 37 | context().parent(), context().self())); |
37 | } | 38 | } |
38 | 39 | ||
@@ -46,7 +47,6 @@ public class RuleChainActor extends ComponentActor<RuleChainId, RuleChainActorMe | @@ -46,7 +47,6 @@ public class RuleChainActor extends ComponentActor<RuleChainId, RuleChainActorMe | ||
46 | processor.onQueueToRuleEngineMsg((QueueToRuleEngineMsg) msg); | 47 | processor.onQueueToRuleEngineMsg((QueueToRuleEngineMsg) msg); |
47 | break; | 48 | break; |
48 | case RULE_TO_RULE_CHAIN_TELL_NEXT_MSG: | 49 | case RULE_TO_RULE_CHAIN_TELL_NEXT_MSG: |
49 | - case REMOTE_TO_RULE_CHAIN_TELL_NEXT_MSG: | ||
50 | processor.onTellNext((RuleNodeToRuleChainTellNextMsg) msg); | 50 | processor.onTellNext((RuleNodeToRuleChainTellNextMsg) msg); |
51 | break; | 51 | break; |
52 | case RULE_CHAIN_TO_RULE_CHAIN_MSG: | 52 | case RULE_CHAIN_TO_RULE_CHAIN_MSG: |
@@ -68,17 +68,17 @@ public class RuleChainActor extends ComponentActor<RuleChainId, RuleChainActorMe | @@ -68,17 +68,17 @@ public class RuleChainActor extends ComponentActor<RuleChainId, RuleChainActorMe | ||
68 | private static final long serialVersionUID = 1L; | 68 | private static final long serialVersionUID = 1L; |
69 | 69 | ||
70 | private final TenantId tenantId; | 70 | private final TenantId tenantId; |
71 | - private final RuleChainId ruleChainId; | 71 | + private final RuleChain ruleChain; |
72 | 72 | ||
73 | - public ActorCreator(ActorSystemContext context, TenantId tenantId, RuleChainId pluginId) { | 73 | + public ActorCreator(ActorSystemContext context, TenantId tenantId, RuleChain ruleChain) { |
74 | super(context); | 74 | super(context); |
75 | this.tenantId = tenantId; | 75 | this.tenantId = tenantId; |
76 | - this.ruleChainId = pluginId; | 76 | + this.ruleChain = ruleChain; |
77 | } | 77 | } |
78 | 78 | ||
79 | @Override | 79 | @Override |
80 | public RuleChainActor create() { | 80 | public RuleChainActor create() { |
81 | - return new RuleChainActor(context, tenantId, ruleChainId); | 81 | + return new RuleChainActor(context, tenantId, ruleChain); |
82 | } | 82 | } |
83 | } | 83 | } |
84 | 84 |
@@ -5,7 +5,7 @@ | @@ -5,7 +5,7 @@ | ||
5 | * you may not use this file except in compliance with 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 | 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 | * Unless required by applicable law or agreed to in writing, software | 10 | * Unless required by applicable law or agreed to in writing, software |
11 | * distributed under the License is distributed on an "AS IS" BASIS, | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
@@ -37,6 +37,8 @@ import org.thingsboard.server.common.msg.TbMsg; | @@ -37,6 +37,8 @@ import org.thingsboard.server.common.msg.TbMsg; | ||
37 | import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; | 37 | import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; |
38 | import org.thingsboard.server.common.msg.queue.PartitionChangeMsg; | 38 | import org.thingsboard.server.common.msg.queue.PartitionChangeMsg; |
39 | import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg; | 39 | import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg; |
40 | +import org.thingsboard.server.common.msg.queue.RuleEngineException; | ||
41 | +import org.thingsboard.server.common.msg.queue.RuleNodeException; | ||
40 | import org.thingsboard.server.common.msg.queue.ServiceType; | 42 | import org.thingsboard.server.common.msg.queue.ServiceType; |
41 | import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; | 43 | import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; |
42 | import org.thingsboard.server.dao.rule.RuleChainService; | 44 | import org.thingsboard.server.dao.rule.RuleChainService; |
@@ -67,14 +69,16 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh | @@ -67,14 +69,16 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh | ||
67 | private final Map<RuleNodeId, List<RuleNodeRelation>> nodeRoutes; | 69 | private final Map<RuleNodeId, List<RuleNodeRelation>> nodeRoutes; |
68 | private final RuleChainService service; | 70 | private final RuleChainService service; |
69 | private final TbQueueProducer<TbProtoQueueMsg<ToRuleEngineMsg>> producer; | 71 | private final TbQueueProducer<TbProtoQueueMsg<ToRuleEngineMsg>> producer; |
72 | + private String ruleChainName; | ||
70 | 73 | ||
71 | private RuleNodeId firstId; | 74 | private RuleNodeId firstId; |
72 | private RuleNodeCtx firstNode; | 75 | private RuleNodeCtx firstNode; |
73 | private boolean started; | 76 | private boolean started; |
74 | 77 | ||
75 | - RuleChainActorMessageProcessor(TenantId tenantId, RuleChainId ruleChainId, ActorSystemContext systemContext | 78 | + RuleChainActorMessageProcessor(TenantId tenantId, RuleChain ruleChain, ActorSystemContext systemContext |
76 | , ActorRef parent, ActorRef self) { | 79 | , ActorRef parent, ActorRef self) { |
77 | - super(systemContext, tenantId, ruleChainId); | 80 | + super(systemContext, tenantId, ruleChain.getId()); |
81 | + this.ruleChainName = ruleChain.getName(); | ||
78 | this.parent = parent; | 82 | this.parent = parent; |
79 | this.self = self; | 83 | this.self = self; |
80 | this.nodeActors = new HashMap<>(); | 84 | this.nodeActors = new HashMap<>(); |
@@ -113,6 +117,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh | @@ -113,6 +117,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh | ||
113 | public void onUpdate(ActorContext context) { | 117 | public void onUpdate(ActorContext context) { |
114 | RuleChain ruleChain = service.findRuleChainById(tenantId, entityId); | 118 | RuleChain ruleChain = service.findRuleChainById(tenantId, entityId); |
115 | if (ruleChain != null) { | 119 | if (ruleChain != null) { |
120 | + ruleChainName = ruleChain.getName(); | ||
116 | List<RuleNode> ruleNodeList = service.getRuleChainNodes(tenantId, entityId); | 121 | List<RuleNode> ruleNodeList = service.getRuleChainNodes(tenantId, entityId); |
117 | log.trace("[{}][{}] Updating rule chain with {} nodes", tenantId, entityId, ruleNodeList.size()); | 122 | log.trace("[{}][{}] Updating rule chain with {} nodes", tenantId, entityId, ruleNodeList.size()); |
118 | for (RuleNode ruleNode : ruleNodeList) { | 123 | for (RuleNode ruleNode : ruleNodeList) { |
@@ -194,7 +199,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh | @@ -194,7 +199,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh | ||
194 | void onQueueToRuleEngineMsg(QueueToRuleEngineMsg envelope) { | 199 | void onQueueToRuleEngineMsg(QueueToRuleEngineMsg envelope) { |
195 | TbMsg msg = envelope.getTbMsg(); | 200 | TbMsg msg = envelope.getTbMsg(); |
196 | log.trace("[{}][{}] Processing message [{}]: {}", entityId, firstId, msg.getId(), msg); | 201 | log.trace("[{}][{}] Processing message [{}]: {}", entityId, firstId, msg.getId(), msg); |
197 | - if (envelope.getRelationTypes() == null) { | 202 | + if (envelope.getRelationTypes() == null || envelope.getRelationTypes().isEmpty()) { |
198 | try { | 203 | try { |
199 | checkActive(); | 204 | checkActive(); |
200 | RuleNodeId targetId = msg.getRuleNodeId(); | 205 | RuleNodeId targetId = msg.getRuleNodeId(); |
@@ -213,10 +218,10 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh | @@ -213,10 +218,10 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh | ||
213 | msg.getCallback().onSuccess(); | 218 | msg.getCallback().onSuccess(); |
214 | } | 219 | } |
215 | } catch (Exception e) { | 220 | } catch (Exception e) { |
216 | - envelope.getTbMsg().getCallback().onFailure(e); | 221 | + envelope.getTbMsg().getCallback().onFailure(new RuleEngineException(e.getMessage())); |
217 | } | 222 | } |
218 | } else { | 223 | } else { |
219 | - onTellNext(envelope.getTbMsg(), envelope.getTbMsg().getRuleNodeId(), envelope.getRelationTypes()); | 224 | + onTellNext(envelope.getTbMsg(), envelope.getTbMsg().getRuleNodeId(), envelope.getRelationTypes(), envelope.getFailureMessage()); |
220 | } | 225 | } |
221 | } | 226 | } |
222 | 227 | ||
@@ -230,10 +235,10 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh | @@ -230,10 +235,10 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh | ||
230 | } | 235 | } |
231 | 236 | ||
232 | void onTellNext(RuleNodeToRuleChainTellNextMsg envelope) { | 237 | void onTellNext(RuleNodeToRuleChainTellNextMsg envelope) { |
233 | - onTellNext(envelope.getMsg(), envelope.getOriginator(), envelope.getRelationTypes()); | 238 | + onTellNext(envelope.getMsg(), envelope.getOriginator(), envelope.getRelationTypes(), envelope.getFailureMessage()); |
234 | } | 239 | } |
235 | 240 | ||
236 | - private void onTellNext(TbMsg msg, RuleNodeId originatorNodeId, Set<String> relationTypes) { | 241 | + private void onTellNext(TbMsg msg, RuleNodeId originatorNodeId, Set<String> relationTypes, String failureMessage) { |
237 | try { | 242 | try { |
238 | checkActive(); | 243 | checkActive(); |
239 | EntityId entityId = msg.getOriginator(); | 244 | EntityId entityId = msg.getOriginator(); |
@@ -245,9 +250,14 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh | @@ -245,9 +250,14 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh | ||
245 | if (relationsCount == 0) { | 250 | if (relationsCount == 0) { |
246 | log.trace("[{}][{}][{}] No outbound relations to process", tenantId, entityId, msg.getId()); | 251 | log.trace("[{}][{}][{}] No outbound relations to process", tenantId, entityId, msg.getId()); |
247 | if (relationTypes.contains(TbRelationTypes.FAILURE)) { | 252 | if (relationTypes.contains(TbRelationTypes.FAILURE)) { |
248 | - log.debug("[{}] Failure during message processing by Rule Node [{}]. Enable and see debug events for more info", entityId, originatorNodeId.getId()); | ||
249 | - //TODO 2.5: Introduce our own RuleEngineFailureException to track what is wrong | ||
250 | - msg.getCallback().onFailure(new RuntimeException("Failure during message processing by Rule Node [" + originatorNodeId.getId().toString() + "]")); | 253 | + RuleNodeCtx ruleNodeCtx = nodeActors.get(originatorNodeId); |
254 | + if (ruleNodeCtx != null) { | ||
255 | + msg.getCallback().onFailure(new RuleNodeException(failureMessage, ruleChainName, ruleNodeCtx.getSelf())); | ||
256 | + } else { | ||
257 | + log.debug("[{}] Failure during message processing by Rule Node [{}]. Enable and see debug events for more info", entityId, originatorNodeId.getId()); | ||
258 | + //TODO 2.5: Introduce our own RuleEngineFailureException to track what is wrong | ||
259 | + msg.getCallback().onFailure(new RuleEngineException("Failure during message processing by Rule Node [" + originatorNodeId.getId().toString() + "]")); | ||
260 | + } | ||
251 | } else { | 261 | } else { |
252 | msg.getCallback().onSuccess(); | 262 | msg.getCallback().onSuccess(); |
253 | } | 263 | } |
@@ -265,7 +275,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh | @@ -265,7 +275,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh | ||
265 | } | 275 | } |
266 | } | 276 | } |
267 | } catch (Exception e) { | 277 | } catch (Exception e) { |
268 | - msg.getCallback().onFailure(e); | 278 | + msg.getCallback().onFailure(new RuleEngineException("onTellNext - " + e.getMessage())); |
269 | } | 279 | } |
270 | } | 280 | } |
271 | 281 |
@@ -15,43 +15,89 @@ | @@ -15,43 +15,89 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.actors.ruleChain; | 16 | package org.thingsboard.server.actors.ruleChain; |
17 | 17 | ||
18 | +import akka.actor.ActorContext; | ||
18 | import akka.actor.ActorRef; | 19 | import akka.actor.ActorRef; |
20 | +import akka.actor.Props; | ||
21 | +import com.google.common.collect.BiMap; | ||
22 | +import com.google.common.collect.HashBiMap; | ||
23 | +import lombok.Getter; | ||
19 | import org.thingsboard.server.actors.ActorSystemContext; | 24 | import org.thingsboard.server.actors.ActorSystemContext; |
20 | import org.thingsboard.server.actors.service.ContextAwareActor; | 25 | import org.thingsboard.server.actors.service.ContextAwareActor; |
21 | -import org.thingsboard.server.actors.shared.rulechain.RuleChainManager; | 26 | +import org.thingsboard.server.actors.service.DefaultActorService; |
27 | +import org.thingsboard.server.common.data.EntityType; | ||
22 | import org.thingsboard.server.common.data.id.EntityId; | 28 | import org.thingsboard.server.common.data.id.EntityId; |
23 | import org.thingsboard.server.common.data.id.RuleChainId; | 29 | import org.thingsboard.server.common.data.id.RuleChainId; |
30 | +import org.thingsboard.server.common.data.id.TenantId; | ||
31 | +import org.thingsboard.server.common.data.page.PageDataIterable; | ||
32 | +import org.thingsboard.server.common.data.rule.RuleChain; | ||
24 | import org.thingsboard.server.dao.rule.RuleChainService; | 33 | import org.thingsboard.server.dao.rule.RuleChainService; |
25 | 34 | ||
35 | +import java.util.function.Function; | ||
36 | + | ||
26 | /** | 37 | /** |
27 | * Created by ashvayka on 15.03.18. | 38 | * Created by ashvayka on 15.03.18. |
28 | */ | 39 | */ |
29 | public abstract class RuleChainManagerActor extends ContextAwareActor { | 40 | public abstract class RuleChainManagerActor extends ContextAwareActor { |
30 | 41 | ||
31 | - protected final RuleChainManager ruleChainManager; | ||
32 | - protected final RuleChainService ruleChainService; | 42 | + protected final TenantId tenantId; |
43 | + private final RuleChainService ruleChainService; | ||
44 | + private final BiMap<RuleChainId, ActorRef> actors; | ||
45 | + @Getter | ||
46 | + protected RuleChain rootChain; | ||
47 | + @Getter | ||
48 | + protected ActorRef rootChainActor; | ||
33 | 49 | ||
34 | - public RuleChainManagerActor(ActorSystemContext systemContext, RuleChainManager ruleChainManager) { | 50 | + public RuleChainManagerActor(ActorSystemContext systemContext, TenantId tenantId) { |
35 | super(systemContext); | 51 | super(systemContext); |
36 | - this.ruleChainManager = ruleChainManager; | 52 | + this.tenantId = tenantId; |
53 | + this.actors = HashBiMap.create(); | ||
37 | this.ruleChainService = systemContext.getRuleChainService(); | 54 | this.ruleChainService = systemContext.getRuleChainService(); |
38 | } | 55 | } |
39 | 56 | ||
40 | protected void initRuleChains() { | 57 | protected void initRuleChains() { |
41 | - ruleChainManager.init(this.context()); | 58 | + for (RuleChain ruleChain : new PageDataIterable<>(link -> ruleChainService.findTenantRuleChains(tenantId, link), ContextAwareActor.ENTITY_PACK_LIMIT)) { |
59 | + RuleChainId ruleChainId = ruleChain.getId(); | ||
60 | + log.debug("[{}|{}] Creating rule chain actor", ruleChainId.getEntityType(), ruleChain.getId()); | ||
61 | + //TODO: remove this cast making UUIDBased subclass of EntityId an interface and vice versa. | ||
62 | + ActorRef actorRef = getOrCreateActor(this.context(), ruleChainId, id -> ruleChain); | ||
63 | + visit(ruleChain, actorRef); | ||
64 | + log.debug("[{}|{}] Rule Chain actor created.", ruleChainId.getEntityType(), ruleChainId.getId()); | ||
65 | + } | ||
66 | + } | ||
67 | + | ||
68 | + protected void visit(RuleChain entity, ActorRef actorRef) { | ||
69 | + if (entity != null && entity.isRoot()) { | ||
70 | + rootChain = entity; | ||
71 | + rootChainActor = actorRef; | ||
72 | + } | ||
73 | + } | ||
74 | + | ||
75 | + public ActorRef getOrCreateActor(ActorContext context, RuleChainId ruleChainId) { | ||
76 | + return getOrCreateActor(context, ruleChainId, eId -> ruleChainService.findRuleChainById(TenantId.SYS_TENANT_ID, eId)); | ||
77 | + } | ||
78 | + | ||
79 | + public ActorRef getOrCreateActor(ActorContext context, RuleChainId ruleChainId, Function<RuleChainId, RuleChain> provider) { | ||
80 | + return actors.computeIfAbsent(ruleChainId, eId -> { | ||
81 | + RuleChain ruleChain = provider.apply(eId); | ||
82 | + return context.actorOf(Props.create(new RuleChainActor.ActorCreator(systemContext, tenantId, ruleChain)) | ||
83 | + .withDispatcher(DefaultActorService.TENANT_RULE_DISPATCHER_NAME), eId.toString()); | ||
84 | + }); | ||
42 | } | 85 | } |
43 | 86 | ||
44 | protected ActorRef getEntityActorRef(EntityId entityId) { | 87 | protected ActorRef getEntityActorRef(EntityId entityId) { |
45 | ActorRef target = null; | 88 | ActorRef target = null; |
46 | - switch (entityId.getEntityType()) { | ||
47 | - case RULE_CHAIN: | ||
48 | - target = ruleChainManager.getOrCreateActor(this.context(), (RuleChainId) entityId); | ||
49 | - break; | 89 | + if (entityId.getEntityType() == EntityType.RULE_CHAIN) { |
90 | + target = getOrCreateActor(this.context(), (RuleChainId) entityId); | ||
50 | } | 91 | } |
51 | return target; | 92 | return target; |
52 | } | 93 | } |
53 | 94 | ||
54 | protected void broadcast(Object msg) { | 95 | protected void broadcast(Object msg) { |
55 | - ruleChainManager.broadcast(msg); | 96 | + actors.values().forEach(actorRef -> actorRef.tell(msg, ActorRef.noSender())); |
56 | } | 97 | } |
98 | + | ||
99 | + public ActorRef get(RuleChainId id) { | ||
100 | + return actors.get(id); | ||
101 | + } | ||
102 | + | ||
57 | } | 103 | } |
@@ -34,6 +34,7 @@ class RuleNodeToRuleChainTellNextMsg implements TbActorMsg, Serializable { | @@ -34,6 +34,7 @@ class RuleNodeToRuleChainTellNextMsg implements TbActorMsg, Serializable { | ||
34 | private final RuleNodeId originator; | 34 | private final RuleNodeId originator; |
35 | private final Set<String> relationTypes; | 35 | private final Set<String> relationTypes; |
36 | private final TbMsg msg; | 36 | private final TbMsg msg; |
37 | + private final String failureMessage; | ||
37 | 38 | ||
38 | @Override | 39 | @Override |
39 | public MsgType getMsgType() { | 40 | public MsgType getMsgType() { |
application/src/main/java/org/thingsboard/server/actors/shared/EntityActorsManager.java
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 | -package org.thingsboard.server.actors.shared; | ||
17 | - | ||
18 | -import akka.actor.ActorContext; | ||
19 | -import akka.actor.ActorRef; | ||
20 | -import akka.actor.Props; | ||
21 | -import akka.actor.UntypedActor; | ||
22 | -import akka.japi.Creator; | ||
23 | -import com.google.common.collect.BiMap; | ||
24 | -import com.google.common.collect.HashBiMap; | ||
25 | -import lombok.extern.slf4j.Slf4j; | ||
26 | -import org.thingsboard.server.actors.ActorSystemContext; | ||
27 | -import org.thingsboard.server.actors.ruleChain.RuleChainActor; | ||
28 | -import org.thingsboard.server.actors.service.ContextAwareActor; | ||
29 | -import org.thingsboard.server.common.data.SearchTextBased; | ||
30 | -import org.thingsboard.server.common.data.id.EntityId; | ||
31 | -import org.thingsboard.server.common.data.id.RuleChainId; | ||
32 | -import org.thingsboard.server.common.data.id.TenantId; | ||
33 | -import org.thingsboard.server.common.data.id.UUIDBased; | ||
34 | -import org.thingsboard.server.common.data.page.PageDataIterable; | ||
35 | - | ||
36 | -import java.util.HashMap; | ||
37 | -import java.util.Map; | ||
38 | - | ||
39 | -/** | ||
40 | - * Created by ashvayka on 15.03.18. | ||
41 | - */ | ||
42 | -@Slf4j | ||
43 | -public abstract class EntityActorsManager<T extends EntityId, A extends UntypedActor, M extends SearchTextBased<? extends UUIDBased>> { | ||
44 | - | ||
45 | - protected final ActorSystemContext systemContext; | ||
46 | - protected final BiMap<T, ActorRef> actors; | ||
47 | - | ||
48 | - public EntityActorsManager(ActorSystemContext systemContext) { | ||
49 | - this.systemContext = systemContext; | ||
50 | - this.actors = HashBiMap.create(); | ||
51 | - } | ||
52 | - | ||
53 | - protected abstract TenantId getTenantId(); | ||
54 | - | ||
55 | - protected abstract String getDispatcherName(); | ||
56 | - | ||
57 | - protected abstract Creator<A> creator(T entityId); | ||
58 | - | ||
59 | - protected abstract PageDataIterable.FetchFunction<M> getFetchEntitiesFunction(); | ||
60 | - | ||
61 | - public void init(ActorContext context) { | ||
62 | - for (M entity : new PageDataIterable<>(getFetchEntitiesFunction(), ContextAwareActor.ENTITY_PACK_LIMIT)) { | ||
63 | - T entityId = (T) entity.getId(); | ||
64 | - log.debug("[{}|{}] Creating entity actor", entityId.getEntityType(), entityId.getId()); | ||
65 | - //TODO: remove this cast making UUIDBased subclass of EntityId an interface and vice versa. | ||
66 | - ActorRef actorRef = getOrCreateActor(context, entityId); | ||
67 | - visit(entity, actorRef); | ||
68 | - log.debug("[{}|{}] Entity actor created.", entityId.getEntityType(), entityId.getId()); | ||
69 | - } | ||
70 | - } | ||
71 | - | ||
72 | - public void visit(M entity, ActorRef actorRef) { | ||
73 | - } | ||
74 | - | ||
75 | - public ActorRef getOrCreateActor(ActorContext context, T entityId) { | ||
76 | - return actors.computeIfAbsent(entityId, eId -> | ||
77 | - context.actorOf(Props.create(creator(eId)) | ||
78 | - .withDispatcher(getDispatcherName()), eId.toString())); | ||
79 | - } | ||
80 | - | ||
81 | - public void broadcast(Object msg) { | ||
82 | - actors.values().forEach(actorRef -> actorRef.tell(msg, ActorRef.noSender())); | ||
83 | - } | ||
84 | - | ||
85 | - public void remove(T id) { | ||
86 | - actors.remove(id); | ||
87 | - } | ||
88 | - | ||
89 | - public ActorRef get(T id) { | ||
90 | - return actors.get(id); | ||
91 | - } | ||
92 | - | ||
93 | -} |
application/src/main/java/org/thingsboard/server/actors/shared/rulechain/RuleChainManager.java
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 | -package org.thingsboard.server.actors.shared.rulechain; | ||
17 | - | ||
18 | -import akka.actor.ActorRef; | ||
19 | -import akka.japi.Creator; | ||
20 | -import lombok.Getter; | ||
21 | -import lombok.extern.slf4j.Slf4j; | ||
22 | -import org.thingsboard.server.actors.ActorSystemContext; | ||
23 | -import org.thingsboard.server.actors.ruleChain.RuleChainActor; | ||
24 | -import org.thingsboard.server.actors.shared.EntityActorsManager; | ||
25 | -import org.thingsboard.server.common.data.id.RuleChainId; | ||
26 | -import org.thingsboard.server.common.data.rule.RuleChain; | ||
27 | -import org.thingsboard.server.dao.rule.RuleChainService; | ||
28 | - | ||
29 | -/** | ||
30 | - * Created by ashvayka on 15.03.18. | ||
31 | - */ | ||
32 | -@Slf4j | ||
33 | -public abstract class RuleChainManager extends EntityActorsManager<RuleChainId, RuleChainActor, RuleChain> { | ||
34 | - | ||
35 | - protected final RuleChainService service; | ||
36 | - @Getter | ||
37 | - protected RuleChain rootChain; | ||
38 | - @Getter | ||
39 | - protected ActorRef rootChainActor; | ||
40 | - | ||
41 | - public RuleChainManager(ActorSystemContext systemContext) { | ||
42 | - super(systemContext); | ||
43 | - this.service = systemContext.getRuleChainService(); | ||
44 | - } | ||
45 | - | ||
46 | - @Override | ||
47 | - public Creator<RuleChainActor> creator(RuleChainId entityId) { | ||
48 | - return new RuleChainActor.ActorCreator(systemContext, getTenantId(), entityId); | ||
49 | - } | ||
50 | - | ||
51 | - @Override | ||
52 | - public void visit(RuleChain entity, ActorRef actorRef) { | ||
53 | - if (entity != null && entity.isRoot()) { | ||
54 | - rootChain = entity; | ||
55 | - rootChainActor = actorRef; | ||
56 | - } | ||
57 | - } | ||
58 | - | ||
59 | -} |
application/src/main/java/org/thingsboard/server/actors/shared/rulechain/TenantRuleChainManager.java
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 | -package org.thingsboard.server.actors.shared.rulechain; | ||
17 | - | ||
18 | -import akka.actor.ActorContext; | ||
19 | -import org.thingsboard.server.actors.ActorSystemContext; | ||
20 | -import org.thingsboard.server.actors.service.DefaultActorService; | ||
21 | -import org.thingsboard.server.common.data.id.TenantId; | ||
22 | -import org.thingsboard.server.common.data.page.PageDataIterable.FetchFunction; | ||
23 | -import org.thingsboard.server.common.data.rule.RuleChain; | ||
24 | - | ||
25 | -public class TenantRuleChainManager extends RuleChainManager { | ||
26 | - | ||
27 | - private final TenantId tenantId; | ||
28 | - | ||
29 | - public TenantRuleChainManager(ActorSystemContext systemContext, TenantId tenantId) { | ||
30 | - super(systemContext); | ||
31 | - this.tenantId = tenantId; | ||
32 | - } | ||
33 | - | ||
34 | - @Override | ||
35 | - public void init(ActorContext context) { | ||
36 | - super.init(context); | ||
37 | - } | ||
38 | - | ||
39 | - @Override | ||
40 | - protected TenantId getTenantId() { | ||
41 | - return tenantId; | ||
42 | - } | ||
43 | - | ||
44 | - @Override | ||
45 | - protected String getDispatcherName() { | ||
46 | - return DefaultActorService.TENANT_RULE_DISPATCHER_NAME; | ||
47 | - } | ||
48 | - | ||
49 | - @Override | ||
50 | - protected FetchFunction<RuleChain> getFetchEntitiesFunction() { | ||
51 | - return link -> service.findTenantRuleChains(tenantId, link); | ||
52 | - } | ||
53 | -} |
@@ -24,7 +24,6 @@ import org.thingsboard.server.actors.service.ContextBasedCreator; | @@ -24,7 +24,6 @@ import org.thingsboard.server.actors.service.ContextBasedCreator; | ||
24 | import org.thingsboard.server.common.data.DataConstants; | 24 | import org.thingsboard.server.common.data.DataConstants; |
25 | import org.thingsboard.server.common.data.Event; | 25 | import org.thingsboard.server.common.data.Event; |
26 | import org.thingsboard.server.common.msg.TbActorMsg; | 26 | import org.thingsboard.server.common.msg.TbActorMsg; |
27 | -import org.thingsboard.server.common.msg.cluster.ServerAddress; | ||
28 | 27 | ||
29 | @Slf4j | 28 | @Slf4j |
30 | public class StatsActor extends ContextAwareActor { | 29 | public class StatsActor extends ContextAwareActor { |
@@ -30,7 +30,6 @@ import org.thingsboard.server.actors.device.DeviceActorCreator; | @@ -30,7 +30,6 @@ import org.thingsboard.server.actors.device.DeviceActorCreator; | ||
30 | import org.thingsboard.server.actors.ruleChain.RuleChainManagerActor; | 30 | import org.thingsboard.server.actors.ruleChain.RuleChainManagerActor; |
31 | import org.thingsboard.server.actors.service.ContextBasedCreator; | 31 | import org.thingsboard.server.actors.service.ContextBasedCreator; |
32 | import org.thingsboard.server.actors.service.DefaultActorService; | 32 | import org.thingsboard.server.actors.service.DefaultActorService; |
33 | -import org.thingsboard.server.actors.shared.rulechain.TenantRuleChainManager; | ||
34 | import org.thingsboard.server.common.data.EntityType; | 33 | import org.thingsboard.server.common.data.EntityType; |
35 | import org.thingsboard.server.common.data.id.DeviceId; | 34 | import org.thingsboard.server.common.data.id.DeviceId; |
36 | import org.thingsboard.server.common.data.id.RuleChainId; | 35 | import org.thingsboard.server.common.data.id.RuleChainId; |
@@ -43,6 +42,7 @@ import org.thingsboard.server.common.msg.aware.RuleChainAwareMsg; | @@ -43,6 +42,7 @@ import org.thingsboard.server.common.msg.aware.RuleChainAwareMsg; | ||
43 | import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; | 42 | import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; |
44 | import org.thingsboard.server.common.msg.queue.PartitionChangeMsg; | 43 | import org.thingsboard.server.common.msg.queue.PartitionChangeMsg; |
45 | import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg; | 44 | import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg; |
45 | +import org.thingsboard.server.common.msg.queue.RuleEngineException; | ||
46 | import org.thingsboard.server.common.msg.queue.ServiceType; | 46 | import org.thingsboard.server.common.msg.queue.ServiceType; |
47 | import scala.concurrent.duration.Duration; | 47 | import scala.concurrent.duration.Duration; |
48 | 48 | ||
@@ -51,12 +51,12 @@ import java.util.stream.Collectors; | @@ -51,12 +51,12 @@ import java.util.stream.Collectors; | ||
51 | 51 | ||
52 | public class TenantActor extends RuleChainManagerActor { | 52 | public class TenantActor extends RuleChainManagerActor { |
53 | 53 | ||
54 | - private final TenantId tenantId; | ||
55 | private final BiMap<DeviceId, ActorRef> deviceActors; | 54 | private final BiMap<DeviceId, ActorRef> deviceActors; |
55 | + private boolean isRuleEngine; | ||
56 | + private boolean isCore; | ||
56 | 57 | ||
57 | private TenantActor(ActorSystemContext systemContext, TenantId tenantId) { | 58 | private TenantActor(ActorSystemContext systemContext, TenantId tenantId) { |
58 | - super(systemContext, new TenantRuleChainManager(systemContext, tenantId)); | ||
59 | - this.tenantId = tenantId; | 59 | + super(systemContext, tenantId); |
60 | this.deviceActors = HashBiMap.create(); | 60 | this.deviceActors = HashBiMap.create(); |
61 | } | 61 | } |
62 | 62 | ||
@@ -69,7 +69,11 @@ public class TenantActor extends RuleChainManagerActor { | @@ -69,7 +69,11 @@ public class TenantActor extends RuleChainManagerActor { | ||
69 | public void preStart() { | 69 | public void preStart() { |
70 | log.info("[{}] Starting tenant actor.", tenantId); | 70 | log.info("[{}] Starting tenant actor.", tenantId); |
71 | try { | 71 | try { |
72 | - initRuleChains(); | 72 | + isRuleEngine = systemContext.getServiceInfoProvider().isService(ServiceType.TB_RULE_ENGINE); |
73 | + isCore = systemContext.getServiceInfoProvider().isService(ServiceType.TB_CORE); | ||
74 | + if (isRuleEngine) { | ||
75 | + initRuleChains(); | ||
76 | + } | ||
73 | log.info("[{}] Tenant actor started.", tenantId); | 77 | log.info("[{}] Tenant actor started.", tenantId); |
74 | } catch (Exception e) { | 78 | } catch (Exception e) { |
75 | log.warn("[{}] Unknown failure", tenantId, e); | 79 | log.warn("[{}] Unknown failure", tenantId, e); |
@@ -115,7 +119,6 @@ public class TenantActor extends RuleChainManagerActor { | @@ -115,7 +119,6 @@ public class TenantActor extends RuleChainManagerActor { | ||
115 | onToDeviceActorMsg((DeviceAwareMsg) msg); | 119 | onToDeviceActorMsg((DeviceAwareMsg) msg); |
116 | break; | 120 | break; |
117 | case RULE_CHAIN_TO_RULE_CHAIN_MSG: | 121 | case RULE_CHAIN_TO_RULE_CHAIN_MSG: |
118 | - case REMOTE_TO_RULE_CHAIN_TELL_NEXT_MSG: | ||
119 | onRuleChainMsg((RuleChainAwareMsg) msg); | 122 | onRuleChainMsg((RuleChainAwareMsg) msg); |
120 | break; | 123 | break; |
121 | default: | 124 | default: |
@@ -129,16 +132,19 @@ public class TenantActor extends RuleChainManagerActor { | @@ -129,16 +132,19 @@ public class TenantActor extends RuleChainManagerActor { | ||
129 | } | 132 | } |
130 | 133 | ||
131 | private void onQueueToRuleEngineMsg(QueueToRuleEngineMsg msg) { | 134 | private void onQueueToRuleEngineMsg(QueueToRuleEngineMsg msg) { |
135 | + if (!isRuleEngine) { | ||
136 | + log.warn("RECEIVED INVALID MESSAGE: {}", msg); | ||
137 | + } | ||
132 | TbMsg tbMsg = msg.getTbMsg(); | 138 | TbMsg tbMsg = msg.getTbMsg(); |
133 | if (tbMsg.getRuleChainId() == null) { | 139 | if (tbMsg.getRuleChainId() == null) { |
134 | - if (ruleChainManager.getRootChainActor() != null) { | ||
135 | - ruleChainManager.getRootChainActor().tell(msg, self()); | 140 | + if (getRootChainActor() != null) { |
141 | + getRootChainActor().tell(msg, self()); | ||
136 | } else { | 142 | } else { |
137 | - tbMsg.getCallback().onFailure(new RuntimeException("No Root Rule Chain available!")); | 143 | + tbMsg.getCallback().onFailure(new RuleEngineException("No Root Rule Chain available!")); |
138 | log.info("[{}] No Root Chain: {}", tenantId, msg); | 144 | log.info("[{}] No Root Chain: {}", tenantId, msg); |
139 | } | 145 | } |
140 | } else { | 146 | } else { |
141 | - ActorRef ruleChainActor = ruleChainManager.get(tbMsg.getRuleChainId()); | 147 | + ActorRef ruleChainActor = get(tbMsg.getRuleChainId()); |
142 | if (ruleChainActor != null) { | 148 | if (ruleChainActor != null) { |
143 | ruleChainActor.tell(msg, self()); | 149 | ruleChainActor.tell(msg, self()); |
144 | } else { | 150 | } else { |
@@ -150,24 +156,29 @@ public class TenantActor extends RuleChainManagerActor { | @@ -150,24 +156,29 @@ public class TenantActor extends RuleChainManagerActor { | ||
150 | } | 156 | } |
151 | 157 | ||
152 | private void onRuleChainMsg(RuleChainAwareMsg msg) { | 158 | private void onRuleChainMsg(RuleChainAwareMsg msg) { |
153 | - ruleChainManager.getOrCreateActor(context(), msg.getRuleChainId()).tell(msg, self()); | 159 | + getOrCreateActor(context(), msg.getRuleChainId()).tell(msg, self()); |
154 | } | 160 | } |
155 | 161 | ||
156 | private void onToDeviceActorMsg(DeviceAwareMsg msg) { | 162 | private void onToDeviceActorMsg(DeviceAwareMsg msg) { |
163 | + if (!isCore) { | ||
164 | + log.warn("RECEIVED INVALID MESSAGE: {}", msg); | ||
165 | + } | ||
157 | getOrCreateDeviceActor(msg.getDeviceId()).tell(msg, ActorRef.noSender()); | 166 | getOrCreateDeviceActor(msg.getDeviceId()).tell(msg, ActorRef.noSender()); |
158 | } | 167 | } |
159 | 168 | ||
160 | private void onComponentLifecycleMsg(ComponentLifecycleMsg msg) { | 169 | private void onComponentLifecycleMsg(ComponentLifecycleMsg msg) { |
161 | - ActorRef target = getEntityActorRef(msg.getEntityId()); | ||
162 | - if (target != null) { | ||
163 | - if (msg.getEntityId().getEntityType() == EntityType.RULE_CHAIN) { | ||
164 | - RuleChain ruleChain = systemContext.getRuleChainService(). | ||
165 | - findRuleChainById(tenantId, new RuleChainId(msg.getEntityId().getId())); | ||
166 | - ruleChainManager.visit(ruleChain, target); | 170 | + if (isRuleEngine) { |
171 | + ActorRef target = getEntityActorRef(msg.getEntityId()); | ||
172 | + if (target != null) { | ||
173 | + if (msg.getEntityId().getEntityType() == EntityType.RULE_CHAIN) { | ||
174 | + RuleChain ruleChain = systemContext.getRuleChainService(). | ||
175 | + findRuleChainById(tenantId, new RuleChainId(msg.getEntityId().getId())); | ||
176 | + visit(ruleChain, target); | ||
177 | + } | ||
178 | + target.tell(msg, ActorRef.noSender()); | ||
179 | + } else { | ||
180 | + log.debug("[{}] Invalid component lifecycle msg: {}", tenantId, msg); | ||
167 | } | 181 | } |
168 | - target.tell(msg, ActorRef.noSender()); | ||
169 | - } else { | ||
170 | - log.debug("[{}] Invalid component lifecycle msg: {}", tenantId, msg); | ||
171 | } | 182 | } |
172 | } | 183 | } |
173 | 184 | ||
@@ -214,15 +225,12 @@ public class TenantActor extends RuleChainManagerActor { | @@ -214,15 +225,12 @@ public class TenantActor extends RuleChainManagerActor { | ||
214 | } | 225 | } |
215 | } | 226 | } |
216 | 227 | ||
217 | - private final SupervisorStrategy strategy = new OneForOneStrategy(3, Duration.create("1 minute"), new Function<Throwable, SupervisorStrategy.Directive>() { | ||
218 | - @Override | ||
219 | - public SupervisorStrategy.Directive apply(Throwable t) { | ||
220 | - log.warn("[{}] Unknown failure", tenantId, t); | ||
221 | - if (t instanceof ActorInitializationException) { | ||
222 | - return SupervisorStrategy.stop(); | ||
223 | - } else { | ||
224 | - return SupervisorStrategy.resume(); | ||
225 | - } | 228 | + private final SupervisorStrategy strategy = new OneForOneStrategy(3, Duration.create("1 minute"), t -> { |
229 | + log.warn("[{}] Unknown failure", tenantId, t); | ||
230 | + if (t instanceof ActorInitializationException) { | ||
231 | + return SupervisorStrategy.stop(); | ||
232 | + } else { | ||
233 | + return SupervisorStrategy.resume(); | ||
226 | } | 234 | } |
227 | }); | 235 | }); |
228 | 236 |
@@ -92,10 +92,10 @@ public class TbWebSocketHandler extends TextWebSocketHandler implements Telemetr | @@ -92,10 +92,10 @@ public class TbWebSocketHandler extends TextWebSocketHandler implements Telemetr | ||
92 | try { | 92 | try { |
93 | SessionMetaData sessionMd = internalSessionMap.get(session.getId()); | 93 | SessionMetaData sessionMd = internalSessionMap.get(session.getId()); |
94 | if (sessionMd != null) { | 94 | if (sessionMd != null) { |
95 | - log.info("[{}][{}] Processing {}", sessionMd.sessionRef.getSecurityCtx().getTenantId(), session.getId(), message.getPayload()); | 95 | + log.trace("[{}][{}] Processing {}", sessionMd.sessionRef.getSecurityCtx().getTenantId(), session.getId(), message.getPayload()); |
96 | webSocketService.handleWebSocketMsg(sessionMd.sessionRef, message.getPayload()); | 96 | webSocketService.handleWebSocketMsg(sessionMd.sessionRef, message.getPayload()); |
97 | } else { | 97 | } else { |
98 | - log.warn("[{}] Failed to find session", session.getId()); | 98 | + log.trace("[{}] Failed to find session", session.getId()); |
99 | session.close(CloseStatus.SERVER_ERROR.withReason("Session not found!")); | 99 | session.close(CloseStatus.SERVER_ERROR.withReason("Session not found!")); |
100 | } | 100 | } |
101 | } catch (IOException e) { | 101 | } catch (IOException e) { |
@@ -139,7 +139,7 @@ public class TbWebSocketHandler extends TextWebSocketHandler implements Telemetr | @@ -139,7 +139,7 @@ public class TbWebSocketHandler extends TextWebSocketHandler implements Telemetr | ||
139 | if (sessionMd != null) { | 139 | if (sessionMd != null) { |
140 | processInWebSocketService(sessionMd.sessionRef, SessionEvent.onError(tError)); | 140 | processInWebSocketService(sessionMd.sessionRef, SessionEvent.onError(tError)); |
141 | } else { | 141 | } else { |
142 | - log.warn("[{}] Failed to find session", session.getId()); | 142 | + log.trace("[{}] Failed to find session", session.getId()); |
143 | } | 143 | } |
144 | log.trace("[{}] Session transport error", session.getId(), tError); | 144 | log.trace("[{}] Session transport error", session.getId(), tError); |
145 | } | 145 | } |
@@ -25,7 +25,7 @@ import org.thingsboard.server.actors.ActorSystemContext; | @@ -25,7 +25,7 @@ import org.thingsboard.server.actors.ActorSystemContext; | ||
25 | import org.thingsboard.server.common.data.id.TenantId; | 25 | import org.thingsboard.server.common.data.id.TenantId; |
26 | import org.thingsboard.server.common.msg.TbActorMsg; | 26 | import org.thingsboard.server.common.msg.TbActorMsg; |
27 | import org.thingsboard.server.common.msg.queue.ServiceType; | 27 | import org.thingsboard.server.common.msg.queue.ServiceType; |
28 | -import org.thingsboard.server.common.msg.queue.TbMsgCallback; | 28 | +import org.thingsboard.server.common.msg.queue.TbCallback; |
29 | import org.thingsboard.server.gen.transport.TransportProtos.DeviceStateServiceMsgProto; | 29 | import org.thingsboard.server.gen.transport.TransportProtos.DeviceStateServiceMsgProto; |
30 | import org.thingsboard.server.gen.transport.TransportProtos.FromDeviceRPCResponseProto; | 30 | import org.thingsboard.server.gen.transport.TransportProtos.FromDeviceRPCResponseProto; |
31 | import org.thingsboard.server.gen.transport.TransportProtos.LocalSubscriptionServiceMsgProto; | 31 | import org.thingsboard.server.gen.transport.TransportProtos.LocalSubscriptionServiceMsgProto; |
@@ -120,8 +120,8 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore | @@ -120,8 +120,8 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore | ||
120 | ConcurrentMap<UUID, TbProtoQueueMsg<ToCoreMsg>> failedMap = new ConcurrentHashMap<>(); | 120 | ConcurrentMap<UUID, TbProtoQueueMsg<ToCoreMsg>> failedMap = new ConcurrentHashMap<>(); |
121 | CountDownLatch processingTimeoutLatch = new CountDownLatch(1); | 121 | CountDownLatch processingTimeoutLatch = new CountDownLatch(1); |
122 | pendingMap.forEach((id, msg) -> { | 122 | pendingMap.forEach((id, msg) -> { |
123 | - log.info("[{}] Creating main callback for message: {}", id, msg.getValue()); | ||
124 | - TbMsgCallback callback = new MsgPackCallback<>(id, processingTimeoutLatch, pendingMap, new ConcurrentHashMap<>(), failedMap); | 123 | + log.trace("[{}] Creating main callback for message: {}", id, msg.getValue()); |
124 | + TbCallback callback = new TbPackCallback<>(id, processingTimeoutLatch, pendingMap, failedMap); | ||
125 | try { | 125 | try { |
126 | ToCoreMsg toCoreMsg = msg.getValue(); | 126 | ToCoreMsg toCoreMsg = msg.getValue(); |
127 | if (toCoreMsg.hasToSubscriptionMgrMsg()) { | 127 | if (toCoreMsg.hasToSubscriptionMgrMsg()) { |
@@ -182,7 +182,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore | @@ -182,7 +182,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore | ||
182 | } | 182 | } |
183 | 183 | ||
184 | @Override | 184 | @Override |
185 | - protected void handleNotification(UUID id, TbProtoQueueMsg<ToCoreNotificationMsg> msg, TbMsgCallback callback) { | 185 | + protected void handleNotification(UUID id, TbProtoQueueMsg<ToCoreNotificationMsg> msg, TbCallback callback) { |
186 | ToCoreNotificationMsg toCoreMsg = msg.getValue(); | 186 | ToCoreNotificationMsg toCoreMsg = msg.getValue(); |
187 | if (toCoreMsg.hasToLocalSubscriptionServiceMsg()) { | 187 | if (toCoreMsg.hasToLocalSubscriptionServiceMsg()) { |
188 | log.trace("[{}] Forwarding message to local subscription service {}", id, toCoreMsg.getToLocalSubscriptionServiceMsg()); | 188 | log.trace("[{}] Forwarding message to local subscription service {}", id, toCoreMsg.getToLocalSubscriptionServiceMsg()); |
@@ -200,7 +200,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore | @@ -200,7 +200,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore | ||
200 | } | 200 | } |
201 | } | 201 | } |
202 | 202 | ||
203 | - private void forwardToCoreRpcService(FromDeviceRPCResponseProto proto, TbMsgCallback callback) { | 203 | + private void forwardToCoreRpcService(FromDeviceRPCResponseProto proto, TbCallback callback) { |
204 | RpcError error = proto.getError() > 0 ? RpcError.values()[proto.getError()] : null; | 204 | RpcError error = proto.getError() > 0 ? RpcError.values()[proto.getError()] : null; |
205 | FromDeviceRpcResponse response = new FromDeviceRpcResponse(new UUID(proto.getRequestIdMSB(), proto.getRequestIdLSB()) | 205 | FromDeviceRpcResponse response = new FromDeviceRpcResponse(new UUID(proto.getRequestIdMSB(), proto.getRequestIdLSB()) |
206 | , proto.getResponse(), error); | 206 | , proto.getResponse(), error); |
@@ -215,7 +215,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore | @@ -215,7 +215,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore | ||
215 | } | 215 | } |
216 | } | 216 | } |
217 | 217 | ||
218 | - private void forwardToLocalSubMgrService(LocalSubscriptionServiceMsgProto msg, TbMsgCallback callback) { | 218 | + private void forwardToLocalSubMgrService(LocalSubscriptionServiceMsgProto msg, TbCallback callback) { |
219 | if (msg.hasSubUpdate()) { | 219 | if (msg.hasSubUpdate()) { |
220 | localSubscriptionService.onSubscriptionUpdate(msg.getSubUpdate().getSessionId(), TbSubscriptionUtils.fromProto(msg.getSubUpdate()), callback); | 220 | localSubscriptionService.onSubscriptionUpdate(msg.getSubUpdate().getSessionId(), TbSubscriptionUtils.fromProto(msg.getSubUpdate()), callback); |
221 | } else { | 221 | } else { |
@@ -223,7 +223,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore | @@ -223,7 +223,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore | ||
223 | } | 223 | } |
224 | } | 224 | } |
225 | 225 | ||
226 | - private void forwardToSubMgrService(SubscriptionMgrMsgProto msg, TbMsgCallback callback) { | 226 | + private void forwardToSubMgrService(SubscriptionMgrMsgProto msg, TbCallback callback) { |
227 | if (msg.hasAttributeSub()) { | 227 | if (msg.hasAttributeSub()) { |
228 | subscriptionManagerService.addSubscription(TbSubscriptionUtils.fromProto(msg.getAttributeSub()), callback); | 228 | subscriptionManagerService.addSubscription(TbSubscriptionUtils.fromProto(msg.getAttributeSub()), callback); |
229 | } else if (msg.hasTelemetrySub()) { | 229 | } else if (msg.hasTelemetrySub()) { |
@@ -248,21 +248,21 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore | @@ -248,21 +248,21 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore | ||
248 | } | 248 | } |
249 | } | 249 | } |
250 | 250 | ||
251 | - private void forwardToStateService(DeviceStateServiceMsgProto deviceStateServiceMsg, TbMsgCallback callback) { | 251 | + private void forwardToStateService(DeviceStateServiceMsgProto deviceStateServiceMsg, TbCallback callback) { |
252 | if (statsEnabled) { | 252 | if (statsEnabled) { |
253 | stats.log(deviceStateServiceMsg); | 253 | stats.log(deviceStateServiceMsg); |
254 | } | 254 | } |
255 | stateService.onQueueMsg(deviceStateServiceMsg, callback); | 255 | stateService.onQueueMsg(deviceStateServiceMsg, callback); |
256 | } | 256 | } |
257 | 257 | ||
258 | - private void forwardToDeviceActor(TransportToDeviceActorMsg toDeviceActorMsg, TbMsgCallback callback) { | 258 | + private void forwardToDeviceActor(TransportToDeviceActorMsg toDeviceActorMsg, TbCallback callback) { |
259 | if (statsEnabled) { | 259 | if (statsEnabled) { |
260 | stats.log(toDeviceActorMsg); | 260 | stats.log(toDeviceActorMsg); |
261 | } | 261 | } |
262 | actorContext.getAppActor().tell(new TransportToDeviceActorMsgWrapper(toDeviceActorMsg, callback), ActorRef.noSender()); | 262 | actorContext.getAppActor().tell(new TransportToDeviceActorMsgWrapper(toDeviceActorMsg, callback), ActorRef.noSender()); |
263 | } | 263 | } |
264 | 264 | ||
265 | - private void throwNotHandled(Object msg, TbMsgCallback callback) { | 265 | + private void throwNotHandled(Object msg, TbCallback callback) { |
266 | log.warn("Message not handled: {}", msg); | 266 | log.warn("Message not handled: {}", msg); |
267 | callback.onFailure(new RuntimeException("Message not handled!")); | 267 | callback.onFailure(new RuntimeException("Message not handled!")); |
268 | } | 268 | } |
@@ -27,8 +27,11 @@ import org.thingsboard.server.common.data.id.TenantId; | @@ -27,8 +27,11 @@ import org.thingsboard.server.common.data.id.TenantId; | ||
27 | import org.thingsboard.server.common.msg.TbActorMsg; | 27 | import org.thingsboard.server.common.msg.TbActorMsg; |
28 | import org.thingsboard.server.common.msg.TbMsg; | 28 | import org.thingsboard.server.common.msg.TbMsg; |
29 | import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg; | 29 | import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg; |
30 | +import org.thingsboard.server.common.msg.queue.RuleEngineException; | ||
31 | +import org.thingsboard.server.common.msg.queue.RuleNodeException; | ||
30 | import org.thingsboard.server.common.msg.queue.ServiceQueue; | 32 | import org.thingsboard.server.common.msg.queue.ServiceQueue; |
31 | import org.thingsboard.server.common.msg.queue.ServiceType; | 33 | import org.thingsboard.server.common.msg.queue.ServiceType; |
34 | +import org.thingsboard.server.common.msg.queue.TbCallback; | ||
32 | import org.thingsboard.server.common.msg.queue.TbMsgCallback; | 35 | import org.thingsboard.server.common.msg.queue.TbMsgCallback; |
33 | import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; | 36 | import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; |
34 | import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg; | 37 | import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg; |
@@ -45,6 +48,7 @@ import org.thingsboard.server.service.queue.processing.TbRuleEngineProcessingDec | @@ -45,6 +48,7 @@ import org.thingsboard.server.service.queue.processing.TbRuleEngineProcessingDec | ||
45 | import org.thingsboard.server.service.queue.processing.TbRuleEngineProcessingResult; | 48 | import org.thingsboard.server.service.queue.processing.TbRuleEngineProcessingResult; |
46 | import org.thingsboard.server.service.queue.processing.TbRuleEngineProcessingStrategy; | 49 | import org.thingsboard.server.service.queue.processing.TbRuleEngineProcessingStrategy; |
47 | import org.thingsboard.server.service.queue.processing.TbRuleEngineProcessingStrategyFactory; | 50 | import org.thingsboard.server.service.queue.processing.TbRuleEngineProcessingStrategyFactory; |
51 | +import org.thingsboard.server.service.stats.RuleEngineStatisticsService; | ||
48 | 52 | ||
49 | import javax.annotation.PostConstruct; | 53 | import javax.annotation.PostConstruct; |
50 | import java.util.Collections; | 54 | import java.util.Collections; |
@@ -69,20 +73,22 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | @@ -69,20 +73,22 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | ||
69 | private long pollDuration; | 73 | private long pollDuration; |
70 | @Value("${queue.rule-engine.pack-processing-timeout}") | 74 | @Value("${queue.rule-engine.pack-processing-timeout}") |
71 | private long packProcessingTimeout; | 75 | private long packProcessingTimeout; |
72 | - @Value("${queue.rule-engine.stats.enabled:false}") | 76 | + @Value("${queue.rule-engine.stats.enabled:true}") |
73 | private boolean statsEnabled; | 77 | private boolean statsEnabled; |
74 | 78 | ||
75 | - private final TbCoreConsumerStats stats = new TbCoreConsumerStats(); | ||
76 | private final TbRuleEngineProcessingStrategyFactory factory; | 79 | private final TbRuleEngineProcessingStrategyFactory factory; |
77 | private final TbRuleEngineQueueFactory tbRuleEngineQueueFactory; | 80 | private final TbRuleEngineQueueFactory tbRuleEngineQueueFactory; |
78 | private final TbQueueRuleEngineSettings ruleEngineSettings; | 81 | private final TbQueueRuleEngineSettings ruleEngineSettings; |
82 | + private final RuleEngineStatisticsService statisticsService; | ||
79 | private final ConcurrentMap<String, TbQueueConsumer<TbProtoQueueMsg<ToRuleEngineMsg>>> consumers = new ConcurrentHashMap<>(); | 83 | private final ConcurrentMap<String, TbQueueConsumer<TbProtoQueueMsg<ToRuleEngineMsg>>> consumers = new ConcurrentHashMap<>(); |
80 | private final ConcurrentMap<String, TbRuleEngineQueueConfiguration> consumerConfigurations = new ConcurrentHashMap<>(); | 84 | private final ConcurrentMap<String, TbRuleEngineQueueConfiguration> consumerConfigurations = new ConcurrentHashMap<>(); |
85 | + private final ConcurrentMap<String, TbRuleEngineConsumerStats> consumerStats = new ConcurrentHashMap<>(); | ||
81 | 86 | ||
82 | public DefaultTbRuleEngineConsumerService(TbRuleEngineProcessingStrategyFactory factory, TbQueueRuleEngineSettings ruleEngineSettings, | 87 | public DefaultTbRuleEngineConsumerService(TbRuleEngineProcessingStrategyFactory factory, TbQueueRuleEngineSettings ruleEngineSettings, |
83 | - TbRuleEngineQueueFactory tbRuleEngineQueueFactory, | 88 | + TbRuleEngineQueueFactory tbRuleEngineQueueFactory, RuleEngineStatisticsService statisticsService, |
84 | ActorSystemContext actorContext, DataDecodingEncodingService encodingService) { | 89 | ActorSystemContext actorContext, DataDecodingEncodingService encodingService) { |
85 | super(actorContext, encodingService, tbRuleEngineQueueFactory.createToRuleEngineNotificationsMsgConsumer()); | 90 | super(actorContext, encodingService, tbRuleEngineQueueFactory.createToRuleEngineNotificationsMsgConsumer()); |
91 | + this.statisticsService = statisticsService; | ||
86 | this.ruleEngineSettings = ruleEngineSettings; | 92 | this.ruleEngineSettings = ruleEngineSettings; |
87 | this.tbRuleEngineQueueFactory = tbRuleEngineQueueFactory; | 93 | this.tbRuleEngineQueueFactory = tbRuleEngineQueueFactory; |
88 | this.factory = factory; | 94 | this.factory = factory; |
@@ -92,7 +98,9 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | @@ -92,7 +98,9 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | ||
92 | public void init() { | 98 | public void init() { |
93 | super.init("tb-rule-engine-consumer", "tb-rule-engine-notifications-consumer"); | 99 | super.init("tb-rule-engine-consumer", "tb-rule-engine-notifications-consumer"); |
94 | for (TbRuleEngineQueueConfiguration configuration : ruleEngineSettings.getQueues()) { | 100 | for (TbRuleEngineQueueConfiguration configuration : ruleEngineSettings.getQueues()) { |
101 | + consumerConfigurations.putIfAbsent(configuration.getName(), configuration); | ||
95 | consumers.computeIfAbsent(configuration.getName(), queueName -> tbRuleEngineQueueFactory.createToRuleEngineMsgConsumer(configuration)); | 102 | consumers.computeIfAbsent(configuration.getName(), queueName -> tbRuleEngineQueueFactory.createToRuleEngineMsgConsumer(configuration)); |
103 | + consumerStats.put(configuration.getName(), new TbRuleEngineConsumerStats(configuration.getName())); | ||
96 | } | 104 | } |
97 | } | 105 | } |
98 | 106 | ||
@@ -107,7 +115,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | @@ -107,7 +115,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | ||
107 | 115 | ||
108 | @Override | 116 | @Override |
109 | protected void launchMainConsumers() { | 117 | protected void launchMainConsumers() { |
110 | - consumers.forEach((queue, consumer) -> launchConsumer(consumer, consumerConfigurations.get(queue))); | 118 | + consumers.forEach((queue, consumer) -> launchConsumer(consumer, consumerConfigurations.get(queue), consumerStats.get(queue))); |
111 | } | 119 | } |
112 | 120 | ||
113 | @Override | 121 | @Override |
@@ -115,7 +123,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | @@ -115,7 +123,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | ||
115 | consumers.values().forEach(TbQueueConsumer::unsubscribe); | 123 | consumers.values().forEach(TbQueueConsumer::unsubscribe); |
116 | } | 124 | } |
117 | 125 | ||
118 | - private void launchConsumer(TbQueueConsumer<TbProtoQueueMsg<ToRuleEngineMsg>> consumer, TbRuleEngineQueueConfiguration configuration) { | 126 | + private void launchConsumer(TbQueueConsumer<TbProtoQueueMsg<ToRuleEngineMsg>> consumer, TbRuleEngineQueueConfiguration configuration, TbRuleEngineConsumerStats stats) { |
119 | consumersExecutor.execute(() -> { | 127 | consumersExecutor.execute(() -> { |
120 | while (!stopped) { | 128 | while (!stopped) { |
121 | try { | 129 | try { |
@@ -123,7 +131,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | @@ -123,7 +131,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | ||
123 | if (msgs.isEmpty()) { | 131 | if (msgs.isEmpty()) { |
124 | continue; | 132 | continue; |
125 | } | 133 | } |
126 | - TbRuleEngineProcessingStrategy strategy = factory.newInstance(configuration.getAckStrategy()); | 134 | + TbRuleEngineProcessingStrategy strategy = factory.newInstance(configuration.getName(), configuration.getAckStrategy()); |
127 | TbRuleEngineProcessingDecision decision = null; | 135 | TbRuleEngineProcessingDecision decision = null; |
128 | boolean firstAttempt = true; | 136 | boolean firstAttempt = true; |
129 | while (!stopped && (firstAttempt || !decision.isCommit())) { | 137 | while (!stopped && (firstAttempt || !decision.isCommit())) { |
@@ -137,21 +145,21 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | @@ -137,21 +145,21 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | ||
137 | } | 145 | } |
138 | ConcurrentMap<UUID, TbProtoQueueMsg<ToRuleEngineMsg>> successMap = new ConcurrentHashMap<>(); | 146 | ConcurrentMap<UUID, TbProtoQueueMsg<ToRuleEngineMsg>> successMap = new ConcurrentHashMap<>(); |
139 | ConcurrentMap<UUID, TbProtoQueueMsg<ToRuleEngineMsg>> failedMap = new ConcurrentHashMap<>(); | 147 | ConcurrentMap<UUID, TbProtoQueueMsg<ToRuleEngineMsg>> failedMap = new ConcurrentHashMap<>(); |
140 | - | 148 | + ConcurrentMap<TenantId, RuleEngineException> exceptionsMap = new ConcurrentHashMap<>(); |
141 | CountDownLatch processingTimeoutLatch = new CountDownLatch(1); | 149 | CountDownLatch processingTimeoutLatch = new CountDownLatch(1); |
142 | allMap.forEach((id, msg) -> { | 150 | allMap.forEach((id, msg) -> { |
143 | - log.info("[{}] Creating main callback for message: {}", id, msg.getValue()); | ||
144 | - TbMsgCallback callback = new MsgPackCallback<>(id, processingTimeoutLatch, allMap, successMap, failedMap); | 151 | + log.trace("[{}] Creating main callback for message: {}", id, msg.getValue()); |
152 | + ToRuleEngineMsg toRuleEngineMsg = msg.getValue(); | ||
153 | + TenantId tenantId = new TenantId(new UUID(toRuleEngineMsg.getTenantIdMSB(), toRuleEngineMsg.getTenantIdLSB())); | ||
154 | + TbMsgCallback callback = new TbMsgPackCallback<>(id, tenantId, processingTimeoutLatch, allMap, successMap, failedMap, exceptionsMap); | ||
145 | try { | 155 | try { |
146 | - ToRuleEngineMsg toRuleEngineMsg = msg.getValue(); | ||
147 | - TenantId tenantId = new TenantId(new UUID(toRuleEngineMsg.getTenantIdMSB(), toRuleEngineMsg.getTenantIdLSB())); | ||
148 | if (toRuleEngineMsg.getTbMsg() != null && !toRuleEngineMsg.getTbMsg().isEmpty()) { | 156 | if (toRuleEngineMsg.getTbMsg() != null && !toRuleEngineMsg.getTbMsg().isEmpty()) { |
149 | forwardToRuleEngineActor(tenantId, toRuleEngineMsg, callback); | 157 | forwardToRuleEngineActor(tenantId, toRuleEngineMsg, callback); |
150 | } else { | 158 | } else { |
151 | callback.onSuccess(); | 159 | callback.onSuccess(); |
152 | } | 160 | } |
153 | - } catch (Throwable e) { | ||
154 | - callback.onFailure(e); | 161 | + } catch (Exception e) { |
162 | + callback.onFailure(new RuleEngineException(e.getMessage())); | ||
155 | } | 163 | } |
156 | }); | 164 | }); |
157 | 165 | ||
@@ -159,7 +167,11 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | @@ -159,7 +167,11 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | ||
159 | if (!processingTimeoutLatch.await(packProcessingTimeout, TimeUnit.MILLISECONDS)) { | 167 | if (!processingTimeoutLatch.await(packProcessingTimeout, TimeUnit.MILLISECONDS)) { |
160 | timeout = true; | 168 | timeout = true; |
161 | } | 169 | } |
162 | - decision = strategy.analyze(new TbRuleEngineProcessingResult(timeout, allMap, successMap, failedMap)); | 170 | + TbRuleEngineProcessingResult result = new TbRuleEngineProcessingResult(timeout, allMap, successMap, failedMap, exceptionsMap); |
171 | + decision = strategy.analyze(result); | ||
172 | + if (statsEnabled) { | ||
173 | + stats.log(result, decision.isCommit()); | ||
174 | + } | ||
163 | } | 175 | } |
164 | consumer.commit(); | 176 | consumer.commit(); |
165 | } catch (Exception e) { | 177 | } catch (Exception e) { |
@@ -193,7 +205,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | @@ -193,7 +205,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | ||
193 | } | 205 | } |
194 | 206 | ||
195 | @Override | 207 | @Override |
196 | - protected void handleNotification(UUID id, TbProtoQueueMsg<ToRuleEngineNotificationMsg> msg, TbMsgCallback callback) throws Exception { | 208 | + protected void handleNotification(UUID id, TbProtoQueueMsg<ToRuleEngineNotificationMsg> msg, TbCallback callback) throws Exception { |
197 | ToRuleEngineNotificationMsg nfMsg = msg.getValue(); | 209 | ToRuleEngineNotificationMsg nfMsg = msg.getValue(); |
198 | if (nfMsg.getComponentLifecycleMsg() != null && !nfMsg.getComponentLifecycleMsg().isEmpty()) { | 210 | if (nfMsg.getComponentLifecycleMsg() != null && !nfMsg.getComponentLifecycleMsg().isEmpty()) { |
199 | Optional<TbActorMsg> actorMsg = encodingService.decode(nfMsg.getComponentLifecycleMsg().toByteArray()); | 211 | Optional<TbActorMsg> actorMsg = encodingService.decode(nfMsg.getComponentLifecycleMsg().toByteArray()); |
@@ -219,18 +231,18 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | @@ -219,18 +231,18 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | ||
219 | relationTypes = new HashSet<>(relationTypesList); | 231 | relationTypes = new HashSet<>(relationTypesList); |
220 | } | 232 | } |
221 | } | 233 | } |
222 | - msg = new QueueToRuleEngineMsg(tenantId, tbMsg, relationTypes); | 234 | + msg = new QueueToRuleEngineMsg(tenantId, tbMsg, relationTypes, toRuleEngineMsg.getFailureMessage()); |
223 | actorContext.getAppActor().tell(msg, ActorRef.noSender()); | 235 | actorContext.getAppActor().tell(msg, ActorRef.noSender()); |
224 | - //TODO: 2.5 before release. | ||
225 | -// if (statsEnabled) { | ||
226 | -// stats.log(toDeviceActorMsg); | ||
227 | -// } | ||
228 | } | 236 | } |
229 | 237 | ||
230 | @Scheduled(fixedDelayString = "${queue.rule-engine.stats.print-interval-ms}") | 238 | @Scheduled(fixedDelayString = "${queue.rule-engine.stats.print-interval-ms}") |
231 | public void printStats() { | 239 | public void printStats() { |
232 | if (statsEnabled) { | 240 | if (statsEnabled) { |
233 | - stats.printStats(); | 241 | + long ts = System.currentTimeMillis(); |
242 | + consumerStats.forEach((queue, stats) -> { | ||
243 | + stats.printStats(); | ||
244 | + statisticsService.reportQueueStats(ts, stats); | ||
245 | + }); | ||
234 | } | 246 | } |
235 | } | 247 | } |
236 | 248 |
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 lombok.extern.slf4j.Slf4j; | ||
19 | +import org.thingsboard.server.common.data.id.TenantId; | ||
20 | +import org.thingsboard.server.common.msg.queue.RuleEngineException; | ||
21 | +import org.thingsboard.server.common.msg.queue.RuleNodeException; | ||
22 | +import org.thingsboard.server.common.msg.queue.TbCallback; | ||
23 | +import org.thingsboard.server.common.msg.queue.TbMsgCallback; | ||
24 | + | ||
25 | +import java.util.UUID; | ||
26 | +import java.util.concurrent.ConcurrentMap; | ||
27 | +import java.util.concurrent.CountDownLatch; | ||
28 | + | ||
29 | +@Slf4j | ||
30 | +public class TbMsgPackCallback<T> implements TbMsgCallback { | ||
31 | + private final CountDownLatch processingTimeoutLatch; | ||
32 | + private final ConcurrentMap<UUID, T> ackMap; | ||
33 | + private final ConcurrentMap<UUID, T> successMap; | ||
34 | + private final ConcurrentMap<UUID, T> failedMap; | ||
35 | + private final UUID id; | ||
36 | + private final TenantId tenantId; | ||
37 | + private final ConcurrentMap<TenantId, RuleEngineException> firstExceptions; | ||
38 | + | ||
39 | + public TbMsgPackCallback(UUID id, TenantId tenantId, | ||
40 | + CountDownLatch processingTimeoutLatch, | ||
41 | + ConcurrentMap<UUID, T> ackMap, | ||
42 | + ConcurrentMap<UUID, T> successMap, | ||
43 | + ConcurrentMap<UUID, T> failedMap, | ||
44 | + ConcurrentMap<TenantId, RuleEngineException> firstExceptions) { | ||
45 | + this.id = id; | ||
46 | + this.tenantId = tenantId; | ||
47 | + this.processingTimeoutLatch = processingTimeoutLatch; | ||
48 | + this.ackMap = ackMap; | ||
49 | + this.successMap = successMap; | ||
50 | + this.failedMap = failedMap; | ||
51 | + this.firstExceptions = firstExceptions; | ||
52 | + } | ||
53 | + | ||
54 | + @Override | ||
55 | + public void onSuccess() { | ||
56 | + log.trace("[{}] ON SUCCESS", id); | ||
57 | + T msg = ackMap.remove(id); | ||
58 | + if (msg != null) { | ||
59 | + successMap.put(id, msg); | ||
60 | + } | ||
61 | + if (msg != null && ackMap.isEmpty()) { | ||
62 | + processingTimeoutLatch.countDown(); | ||
63 | + } | ||
64 | + } | ||
65 | + | ||
66 | + @Override | ||
67 | + public void onFailure(RuleEngineException e) { | ||
68 | + log.trace("[{}] ON FAILURE", id, e); | ||
69 | + T msg = ackMap.remove(id); | ||
70 | + if (msg != null) { | ||
71 | + failedMap.put(id, msg); | ||
72 | + firstExceptions.putIfAbsent(tenantId, e); | ||
73 | + } | ||
74 | + if (ackMap.isEmpty()) { | ||
75 | + processingTimeoutLatch.countDown(); | ||
76 | + } | ||
77 | + } | ||
78 | +} |
application/src/main/java/org/thingsboard/server/service/queue/TbPackCallback.java
renamed from
application/src/main/java/org/thingsboard/server/service/queue/MsgPackCallback.java
@@ -16,30 +16,26 @@ | @@ -16,30 +16,26 @@ | ||
16 | package org.thingsboard.server.service.queue; | 16 | package org.thingsboard.server.service.queue; |
17 | 17 | ||
18 | import lombok.extern.slf4j.Slf4j; | 18 | import lombok.extern.slf4j.Slf4j; |
19 | -import org.thingsboard.server.common.msg.queue.TbMsgCallback; | ||
20 | -import org.thingsboard.server.queue.common.TbProtoQueueMsg; | 19 | +import org.thingsboard.server.common.msg.queue.TbCallback; |
21 | 20 | ||
22 | import java.util.UUID; | 21 | import java.util.UUID; |
23 | -import java.util.concurrent.ConcurrentHashMap; | ||
24 | import java.util.concurrent.ConcurrentMap; | 22 | import java.util.concurrent.ConcurrentMap; |
25 | import java.util.concurrent.CountDownLatch; | 23 | import java.util.concurrent.CountDownLatch; |
26 | 24 | ||
27 | @Slf4j | 25 | @Slf4j |
28 | -public class MsgPackCallback<T> implements TbMsgCallback { | 26 | +public class TbPackCallback<T> implements TbCallback { |
29 | private final CountDownLatch processingTimeoutLatch; | 27 | private final CountDownLatch processingTimeoutLatch; |
30 | private final ConcurrentMap<UUID, T> ackMap; | 28 | private final ConcurrentMap<UUID, T> ackMap; |
31 | - private final ConcurrentMap<UUID, T> successMap; | ||
32 | private final ConcurrentMap<UUID, T> failedMap; | 29 | private final ConcurrentMap<UUID, T> failedMap; |
33 | private final UUID id; | 30 | private final UUID id; |
34 | 31 | ||
35 | - public MsgPackCallback(UUID id, CountDownLatch processingTimeoutLatch, | ||
36 | - ConcurrentMap<UUID, T> ackMap, | ||
37 | - ConcurrentMap<UUID, T> successMap, | ||
38 | - ConcurrentMap<UUID, T> failedMap) { | 32 | + public TbPackCallback(UUID id, |
33 | + CountDownLatch processingTimeoutLatch, | ||
34 | + ConcurrentMap<UUID, T> ackMap, | ||
35 | + ConcurrentMap<UUID, T> failedMap) { | ||
39 | this.id = id; | 36 | this.id = id; |
40 | this.processingTimeoutLatch = processingTimeoutLatch; | 37 | this.processingTimeoutLatch = processingTimeoutLatch; |
41 | this.ackMap = ackMap; | 38 | this.ackMap = ackMap; |
42 | - this.successMap = successMap; | ||
43 | this.failedMap = failedMap; | 39 | this.failedMap = failedMap; |
44 | } | 40 | } |
45 | 41 | ||
@@ -47,9 +43,6 @@ public class MsgPackCallback<T> implements TbMsgCallback { | @@ -47,9 +43,6 @@ public class MsgPackCallback<T> implements TbMsgCallback { | ||
47 | public void onSuccess() { | 43 | public void onSuccess() { |
48 | log.trace("[{}] ON SUCCESS", id); | 44 | log.trace("[{}] ON SUCCESS", id); |
49 | T msg = ackMap.remove(id); | 45 | T msg = ackMap.remove(id); |
50 | - if (msg != null) { | ||
51 | - successMap.put(id, msg); | ||
52 | - } | ||
53 | if (msg != null && ackMap.isEmpty()) { | 46 | if (msg != null && ackMap.isEmpty()) { |
54 | processingTimeoutLatch.countDown(); | 47 | processingTimeoutLatch.countDown(); |
55 | } | 48 | } |
@@ -57,7 +50,7 @@ public class MsgPackCallback<T> implements TbMsgCallback { | @@ -57,7 +50,7 @@ public class MsgPackCallback<T> implements TbMsgCallback { | ||
57 | 50 | ||
58 | @Override | 51 | @Override |
59 | public void onFailure(Throwable t) { | 52 | public void onFailure(Throwable t) { |
60 | - log.trace("[{}] ON FAILURE", id); | 53 | + log.trace("[{}] ON FAILURE", id, t); |
61 | T msg = ackMap.remove(id); | 54 | T msg = ackMap.remove(id); |
62 | if (msg != null) { | 55 | if (msg != null) { |
63 | failedMap.put(id, msg); | 56 | failedMap.put(id, msg); |
@@ -15,38 +15,119 @@ | @@ -15,38 +15,119 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.service.queue; | 16 | package org.thingsboard.server.service.queue; |
17 | 17 | ||
18 | +import lombok.Data; | ||
18 | import lombok.extern.slf4j.Slf4j; | 19 | import lombok.extern.slf4j.Slf4j; |
19 | -import org.thingsboard.server.gen.transport.TransportProtos; | 20 | +import org.thingsboard.server.common.data.id.TenantId; |
21 | +import org.thingsboard.server.common.msg.queue.RuleEngineException; | ||
22 | +import org.thingsboard.server.common.msg.queue.RuleNodeException; | ||
23 | +import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; | ||
24 | +import org.thingsboard.server.queue.common.TbProtoQueueMsg; | ||
25 | +import org.thingsboard.server.service.queue.processing.TbRuleEngineProcessingResult; | ||
20 | 26 | ||
27 | +import java.util.HashMap; | ||
28 | +import java.util.Map; | ||
29 | +import java.util.UUID; | ||
30 | +import java.util.concurrent.ConcurrentHashMap; | ||
31 | +import java.util.concurrent.ConcurrentMap; | ||
21 | import java.util.concurrent.atomic.AtomicInteger; | 32 | import java.util.concurrent.atomic.AtomicInteger; |
22 | 33 | ||
23 | @Slf4j | 34 | @Slf4j |
35 | +@Data | ||
24 | public class TbRuleEngineConsumerStats { | 36 | public class TbRuleEngineConsumerStats { |
25 | 37 | ||
26 | - private final AtomicInteger totalCounter = new AtomicInteger(0); | ||
27 | - private final AtomicInteger postTelemetryCounter = new AtomicInteger(0); | ||
28 | - private final AtomicInteger postAttributesCounter = new AtomicInteger(0); | ||
29 | - private final AtomicInteger toServerRPCCallRequestCounter = new AtomicInteger(0); | 38 | + public static final String TOTAL_MSGS = "totalMsgs"; |
39 | + public static final String SUCCESSFUL_MSGS = "successfulMsgs"; | ||
40 | + public static final String TMP_TIMEOUT = "tmpTimeout"; | ||
41 | + public static final String TMP_FAILED = "tmpFailed"; | ||
42 | + public static final String TIMEOUT_MSGS = "timeoutMsgs"; | ||
43 | + public static final String FAILED_MSGS = "failedMsgs"; | ||
44 | + public static final String SUCCESSFUL_ITERATIONS = "successfulIterations"; | ||
45 | + public static final String FAILED_ITERATIONS = "failedIterations"; | ||
30 | 46 | ||
31 | - public void log(TransportProtos.TransportToRuleEngineMsg msg) { | ||
32 | - totalCounter.incrementAndGet(); | ||
33 | - if (msg.hasPostTelemetry()) { | ||
34 | - postTelemetryCounter.incrementAndGet(); | ||
35 | - } | ||
36 | - if (msg.hasPostAttributes()) { | ||
37 | - postAttributesCounter.incrementAndGet(); | ||
38 | - } | ||
39 | - if (msg.hasToServerRPCCallRequest()) { | ||
40 | - toServerRPCCallRequestCounter.incrementAndGet(); | 47 | + private final AtomicInteger totalMsgCounter = new AtomicInteger(0); |
48 | + private final AtomicInteger successMsgCounter = new AtomicInteger(0); | ||
49 | + private final AtomicInteger tmpTimeoutMsgCounter = new AtomicInteger(0); | ||
50 | + private final AtomicInteger tmpFailedMsgCounter = new AtomicInteger(0); | ||
51 | + | ||
52 | + private final AtomicInteger timeoutMsgCounter = new AtomicInteger(0); | ||
53 | + private final AtomicInteger failedMsgCounter = new AtomicInteger(0); | ||
54 | + | ||
55 | + private final AtomicInteger successIterationsCounter = new AtomicInteger(0); | ||
56 | + private final AtomicInteger failedIterationsCounter = new AtomicInteger(0); | ||
57 | + | ||
58 | + private final Map<String, AtomicInteger> counters = new HashMap<>(); | ||
59 | + private final ConcurrentMap<UUID, TbTenantRuleEngineStats> tenantStats = new ConcurrentHashMap<>(); | ||
60 | + private final ConcurrentMap<TenantId, RuleEngineException> tenantExceptions = new ConcurrentHashMap<>(); | ||
61 | + | ||
62 | + private final String queueName; | ||
63 | + | ||
64 | + public TbRuleEngineConsumerStats(String queueName) { | ||
65 | + this.queueName = queueName; | ||
66 | + counters.put(TOTAL_MSGS, totalMsgCounter); | ||
67 | + counters.put(SUCCESSFUL_MSGS, successMsgCounter); | ||
68 | + counters.put(TIMEOUT_MSGS, timeoutMsgCounter); | ||
69 | + counters.put(FAILED_MSGS, failedMsgCounter); | ||
70 | + | ||
71 | + counters.put(TMP_TIMEOUT, tmpTimeoutMsgCounter); | ||
72 | + counters.put(TMP_FAILED, tmpFailedMsgCounter); | ||
73 | + counters.put(SUCCESSFUL_ITERATIONS, successIterationsCounter); | ||
74 | + counters.put(FAILED_ITERATIONS, failedIterationsCounter); | ||
75 | + } | ||
76 | + | ||
77 | + public void log(TbRuleEngineProcessingResult msg, boolean finalIterationForPack) { | ||
78 | + int success = msg.getSuccessMap().size(); | ||
79 | + int pending = msg.getPendingMap().size(); | ||
80 | + int failed = msg.getFailureMap().size(); | ||
81 | + totalMsgCounter.addAndGet(success + pending + failed); | ||
82 | + successMsgCounter.addAndGet(success); | ||
83 | + msg.getSuccessMap().values().forEach(m -> getTenantStats(m).logSuccess()); | ||
84 | + if (finalIterationForPack) { | ||
85 | + if (pending > 0 || failed > 0) { | ||
86 | + timeoutMsgCounter.addAndGet(pending); | ||
87 | + failedMsgCounter.addAndGet(failed); | ||
88 | + if (pending > 0) { | ||
89 | + msg.getPendingMap().values().forEach(m -> getTenantStats(m).logTimeout()); | ||
90 | + } | ||
91 | + if (failed > 0) { | ||
92 | + msg.getFailureMap().values().forEach(m -> getTenantStats(m).logFailed()); | ||
93 | + } | ||
94 | + failedIterationsCounter.incrementAndGet(); | ||
95 | + } else { | ||
96 | + successIterationsCounter.incrementAndGet(); | ||
97 | + } | ||
98 | + } else { | ||
99 | + failedIterationsCounter.incrementAndGet(); | ||
100 | + tmpTimeoutMsgCounter.addAndGet(pending); | ||
101 | + tmpFailedMsgCounter.addAndGet(failed); | ||
102 | + if (pending > 0) { | ||
103 | + msg.getPendingMap().values().forEach(m -> getTenantStats(m).logTmpTimeout()); | ||
104 | + } | ||
105 | + if (failed > 0) { | ||
106 | + msg.getFailureMap().values().forEach(m -> getTenantStats(m).logTmpFailed()); | ||
107 | + } | ||
41 | } | 108 | } |
109 | + msg.getExceptionsMap().forEach(tenantExceptions::putIfAbsent); | ||
110 | + } | ||
111 | + | ||
112 | + private TbTenantRuleEngineStats getTenantStats(TbProtoQueueMsg<ToRuleEngineMsg> m) { | ||
113 | + ToRuleEngineMsg reMsg = m.getValue(); | ||
114 | + return tenantStats.computeIfAbsent(new UUID(reMsg.getTenantIdMSB(), reMsg.getTenantIdLSB()), TbTenantRuleEngineStats::new); | ||
42 | } | 115 | } |
43 | 116 | ||
44 | public void printStats() { | 117 | public void printStats() { |
45 | - int total = totalCounter.getAndSet(0); | 118 | + int total = totalMsgCounter.get(); |
46 | if (total > 0) { | 119 | if (total > 0) { |
47 | - log.info("Transport total [{}] telemetry [{}] attributes [{}] toServerRpc [{}]", | ||
48 | - total, postTelemetryCounter.getAndSet(0), | ||
49 | - postAttributesCounter.getAndSet(0), toServerRPCCallRequestCounter.getAndSet(0)); | 120 | + StringBuilder stats = new StringBuilder(); |
121 | + counters.forEach((label, value) -> { | ||
122 | + stats.append(label).append(" = [").append(value.get()).append("] "); | ||
123 | + }); | ||
124 | + log.info("[{}] Stats: {}", queueName, stats); | ||
50 | } | 125 | } |
51 | } | 126 | } |
127 | + | ||
128 | + public void reset() { | ||
129 | + counters.values().forEach(counter -> counter.set(0)); | ||
130 | + tenantStats.clear(); | ||
131 | + tenantExceptions.clear(); | ||
132 | + } | ||
52 | } | 133 | } |
application/src/main/java/org/thingsboard/server/service/queue/TbTenantRuleEngineStats.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 lombok.Data; | ||
19 | +import lombok.extern.slf4j.Slf4j; | ||
20 | + | ||
21 | +import java.util.HashMap; | ||
22 | +import java.util.Map; | ||
23 | +import java.util.UUID; | ||
24 | +import java.util.concurrent.atomic.AtomicInteger; | ||
25 | + | ||
26 | +@Slf4j | ||
27 | +@Data | ||
28 | +public class TbTenantRuleEngineStats { | ||
29 | + | ||
30 | + private final UUID tenantId; | ||
31 | + | ||
32 | + private final AtomicInteger totalMsgCounter = new AtomicInteger(0); | ||
33 | + private final AtomicInteger successMsgCounter = new AtomicInteger(0); | ||
34 | + private final AtomicInteger tmpTimeoutMsgCounter = new AtomicInteger(0); | ||
35 | + private final AtomicInteger tmpFailedMsgCounter = new AtomicInteger(0); | ||
36 | + | ||
37 | + private final AtomicInteger timeoutMsgCounter = new AtomicInteger(0); | ||
38 | + private final AtomicInteger failedMsgCounter = new AtomicInteger(0); | ||
39 | + | ||
40 | + private final Map<String, AtomicInteger> counters = new HashMap<>(); | ||
41 | + | ||
42 | + public TbTenantRuleEngineStats(UUID tenantId) { | ||
43 | + this.tenantId = tenantId; | ||
44 | + counters.put(TbRuleEngineConsumerStats.TOTAL_MSGS, totalMsgCounter); | ||
45 | + counters.put(TbRuleEngineConsumerStats.SUCCESSFUL_MSGS, successMsgCounter); | ||
46 | + counters.put(TbRuleEngineConsumerStats.TIMEOUT_MSGS, timeoutMsgCounter); | ||
47 | + counters.put(TbRuleEngineConsumerStats.FAILED_MSGS, failedMsgCounter); | ||
48 | + | ||
49 | + counters.put(TbRuleEngineConsumerStats.TMP_TIMEOUT, tmpTimeoutMsgCounter); | ||
50 | + counters.put(TbRuleEngineConsumerStats.TMP_FAILED, tmpFailedMsgCounter); | ||
51 | + } | ||
52 | + | ||
53 | + public void logSuccess() { | ||
54 | + totalMsgCounter.incrementAndGet(); | ||
55 | + successMsgCounter.incrementAndGet(); | ||
56 | + } | ||
57 | + | ||
58 | + public void logFailed() { | ||
59 | + totalMsgCounter.incrementAndGet(); | ||
60 | + failedMsgCounter.incrementAndGet(); | ||
61 | + } | ||
62 | + | ||
63 | + public void logTimeout() { | ||
64 | + totalMsgCounter.incrementAndGet(); | ||
65 | + timeoutMsgCounter.incrementAndGet(); | ||
66 | + } | ||
67 | + | ||
68 | + public void logTmpFailed() { | ||
69 | + totalMsgCounter.incrementAndGet(); | ||
70 | + tmpFailedMsgCounter.incrementAndGet(); | ||
71 | + } | ||
72 | + | ||
73 | + public void logTmpTimeout() { | ||
74 | + totalMsgCounter.incrementAndGet(); | ||
75 | + tmpTimeoutMsgCounter.incrementAndGet(); | ||
76 | + } | ||
77 | + | ||
78 | + public void printStats() { | ||
79 | + int total = totalMsgCounter.get(); | ||
80 | + if (total > 0) { | ||
81 | + StringBuilder stats = new StringBuilder(); | ||
82 | + counters.forEach((label, value) -> { | ||
83 | + stats.append(label).append(" = [").append(value.get()).append("]"); | ||
84 | + }); | ||
85 | + log.info("[{}] Stats: {}", tenantId, stats); | ||
86 | + } | ||
87 | + } | ||
88 | + | ||
89 | + public void reset() { | ||
90 | + counters.values().forEach(counter -> counter.set(0)); | ||
91 | + } | ||
92 | +} |
@@ -22,12 +22,12 @@ import org.springframework.context.event.EventListener; | @@ -22,12 +22,12 @@ import org.springframework.context.event.EventListener; | ||
22 | import org.thingsboard.common.util.ThingsBoardThreadFactory; | 22 | import org.thingsboard.common.util.ThingsBoardThreadFactory; |
23 | import org.thingsboard.server.actors.ActorSystemContext; | 23 | import org.thingsboard.server.actors.ActorSystemContext; |
24 | import org.thingsboard.server.common.msg.queue.ServiceType; | 24 | import org.thingsboard.server.common.msg.queue.ServiceType; |
25 | -import org.thingsboard.server.common.msg.queue.TbMsgCallback; | 25 | +import org.thingsboard.server.common.msg.queue.TbCallback; |
26 | import org.thingsboard.server.queue.TbQueueConsumer; | 26 | import org.thingsboard.server.queue.TbQueueConsumer; |
27 | import org.thingsboard.server.queue.common.TbProtoQueueMsg; | 27 | import org.thingsboard.server.queue.common.TbProtoQueueMsg; |
28 | import org.thingsboard.server.queue.discovery.PartitionChangeEvent; | 28 | import org.thingsboard.server.queue.discovery.PartitionChangeEvent; |
29 | import org.thingsboard.server.service.encoding.DataDecodingEncodingService; | 29 | import org.thingsboard.server.service.encoding.DataDecodingEncodingService; |
30 | -import org.thingsboard.server.service.queue.MsgPackCallback; | 30 | +import org.thingsboard.server.service.queue.TbPackCallback; |
31 | 31 | ||
32 | import javax.annotation.PreDestroy; | 32 | import javax.annotation.PreDestroy; |
33 | import java.util.List; | 33 | import java.util.List; |
@@ -95,8 +95,8 @@ public abstract class AbstractConsumerService<N extends com.google.protobuf.Gene | @@ -95,8 +95,8 @@ public abstract class AbstractConsumerService<N extends com.google.protobuf.Gene | ||
95 | ConcurrentMap<UUID, TbProtoQueueMsg<N>> failedMap = new ConcurrentHashMap<>(); | 95 | ConcurrentMap<UUID, TbProtoQueueMsg<N>> failedMap = new ConcurrentHashMap<>(); |
96 | CountDownLatch processingTimeoutLatch = new CountDownLatch(1); | 96 | CountDownLatch processingTimeoutLatch = new CountDownLatch(1); |
97 | pendingMap.forEach((id, msg) -> { | 97 | pendingMap.forEach((id, msg) -> { |
98 | - log.info("[{}] Creating notification callback for message: {}", id, msg.getValue()); | ||
99 | - TbMsgCallback callback = new MsgPackCallback<>(id, processingTimeoutLatch, pendingMap, new ConcurrentHashMap<>(), failedMap); | 98 | + log.trace("[{}] Creating notification callback for message: {}", id, msg.getValue()); |
99 | + TbCallback callback = new TbPackCallback<>(id, processingTimeoutLatch, pendingMap, failedMap); | ||
100 | try { | 100 | try { |
101 | handleNotification(id, msg, callback); | 101 | handleNotification(id, msg, callback); |
102 | } catch (Throwable e) { | 102 | } catch (Throwable e) { |
@@ -124,7 +124,7 @@ public abstract class AbstractConsumerService<N extends com.google.protobuf.Gene | @@ -124,7 +124,7 @@ public abstract class AbstractConsumerService<N extends com.google.protobuf.Gene | ||
124 | }); | 124 | }); |
125 | } | 125 | } |
126 | 126 | ||
127 | - protected abstract void handleNotification(UUID id, TbProtoQueueMsg<N> msg, TbMsgCallback callback) throws Exception; | 127 | + protected abstract void handleNotification(UUID id, TbProtoQueueMsg<N> msg, TbCallback callback) throws Exception; |
128 | 128 | ||
129 | @PreDestroy | 129 | @PreDestroy |
130 | public void destroy() { | 130 | public void destroy() { |
@@ -16,6 +16,8 @@ | @@ -16,6 +16,8 @@ | ||
16 | package org.thingsboard.server.service.queue.processing; | 16 | package org.thingsboard.server.service.queue.processing; |
17 | 17 | ||
18 | import lombok.Getter; | 18 | import lombok.Getter; |
19 | +import org.thingsboard.server.common.data.id.TenantId; | ||
20 | +import org.thingsboard.server.common.msg.queue.RuleEngineException; | ||
19 | import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; | 21 | import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; |
20 | import org.thingsboard.server.queue.common.TbProtoQueueMsg; | 22 | import org.thingsboard.server.queue.common.TbProtoQueueMsg; |
21 | 23 | ||
@@ -25,24 +27,28 @@ import java.util.concurrent.ConcurrentMap; | @@ -25,24 +27,28 @@ import java.util.concurrent.ConcurrentMap; | ||
25 | public class TbRuleEngineProcessingResult { | 27 | public class TbRuleEngineProcessingResult { |
26 | 28 | ||
27 | @Getter | 29 | @Getter |
28 | - private boolean success; | 30 | + private final boolean success; |
29 | @Getter | 31 | @Getter |
30 | - private boolean timeout; | 32 | + private final boolean timeout; |
31 | @Getter | 33 | @Getter |
32 | - private ConcurrentMap<UUID, TbProtoQueueMsg<ToRuleEngineMsg>> pendingMap; | 34 | + private final ConcurrentMap<UUID, TbProtoQueueMsg<ToRuleEngineMsg>> pendingMap; |
33 | @Getter | 35 | @Getter |
34 | - private ConcurrentMap<UUID, TbProtoQueueMsg<ToRuleEngineMsg>> successMap; | 36 | + private final ConcurrentMap<UUID, TbProtoQueueMsg<ToRuleEngineMsg>> successMap; |
35 | @Getter | 37 | @Getter |
36 | - private ConcurrentMap<UUID, TbProtoQueueMsg<ToRuleEngineMsg>> failureMap; | 38 | + private final ConcurrentMap<UUID, TbProtoQueueMsg<ToRuleEngineMsg>> failureMap; |
39 | + @Getter | ||
40 | + private final ConcurrentMap<TenantId, RuleEngineException> exceptionsMap; | ||
37 | 41 | ||
38 | public TbRuleEngineProcessingResult(boolean timeout, | 42 | public TbRuleEngineProcessingResult(boolean timeout, |
39 | ConcurrentMap<UUID, TbProtoQueueMsg<ToRuleEngineMsg>> pendingMap, | 43 | ConcurrentMap<UUID, TbProtoQueueMsg<ToRuleEngineMsg>> pendingMap, |
40 | ConcurrentMap<UUID, TbProtoQueueMsg<ToRuleEngineMsg>> successMap, | 44 | ConcurrentMap<UUID, TbProtoQueueMsg<ToRuleEngineMsg>> successMap, |
41 | - ConcurrentMap<UUID, TbProtoQueueMsg<ToRuleEngineMsg>> failureMap) { | 45 | + ConcurrentMap<UUID, TbProtoQueueMsg<ToRuleEngineMsg>> failureMap, |
46 | + ConcurrentMap<TenantId, RuleEngineException> exceptionsMap) { | ||
42 | this.timeout = timeout; | 47 | this.timeout = timeout; |
43 | this.pendingMap = pendingMap; | 48 | this.pendingMap = pendingMap; |
44 | this.successMap = successMap; | 49 | this.successMap = successMap; |
45 | this.failureMap = failureMap; | 50 | this.failureMap = failureMap; |
51 | + this.exceptionsMap = exceptionsMap; | ||
46 | this.success = !timeout && pendingMap.isEmpty() && failureMap.isEmpty(); | 52 | this.success = !timeout && pendingMap.isEmpty() && failureMap.isEmpty(); |
47 | } | 53 | } |
48 | } | 54 | } |
@@ -32,24 +32,25 @@ import java.util.concurrent.TimeUnit; | @@ -32,24 +32,25 @@ import java.util.concurrent.TimeUnit; | ||
32 | @Slf4j | 32 | @Slf4j |
33 | public class TbRuleEngineProcessingStrategyFactory { | 33 | public class TbRuleEngineProcessingStrategyFactory { |
34 | 34 | ||
35 | - public TbRuleEngineProcessingStrategy newInstance(TbRuleEngineQueueAckStrategyConfiguration configuration) { | 35 | + public TbRuleEngineProcessingStrategy newInstance(String name, TbRuleEngineQueueAckStrategyConfiguration configuration) { |
36 | switch (configuration.getType()) { | 36 | switch (configuration.getType()) { |
37 | case "SKIP_ALL": | 37 | case "SKIP_ALL": |
38 | - return new SkipStrategy(); | 38 | + return new SkipStrategy(name); |
39 | case "RETRY_ALL": | 39 | case "RETRY_ALL": |
40 | - return new RetryStrategy(true, true, true, configuration); | 40 | + return new RetryStrategy(name, true, true, true, configuration); |
41 | case "RETRY_FAILED": | 41 | case "RETRY_FAILED": |
42 | - return new RetryStrategy(false, true, false, configuration); | 42 | + return new RetryStrategy(name, false, true, false, configuration); |
43 | case "RETRY_TIMED_OUT": | 43 | case "RETRY_TIMED_OUT": |
44 | - return new RetryStrategy(false, false, true, configuration); | 44 | + return new RetryStrategy(name, false, false, true, configuration); |
45 | case "RETRY_FAILED_AND_TIMED_OUT": | 45 | case "RETRY_FAILED_AND_TIMED_OUT": |
46 | - return new RetryStrategy(false, true, true, configuration); | 46 | + return new RetryStrategy(name, false, true, true, configuration); |
47 | default: | 47 | default: |
48 | throw new RuntimeException("TbRuleEngineProcessingStrategy with type " + configuration.getType() + " is not supported!"); | 48 | throw new RuntimeException("TbRuleEngineProcessingStrategy with type " + configuration.getType() + " is not supported!"); |
49 | } | 49 | } |
50 | } | 50 | } |
51 | 51 | ||
52 | private static class RetryStrategy implements TbRuleEngineProcessingStrategy { | 52 | private static class RetryStrategy implements TbRuleEngineProcessingStrategy { |
53 | + private final String queueName; | ||
53 | private final boolean retrySuccessful; | 54 | private final boolean retrySuccessful; |
54 | private final boolean retryFailed; | 55 | private final boolean retryFailed; |
55 | private final boolean retryTimeout; | 56 | private final boolean retryTimeout; |
@@ -60,7 +61,8 @@ public class TbRuleEngineProcessingStrategyFactory { | @@ -60,7 +61,8 @@ public class TbRuleEngineProcessingStrategyFactory { | ||
60 | private int initialTotalCount; | 61 | private int initialTotalCount; |
61 | private int retryCount; | 62 | private int retryCount; |
62 | 63 | ||
63 | - public RetryStrategy(boolean retrySuccessful, boolean retryFailed, boolean retryTimeout, TbRuleEngineQueueAckStrategyConfiguration configuration) { | 64 | + public RetryStrategy(String queueName, boolean retrySuccessful, boolean retryFailed, boolean retryTimeout, TbRuleEngineQueueAckStrategyConfiguration configuration) { |
65 | + this.queueName = queueName; | ||
64 | this.retrySuccessful = retrySuccessful; | 66 | this.retrySuccessful = retrySuccessful; |
65 | this.retryFailed = retryFailed; | 67 | this.retryFailed = retryFailed; |
66 | this.retryTimeout = retryTimeout; | 68 | this.retryTimeout = retryTimeout; |
@@ -80,10 +82,10 @@ public class TbRuleEngineProcessingStrategyFactory { | @@ -80,10 +82,10 @@ public class TbRuleEngineProcessingStrategyFactory { | ||
80 | retryCount++; | 82 | retryCount++; |
81 | double failedCount = result.getFailureMap().size() + result.getPendingMap().size(); | 83 | double failedCount = result.getFailureMap().size() + result.getPendingMap().size(); |
82 | if (maxRetries > 0 && retryCount > maxRetries) { | 84 | if (maxRetries > 0 && retryCount > maxRetries) { |
83 | - log.info("Skip reprocess of the rule engine pack due to max retries"); | 85 | + log.info("[{}] Skip reprocess of the rule engine pack due to max retries", queueName); |
84 | return new TbRuleEngineProcessingDecision(true, null); | 86 | return new TbRuleEngineProcessingDecision(true, null); |
85 | } else if (maxAllowedFailurePercentage > 0 && (failedCount / initialTotalCount) > maxAllowedFailurePercentage) { | 87 | } else if (maxAllowedFailurePercentage > 0 && (failedCount / initialTotalCount) > maxAllowedFailurePercentage) { |
86 | - log.info("Skip reprocess of the rule engine pack due to max allowed failure percentage"); | 88 | + log.info("[{}] Skip reprocess of the rule engine pack due to max allowed failure percentage", queueName); |
87 | return new TbRuleEngineProcessingDecision(true, null); | 89 | return new TbRuleEngineProcessingDecision(true, null); |
88 | } else { | 90 | } else { |
89 | ConcurrentMap<UUID, TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> toReprocess = new ConcurrentHashMap<>(initialTotalCount); | 91 | ConcurrentMap<UUID, TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> toReprocess = new ConcurrentHashMap<>(initialTotalCount); |
@@ -96,8 +98,7 @@ public class TbRuleEngineProcessingStrategyFactory { | @@ -96,8 +98,7 @@ public class TbRuleEngineProcessingStrategyFactory { | ||
96 | if (retrySuccessful) { | 98 | if (retrySuccessful) { |
97 | result.getSuccessMap().forEach(toReprocess::put); | 99 | result.getSuccessMap().forEach(toReprocess::put); |
98 | } | 100 | } |
99 | - log.info("Going to reprocess {} messages", toReprocess.size()); | ||
100 | - //TODO: 2.5 Log most popular rule nodes by error count; | 101 | + log.info("[{}] Going to reprocess {} messages", queueName, toReprocess.size()); |
101 | if (log.isTraceEnabled()) { | 102 | if (log.isTraceEnabled()) { |
102 | toReprocess.forEach((id, msg) -> log.trace("Going to reprocess [{}]: {}", id, msg.getValue())); | 103 | toReprocess.forEach((id, msg) -> log.trace("Going to reprocess [{}]: {}", id, msg.getValue())); |
103 | } | 104 | } |
@@ -116,9 +117,15 @@ public class TbRuleEngineProcessingStrategyFactory { | @@ -116,9 +117,15 @@ public class TbRuleEngineProcessingStrategyFactory { | ||
116 | 117 | ||
117 | private static class SkipStrategy implements TbRuleEngineProcessingStrategy { | 118 | private static class SkipStrategy implements TbRuleEngineProcessingStrategy { |
118 | 119 | ||
120 | + private final String queueName; | ||
121 | + | ||
122 | + public SkipStrategy(String name) { | ||
123 | + this.queueName = name; | ||
124 | + } | ||
125 | + | ||
119 | @Override | 126 | @Override |
120 | public TbRuleEngineProcessingDecision analyze(TbRuleEngineProcessingResult result) { | 127 | public TbRuleEngineProcessingDecision analyze(TbRuleEngineProcessingResult result) { |
121 | - log.info("Skip reprocess of the rule engine pack"); | 128 | + log.info("[{}] Reprocessing skipped for {} failed and {} timeout messages", queueName, result.getFailureMap().size(), result.getPendingMap().size()); |
122 | return new TbRuleEngineProcessingDecision(true, null); | 129 | return new TbRuleEngineProcessingDecision(true, null); |
123 | } | 130 | } |
124 | } | 131 | } |
@@ -19,7 +19,6 @@ import lombok.Getter; | @@ -19,7 +19,6 @@ import lombok.Getter; | ||
19 | import lombok.RequiredArgsConstructor; | 19 | import lombok.RequiredArgsConstructor; |
20 | import lombok.ToString; | 20 | import lombok.ToString; |
21 | import org.thingsboard.rule.engine.api.RpcError; | 21 | import org.thingsboard.rule.engine.api.RpcError; |
22 | -import org.thingsboard.server.common.msg.cluster.ServerAddress; | ||
23 | 22 | ||
24 | import java.util.Optional; | 23 | import java.util.Optional; |
25 | import java.util.UUID; | 24 | import java.util.UUID; |
@@ -22,11 +22,8 @@ import org.thingsboard.rule.engine.api.msg.ToDeviceActorNotificationMsg; | @@ -22,11 +22,8 @@ import org.thingsboard.rule.engine.api.msg.ToDeviceActorNotificationMsg; | ||
22 | import org.thingsboard.server.common.data.id.DeviceId; | 22 | import org.thingsboard.server.common.data.id.DeviceId; |
23 | import org.thingsboard.server.common.data.id.TenantId; | 23 | import org.thingsboard.server.common.data.id.TenantId; |
24 | import org.thingsboard.server.common.msg.MsgType; | 24 | import org.thingsboard.server.common.msg.MsgType; |
25 | -import org.thingsboard.server.common.msg.cluster.ServerAddress; | ||
26 | import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest; | 25 | import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest; |
27 | 26 | ||
28 | -import java.util.Optional; | ||
29 | - | ||
30 | /** | 27 | /** |
31 | * Created by ashvayka on 16.04.18. | 28 | * Created by ashvayka on 16.04.18. |
32 | */ | 29 | */ |
@@ -55,7 +55,7 @@ import org.thingsboard.server.queue.discovery.PartitionService; | @@ -55,7 +55,7 @@ import org.thingsboard.server.queue.discovery.PartitionService; | ||
55 | import org.thingsboard.server.common.msg.queue.ServiceType; | 55 | import org.thingsboard.server.common.msg.queue.ServiceType; |
56 | import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; | 56 | import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; |
57 | import org.thingsboard.server.gen.transport.TransportProtos; | 57 | import org.thingsboard.server.gen.transport.TransportProtos; |
58 | -import org.thingsboard.server.common.msg.queue.TbMsgCallback; | 58 | +import org.thingsboard.server.common.msg.queue.TbCallback; |
59 | import org.thingsboard.server.queue.provider.TbQueueProducerProvider; | 59 | import org.thingsboard.server.queue.provider.TbQueueProducerProvider; |
60 | import org.thingsboard.server.queue.util.TbCoreComponent; | 60 | import org.thingsboard.server.queue.util.TbCoreComponent; |
61 | import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService; | 61 | import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService; |
@@ -242,7 +242,7 @@ public class DefaultDeviceStateService implements DeviceStateService { | @@ -242,7 +242,7 @@ public class DefaultDeviceStateService implements DeviceStateService { | ||
242 | } | 242 | } |
243 | 243 | ||
244 | @Override | 244 | @Override |
245 | - public void onQueueMsg(TransportProtos.DeviceStateServiceMsgProto proto, TbMsgCallback callback) { | 245 | + public void onQueueMsg(TransportProtos.DeviceStateServiceMsgProto proto, TbCallback callback) { |
246 | try { | 246 | try { |
247 | TenantId tenantId = new TenantId(new UUID(proto.getTenantIdMSB(), proto.getTenantIdLSB())); | 247 | TenantId tenantId = new TenantId(new UUID(proto.getTenantIdMSB(), proto.getTenantIdLSB())); |
248 | DeviceId deviceId = new DeviceId(new UUID(proto.getDeviceIdMSB(), proto.getDeviceIdLSB())); | 248 | DeviceId deviceId = new DeviceId(new UUID(proto.getDeviceIdMSB(), proto.getDeviceIdLSB())); |
@@ -20,7 +20,7 @@ import org.thingsboard.server.common.data.Device; | @@ -20,7 +20,7 @@ import org.thingsboard.server.common.data.Device; | ||
20 | import org.thingsboard.server.common.data.id.DeviceId; | 20 | import org.thingsboard.server.common.data.id.DeviceId; |
21 | import org.thingsboard.server.queue.discovery.PartitionChangeEvent; | 21 | import org.thingsboard.server.queue.discovery.PartitionChangeEvent; |
22 | import org.thingsboard.server.gen.transport.TransportProtos; | 22 | import org.thingsboard.server.gen.transport.TransportProtos; |
23 | -import org.thingsboard.server.common.msg.queue.TbMsgCallback; | 23 | +import org.thingsboard.server.common.msg.queue.TbCallback; |
24 | 24 | ||
25 | /** | 25 | /** |
26 | * Created by ashvayka on 01.05.18. | 26 | * Created by ashvayka on 01.05.18. |
@@ -41,6 +41,6 @@ public interface DeviceStateService extends ApplicationListener<PartitionChangeE | @@ -41,6 +41,6 @@ public interface DeviceStateService extends ApplicationListener<PartitionChangeE | ||
41 | 41 | ||
42 | void onDeviceInactivityTimeoutUpdate(DeviceId deviceId, long inactivityTimeout); | 42 | void onDeviceInactivityTimeoutUpdate(DeviceId deviceId, long inactivityTimeout); |
43 | 43 | ||
44 | - void onQueueMsg(TransportProtos.DeviceStateServiceMsgProto serverAddress, TbMsgCallback bytes); | 44 | + void onQueueMsg(TransportProtos.DeviceStateServiceMsgProto serverAddress, TbCallback bytes); |
45 | 45 | ||
46 | } | 46 | } |
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.stats; | ||
17 | + | ||
18 | +import com.google.common.util.concurrent.FutureCallback; | ||
19 | +import lombok.Data; | ||
20 | +import lombok.extern.slf4j.Slf4j; | ||
21 | +import org.springframework.stereotype.Service; | ||
22 | +import org.thingsboard.server.common.data.asset.Asset; | ||
23 | +import org.thingsboard.server.common.data.id.AssetId; | ||
24 | +import org.thingsboard.server.common.data.id.TenantId; | ||
25 | +import org.thingsboard.server.common.data.kv.BasicTsKvEntry; | ||
26 | +import org.thingsboard.server.common.data.kv.JsonDataEntry; | ||
27 | +import org.thingsboard.server.common.data.kv.LongDataEntry; | ||
28 | +import org.thingsboard.server.common.data.kv.TsKvEntry; | ||
29 | +import org.thingsboard.server.dao.asset.AssetService; | ||
30 | +import org.thingsboard.server.queue.discovery.TbServiceInfoProvider; | ||
31 | +import org.thingsboard.server.queue.util.TbRuleEngineComponent; | ||
32 | +import org.thingsboard.server.service.queue.TbRuleEngineConsumerStats; | ||
33 | +import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService; | ||
34 | + | ||
35 | +import javax.annotation.Nullable; | ||
36 | +import java.util.Collections; | ||
37 | +import java.util.List; | ||
38 | +import java.util.concurrent.ConcurrentHashMap; | ||
39 | +import java.util.concurrent.ConcurrentMap; | ||
40 | +import java.util.concurrent.locks.Lock; | ||
41 | +import java.util.concurrent.locks.ReentrantLock; | ||
42 | +import java.util.stream.Collectors; | ||
43 | + | ||
44 | +@TbRuleEngineComponent | ||
45 | +@Service | ||
46 | +@Slf4j | ||
47 | +public class DefaultRuleEngineStatisticsService implements RuleEngineStatisticsService { | ||
48 | + | ||
49 | + public static final FutureCallback<Void> CALLBACK = new FutureCallback<Void>() { | ||
50 | + @Override | ||
51 | + public void onSuccess(@Nullable Void result) { | ||
52 | + | ||
53 | + } | ||
54 | + | ||
55 | + @Override | ||
56 | + public void onFailure(Throwable t) { | ||
57 | + log.warn("Failed to persist statistics", t); | ||
58 | + } | ||
59 | + }; | ||
60 | + | ||
61 | + private final TbServiceInfoProvider serviceInfoProvider; | ||
62 | + private final TelemetrySubscriptionService tsService; | ||
63 | + private final Lock lock = new ReentrantLock(); | ||
64 | + private final AssetService assetService; | ||
65 | + private final ConcurrentMap<TenantQueueKey, AssetId> tenantQueueAssets; | ||
66 | + | ||
67 | + public DefaultRuleEngineStatisticsService(TelemetrySubscriptionService tsService, TbServiceInfoProvider serviceInfoProvider, AssetService assetService) { | ||
68 | + this.tsService = tsService; | ||
69 | + this.serviceInfoProvider = serviceInfoProvider; | ||
70 | + this.assetService = assetService; | ||
71 | + this.tenantQueueAssets = new ConcurrentHashMap<>(); | ||
72 | + } | ||
73 | + | ||
74 | + @Override | ||
75 | + public void reportQueueStats(long ts, TbRuleEngineConsumerStats ruleEngineStats) { | ||
76 | + String queueName = ruleEngineStats.getQueueName(); | ||
77 | + ruleEngineStats.getTenantStats().forEach((id, stats) -> { | ||
78 | + TenantId tenantId = new TenantId(id); | ||
79 | + AssetId serviceAssetId = getServiceAssetId(tenantId, queueName); | ||
80 | + if (stats.getTotalMsgCounter().get() > 0) { | ||
81 | + List<TsKvEntry> tsList = stats.getCounters().entrySet().stream() | ||
82 | + .map(kv -> new BasicTsKvEntry(ts, new LongDataEntry(kv.getKey(), (long) kv.getValue().get()))) | ||
83 | + .collect(Collectors.toList()); | ||
84 | + if (!tsList.isEmpty()) { | ||
85 | + tsService.saveAndNotify(tenantId, serviceAssetId, tsList, CALLBACK); | ||
86 | + } | ||
87 | + } | ||
88 | + }); | ||
89 | + ruleEngineStats.getTenantExceptions().forEach((tenantId, e) -> { | ||
90 | + TsKvEntry tsKv = new BasicTsKvEntry(ts, new JsonDataEntry("ruleEngineException", e.toJsonString())); | ||
91 | + tsService.saveAndNotify(tenantId, getServiceAssetId(tenantId, queueName), Collections.singletonList(tsKv), CALLBACK); | ||
92 | + }); | ||
93 | + ruleEngineStats.reset(); | ||
94 | + } | ||
95 | + | ||
96 | + private AssetId getServiceAssetId(TenantId tenantId, String queueName) { | ||
97 | + TenantQueueKey key = new TenantQueueKey(tenantId, queueName); | ||
98 | + AssetId assetId = tenantQueueAssets.get(key); | ||
99 | + if (assetId == null) { | ||
100 | + lock.lock(); | ||
101 | + try { | ||
102 | + assetId = tenantQueueAssets.get(key); | ||
103 | + if (assetId == null) { | ||
104 | + Asset asset = assetService.findAssetByTenantIdAndName(tenantId, queueName + "_" + serviceInfoProvider.getServiceId()); | ||
105 | + if (asset == null) { | ||
106 | + asset = new Asset(); | ||
107 | + asset.setTenantId(tenantId); | ||
108 | + asset.setName(queueName + "_" + serviceInfoProvider.getServiceId()); | ||
109 | + asset.setType("TbServiceQueue"); | ||
110 | + asset = assetService.saveAsset(asset); | ||
111 | + } | ||
112 | + assetId = asset.getId(); | ||
113 | + tenantQueueAssets.put(key, assetId); | ||
114 | + } | ||
115 | + } finally { | ||
116 | + lock.unlock(); | ||
117 | + } | ||
118 | + } | ||
119 | + return assetId; | ||
120 | + } | ||
121 | + | ||
122 | + @Data | ||
123 | + private static class TenantQueueKey { | ||
124 | + private final TenantId tenantId; | ||
125 | + private final String queueName; | ||
126 | + } | ||
127 | +} |
application/src/main/java/org/thingsboard/server/service/stats/RuleEngineStatisticsService.java
renamed from
common/message/src/main/java/org/thingsboard/server/common/msg/cluster/ServerType.java
@@ -13,11 +13,11 @@ | @@ -13,11 +13,11 @@ | ||
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | -package org.thingsboard.server.common.msg.cluster; | 16 | +package org.thingsboard.server.service.stats; |
17 | 17 | ||
18 | -/** | ||
19 | - * Created by ashvayka on 23.09.18. | ||
20 | - */ | ||
21 | -public enum ServerType { | ||
22 | - CORE | 18 | +import org.thingsboard.server.service.queue.TbRuleEngineConsumerStats; |
19 | + | ||
20 | +public interface RuleEngineStatisticsService { | ||
21 | + | ||
22 | + void reportQueueStats(long ts, TbRuleEngineConsumerStats stats); | ||
23 | } | 23 | } |
@@ -34,7 +34,7 @@ import org.thingsboard.server.common.data.kv.BasicTsKvEntry; | @@ -34,7 +34,7 @@ import org.thingsboard.server.common.data.kv.BasicTsKvEntry; | ||
34 | import org.thingsboard.server.common.data.kv.ReadTsKvQuery; | 34 | import org.thingsboard.server.common.data.kv.ReadTsKvQuery; |
35 | import org.thingsboard.server.common.data.kv.TsKvEntry; | 35 | import org.thingsboard.server.common.data.kv.TsKvEntry; |
36 | import org.thingsboard.server.common.msg.queue.ServiceType; | 36 | import org.thingsboard.server.common.msg.queue.ServiceType; |
37 | -import org.thingsboard.server.common.msg.queue.TbMsgCallback; | 37 | +import org.thingsboard.server.common.msg.queue.TbCallback; |
38 | import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; | 38 | import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; |
39 | import org.thingsboard.server.dao.attributes.AttributesService; | 39 | import org.thingsboard.server.dao.attributes.AttributesService; |
40 | import org.thingsboard.server.dao.timeseries.TimeseriesService; | 40 | import org.thingsboard.server.dao.timeseries.TimeseriesService; |
@@ -123,7 +123,7 @@ public class DefaultSubscriptionManagerService implements SubscriptionManagerSer | @@ -123,7 +123,7 @@ public class DefaultSubscriptionManagerService implements SubscriptionManagerSer | ||
123 | } | 123 | } |
124 | 124 | ||
125 | @Override | 125 | @Override |
126 | - public void addSubscription(TbSubscription subscription, TbMsgCallback callback) { | 126 | + public void addSubscription(TbSubscription subscription, TbCallback callback) { |
127 | log.trace("[{}][{}][{}] Registering remote subscription for entity [{}]", | 127 | log.trace("[{}][{}][{}] Registering remote subscription for entity [{}]", |
128 | subscription.getServiceId(), subscription.getSessionId(), subscription.getSubscriptionId(), subscription.getEntityId()); | 128 | subscription.getServiceId(), subscription.getSessionId(), subscription.getSubscriptionId(), subscription.getEntityId()); |
129 | TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_CORE, subscription.getTenantId(), subscription.getEntityId()); | 129 | TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_CORE, subscription.getTenantId(), subscription.getEntityId()); |
@@ -151,7 +151,7 @@ public class DefaultSubscriptionManagerService implements SubscriptionManagerSer | @@ -151,7 +151,7 @@ public class DefaultSubscriptionManagerService implements SubscriptionManagerSer | ||
151 | } | 151 | } |
152 | 152 | ||
153 | @Override | 153 | @Override |
154 | - public void cancelSubscription(String sessionId, int subscriptionId, TbMsgCallback callback) { | 154 | + public void cancelSubscription(String sessionId, int subscriptionId, TbCallback callback) { |
155 | log.debug("[{}][{}] Going to remove subscription.", sessionId, subscriptionId); | 155 | log.debug("[{}][{}] Going to remove subscription.", sessionId, subscriptionId); |
156 | Map<Integer, TbSubscription> sessionSubscriptions = subscriptionsByWsSessionId.get(sessionId); | 156 | Map<Integer, TbSubscription> sessionSubscriptions = subscriptionsByWsSessionId.get(sessionId); |
157 | if (sessionSubscriptions != null) { | 157 | if (sessionSubscriptions != null) { |
@@ -189,7 +189,7 @@ public class DefaultSubscriptionManagerService implements SubscriptionManagerSer | @@ -189,7 +189,7 @@ public class DefaultSubscriptionManagerService implements SubscriptionManagerSer | ||
189 | } | 189 | } |
190 | 190 | ||
191 | @Override | 191 | @Override |
192 | - public void onTimeSeriesUpdate(TenantId tenantId, EntityId entityId, List<TsKvEntry> ts, TbMsgCallback callback) { | 192 | + public void onTimeSeriesUpdate(TenantId tenantId, EntityId entityId, List<TsKvEntry> ts, TbCallback callback) { |
193 | onLocalSubUpdate(entityId, | 193 | onLocalSubUpdate(entityId, |
194 | s -> { | 194 | s -> { |
195 | if (TbSubscriptionType.TIMESERIES.equals(s.getType())) { | 195 | if (TbSubscriptionType.TIMESERIES.equals(s.getType())) { |
@@ -213,7 +213,7 @@ public class DefaultSubscriptionManagerService implements SubscriptionManagerSer | @@ -213,7 +213,7 @@ public class DefaultSubscriptionManagerService implements SubscriptionManagerSer | ||
213 | } | 213 | } |
214 | 214 | ||
215 | @Override | 215 | @Override |
216 | - public void onAttributesUpdate(TenantId tenantId, EntityId entityId, String scope, List<AttributeKvEntry> attributes, TbMsgCallback callback) { | 216 | + public void onAttributesUpdate(TenantId tenantId, EntityId entityId, String scope, List<AttributeKvEntry> attributes, TbCallback callback) { |
217 | onLocalSubUpdate(entityId, | 217 | onLocalSubUpdate(entityId, |
218 | s -> { | 218 | s -> { |
219 | if (TbSubscriptionType.ATTRIBUTES.equals(s.getType())) { | 219 | if (TbSubscriptionType.ATTRIBUTES.equals(s.getType())) { |
@@ -261,7 +261,7 @@ public class DefaultSubscriptionManagerService implements SubscriptionManagerSer | @@ -261,7 +261,7 @@ public class DefaultSubscriptionManagerService implements SubscriptionManagerSer | ||
261 | if (subscriptionUpdate != null && !subscriptionUpdate.isEmpty()) { | 261 | if (subscriptionUpdate != null && !subscriptionUpdate.isEmpty()) { |
262 | if (serviceId.equals(s.getServiceId())) { | 262 | if (serviceId.equals(s.getServiceId())) { |
263 | SubscriptionUpdate update = new SubscriptionUpdate(s.getSubscriptionId(), subscriptionUpdate); | 263 | SubscriptionUpdate update = new SubscriptionUpdate(s.getSubscriptionId(), subscriptionUpdate); |
264 | - localSubscriptionService.onSubscriptionUpdate(s.getSessionId(), update, TbMsgCallback.EMPTY); | 264 | + localSubscriptionService.onSubscriptionUpdate(s.getSessionId(), update, TbCallback.EMPTY); |
265 | } else { | 265 | } else { |
266 | TopicPartitionInfo tpi = partitionService.getNotificationsTopic(ServiceType.TB_CORE, s.getServiceId()); | 266 | TopicPartitionInfo tpi = partitionService.getNotificationsTopic(ServiceType.TB_CORE, s.getServiceId()); |
267 | toCoreNotificationsProducer.send(tpi, toProto(s, subscriptionUpdate), null); | 267 | toCoreNotificationsProducer.send(tpi, toProto(s, subscriptionUpdate), null); |
@@ -35,7 +35,7 @@ import org.thingsboard.server.queue.discovery.PartitionChangeEvent; | @@ -35,7 +35,7 @@ import org.thingsboard.server.queue.discovery.PartitionChangeEvent; | ||
35 | import org.thingsboard.server.queue.discovery.PartitionService; | 35 | import org.thingsboard.server.queue.discovery.PartitionService; |
36 | import org.thingsboard.server.common.msg.queue.ServiceType; | 36 | import org.thingsboard.server.common.msg.queue.ServiceType; |
37 | import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; | 37 | import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; |
38 | -import org.thingsboard.server.common.msg.queue.TbMsgCallback; | 38 | +import org.thingsboard.server.common.msg.queue.TbCallback; |
39 | import org.thingsboard.server.queue.provider.TbQueueProducerProvider; | 39 | import org.thingsboard.server.queue.provider.TbQueueProducerProvider; |
40 | import org.thingsboard.server.queue.util.TbCoreComponent; | 40 | import org.thingsboard.server.queue.util.TbCoreComponent; |
41 | import org.thingsboard.server.service.telemetry.TelemetryWebSocketService; | 41 | import org.thingsboard.server.service.telemetry.TelemetryWebSocketService; |
@@ -135,7 +135,7 @@ public class DefaultTbLocalSubscriptionService implements TbLocalSubscriptionSer | @@ -135,7 +135,7 @@ public class DefaultTbLocalSubscriptionService implements TbLocalSubscriptionSer | ||
135 | if (currentPartitions.contains(tpi)) { | 135 | if (currentPartitions.contains(tpi)) { |
136 | // Subscription is managed on the same server; | 136 | // Subscription is managed on the same server; |
137 | if (pushToLocalService) { | 137 | if (pushToLocalService) { |
138 | - subscriptionManagerService.addSubscription(subscription, TbMsgCallback.EMPTY); | 138 | + subscriptionManagerService.addSubscription(subscription, TbCallback.EMPTY); |
139 | } | 139 | } |
140 | } else { | 140 | } else { |
141 | // Push to the queue; | 141 | // Push to the queue; |
@@ -145,7 +145,7 @@ public class DefaultTbLocalSubscriptionService implements TbLocalSubscriptionSer | @@ -145,7 +145,7 @@ public class DefaultTbLocalSubscriptionService implements TbLocalSubscriptionSer | ||
145 | } | 145 | } |
146 | 146 | ||
147 | @Override | 147 | @Override |
148 | - public void onSubscriptionUpdate(String sessionId, SubscriptionUpdate update, TbMsgCallback callback) { | 148 | + public void onSubscriptionUpdate(String sessionId, SubscriptionUpdate update, TbCallback callback) { |
149 | TbSubscription subscription = subscriptionsBySessionId | 149 | TbSubscription subscription = subscriptionsBySessionId |
150 | .getOrDefault(sessionId, Collections.emptyMap()).get(update.getSubscriptionId()); | 150 | .getOrDefault(sessionId, Collections.emptyMap()).get(update.getSubscriptionId()); |
151 | if (subscription != null) { | 151 | if (subscription != null) { |
@@ -177,7 +177,7 @@ public class DefaultTbLocalSubscriptionService implements TbLocalSubscriptionSer | @@ -177,7 +177,7 @@ public class DefaultTbLocalSubscriptionService implements TbLocalSubscriptionSer | ||
177 | TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_CORE, subscription.getTenantId(), subscription.getEntityId()); | 177 | TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_CORE, subscription.getTenantId(), subscription.getEntityId()); |
178 | if (currentPartitions.contains(tpi)) { | 178 | if (currentPartitions.contains(tpi)) { |
179 | // Subscription is managed on the same server; | 179 | // Subscription is managed on the same server; |
180 | - subscriptionManagerService.cancelSubscription(sessionId, subscriptionId, TbMsgCallback.EMPTY); | 180 | + subscriptionManagerService.cancelSubscription(sessionId, subscriptionId, TbCallback.EMPTY); |
181 | } else { | 181 | } else { |
182 | // Push to the queue; | 182 | // Push to the queue; |
183 | TransportProtos.ToCoreMsg toCoreMsg = TbSubscriptionUtils.toCloseSubscriptionProto(subscription); | 183 | TransportProtos.ToCoreMsg toCoreMsg = TbSubscriptionUtils.toCloseSubscriptionProto(subscription); |
@@ -21,18 +21,18 @@ import org.thingsboard.server.common.data.id.TenantId; | @@ -21,18 +21,18 @@ import org.thingsboard.server.common.data.id.TenantId; | ||
21 | import org.thingsboard.server.common.data.kv.AttributeKvEntry; | 21 | import org.thingsboard.server.common.data.kv.AttributeKvEntry; |
22 | import org.thingsboard.server.common.data.kv.TsKvEntry; | 22 | import org.thingsboard.server.common.data.kv.TsKvEntry; |
23 | import org.thingsboard.server.queue.discovery.PartitionChangeEvent; | 23 | import org.thingsboard.server.queue.discovery.PartitionChangeEvent; |
24 | -import org.thingsboard.server.common.msg.queue.TbMsgCallback; | 24 | +import org.thingsboard.server.common.msg.queue.TbCallback; |
25 | 25 | ||
26 | import java.util.List; | 26 | import java.util.List; |
27 | 27 | ||
28 | public interface SubscriptionManagerService extends ApplicationListener<PartitionChangeEvent> { | 28 | public interface SubscriptionManagerService extends ApplicationListener<PartitionChangeEvent> { |
29 | 29 | ||
30 | - void addSubscription(TbSubscription subscription, TbMsgCallback callback); | 30 | + void addSubscription(TbSubscription subscription, TbCallback callback); |
31 | 31 | ||
32 | - void cancelSubscription(String sessionId, int subscriptionId, TbMsgCallback callback); | 32 | + void cancelSubscription(String sessionId, int subscriptionId, TbCallback callback); |
33 | 33 | ||
34 | - void onTimeSeriesUpdate(TenantId tenantId, EntityId entityId, List<TsKvEntry> ts, TbMsgCallback callback); | 34 | + void onTimeSeriesUpdate(TenantId tenantId, EntityId entityId, List<TsKvEntry> ts, TbCallback callback); |
35 | 35 | ||
36 | - void onAttributesUpdate(TenantId tenantId, EntityId entityId, String scope, List<AttributeKvEntry> attributes, TbMsgCallback callback); | 36 | + void onAttributesUpdate(TenantId tenantId, EntityId entityId, String scope, List<AttributeKvEntry> attributes, TbCallback callback); |
37 | 37 | ||
38 | } | 38 | } |
@@ -17,7 +17,7 @@ package org.thingsboard.server.service.subscription; | @@ -17,7 +17,7 @@ package org.thingsboard.server.service.subscription; | ||
17 | 17 | ||
18 | import org.thingsboard.server.queue.discovery.ClusterTopologyChangeEvent; | 18 | import org.thingsboard.server.queue.discovery.ClusterTopologyChangeEvent; |
19 | import org.thingsboard.server.queue.discovery.PartitionChangeEvent; | 19 | import org.thingsboard.server.queue.discovery.PartitionChangeEvent; |
20 | -import org.thingsboard.server.common.msg.queue.TbMsgCallback; | 20 | +import org.thingsboard.server.common.msg.queue.TbCallback; |
21 | import org.thingsboard.server.service.telemetry.sub.SubscriptionUpdate; | 21 | import org.thingsboard.server.service.telemetry.sub.SubscriptionUpdate; |
22 | 22 | ||
23 | public interface TbLocalSubscriptionService { | 23 | public interface TbLocalSubscriptionService { |
@@ -28,7 +28,7 @@ public interface TbLocalSubscriptionService { | @@ -28,7 +28,7 @@ public interface TbLocalSubscriptionService { | ||
28 | 28 | ||
29 | void cancelAllSessionSubscriptions(String sessionId); | 29 | void cancelAllSessionSubscriptions(String sessionId); |
30 | 30 | ||
31 | - void onSubscriptionUpdate(String sessionId, SubscriptionUpdate update, TbMsgCallback callback); | 31 | + void onSubscriptionUpdate(String sessionId, SubscriptionUpdate update, TbCallback callback); |
32 | 32 | ||
33 | void onApplicationEvent(PartitionChangeEvent event); | 33 | void onApplicationEvent(PartitionChangeEvent event); |
34 | 34 |
@@ -41,7 +41,7 @@ import org.thingsboard.server.queue.discovery.PartitionChangeEvent; | @@ -41,7 +41,7 @@ import org.thingsboard.server.queue.discovery.PartitionChangeEvent; | ||
41 | import org.thingsboard.server.queue.discovery.PartitionService; | 41 | import org.thingsboard.server.queue.discovery.PartitionService; |
42 | import org.thingsboard.server.common.msg.queue.ServiceType; | 42 | import org.thingsboard.server.common.msg.queue.ServiceType; |
43 | import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; | 43 | import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; |
44 | -import org.thingsboard.server.common.msg.queue.TbMsgCallback; | 44 | +import org.thingsboard.server.common.msg.queue.TbCallback; |
45 | import org.thingsboard.server.queue.provider.TbQueueProducerProvider; | 45 | import org.thingsboard.server.queue.provider.TbQueueProducerProvider; |
46 | import org.thingsboard.server.service.subscription.SubscriptionManagerService; | 46 | import org.thingsboard.server.service.subscription.SubscriptionManagerService; |
47 | import org.thingsboard.server.service.subscription.TbSubscriptionUtils; | 47 | import org.thingsboard.server.service.subscription.TbSubscriptionUtils; |
@@ -166,7 +166,7 @@ public class DefaultTelemetrySubscriptionService implements TelemetrySubscriptio | @@ -166,7 +166,7 @@ public class DefaultTelemetrySubscriptionService implements TelemetrySubscriptio | ||
166 | TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_CORE, tenantId, entityId); | 166 | TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_CORE, tenantId, entityId); |
167 | if (currentPartitions.contains(tpi)) { | 167 | if (currentPartitions.contains(tpi)) { |
168 | if (subscriptionManagerService.isPresent()) { | 168 | if (subscriptionManagerService.isPresent()) { |
169 | - subscriptionManagerService.get().onAttributesUpdate(tenantId, entityId, scope, attributes, TbMsgCallback.EMPTY); | 169 | + subscriptionManagerService.get().onAttributesUpdate(tenantId, entityId, scope, attributes, TbCallback.EMPTY); |
170 | } else { | 170 | } else { |
171 | log.warn("Possible misconfiguration because subscriptionManagerService is null!"); | 171 | log.warn("Possible misconfiguration because subscriptionManagerService is null!"); |
172 | } | 172 | } |
@@ -180,7 +180,7 @@ public class DefaultTelemetrySubscriptionService implements TelemetrySubscriptio | @@ -180,7 +180,7 @@ public class DefaultTelemetrySubscriptionService implements TelemetrySubscriptio | ||
180 | TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_CORE, tenantId, entityId); | 180 | TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_CORE, tenantId, entityId); |
181 | if (currentPartitions.contains(tpi)) { | 181 | if (currentPartitions.contains(tpi)) { |
182 | if (subscriptionManagerService.isPresent()) { | 182 | if (subscriptionManagerService.isPresent()) { |
183 | - subscriptionManagerService.get().onTimeSeriesUpdate(tenantId, entityId, ts, TbMsgCallback.EMPTY); | 183 | + subscriptionManagerService.get().onTimeSeriesUpdate(tenantId, entityId, ts, TbCallback.EMPTY); |
184 | } else { | 184 | } else { |
185 | log.warn("Possible misconfiguration because subscriptionManagerService is null!"); | 185 | log.warn("Possible misconfiguration because subscriptionManagerService is null!"); |
186 | } | 186 | } |
application/src/main/java/org/thingsboard/server/service/telemetry/TelemetrySubscriptionService.java
@@ -17,11 +17,7 @@ package org.thingsboard.server.service.telemetry; | @@ -17,11 +17,7 @@ package org.thingsboard.server.service.telemetry; | ||
17 | 17 | ||
18 | import org.springframework.context.ApplicationListener; | 18 | import org.springframework.context.ApplicationListener; |
19 | import org.thingsboard.rule.engine.api.RuleEngineTelemetryService; | 19 | import org.thingsboard.rule.engine.api.RuleEngineTelemetryService; |
20 | -import org.thingsboard.server.common.data.id.EntityId; | ||
21 | -import org.thingsboard.server.common.data.id.TenantId; | ||
22 | -import org.thingsboard.server.common.msg.cluster.ServerAddress; | ||
23 | import org.thingsboard.server.queue.discovery.PartitionChangeEvent; | 20 | import org.thingsboard.server.queue.discovery.PartitionChangeEvent; |
24 | -import org.thingsboard.server.service.telemetry.sub.SubscriptionState; | ||
25 | 21 | ||
26 | /** | 22 | /** |
27 | * Created by ashvayka on 27.03.18. | 23 | * Created by ashvayka on 27.03.18. |
application/src/main/java/org/thingsboard/server/service/telemetry/sub/Subscription.java
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 | -package org.thingsboard.server.service.telemetry.sub; | ||
17 | - | ||
18 | -import lombok.AllArgsConstructor; | ||
19 | -import lombok.Data; | ||
20 | -import org.thingsboard.server.common.data.id.EntityId; | ||
21 | -import org.thingsboard.server.common.msg.cluster.ServerAddress; | ||
22 | -import org.thingsboard.server.service.telemetry.TelemetryFeature; | ||
23 | - | ||
24 | -import java.util.Map; | ||
25 | - | ||
26 | -@Data | ||
27 | -@AllArgsConstructor | ||
28 | -public class Subscription { | ||
29 | - | ||
30 | - private final SubscriptionState sub; | ||
31 | - private final boolean local; | ||
32 | - private ServerAddress server; | ||
33 | - private long startTime; | ||
34 | - private long endTime; | ||
35 | - | ||
36 | - public Subscription(SubscriptionState sub, boolean local, ServerAddress server) { | ||
37 | - this(sub, local, server, 0L, 0L); | ||
38 | - } | ||
39 | - | ||
40 | - public String getWsSessionId() { | ||
41 | - return getSub().getWsSessionId(); | ||
42 | - } | ||
43 | - | ||
44 | - public int getSubscriptionId() { | ||
45 | - return getSub().getSubscriptionId(); | ||
46 | - } | ||
47 | - | ||
48 | - public EntityId getEntityId() { | ||
49 | - return getSub().getEntityId(); | ||
50 | - } | ||
51 | - | ||
52 | - public TelemetryFeature getType() { | ||
53 | - return getSub().getType(); | ||
54 | - } | ||
55 | - | ||
56 | - public String getScope() { | ||
57 | - return getSub().getScope(); | ||
58 | - } | ||
59 | - | ||
60 | - public boolean isAllKeys() { | ||
61 | - return getSub().isAllKeys(); | ||
62 | - } | ||
63 | - | ||
64 | - public Map<String, Long> getKeyStates() { | ||
65 | - return getSub().getKeyStates(); | ||
66 | - } | ||
67 | - | ||
68 | - public void setKeyState(String key, long ts) { | ||
69 | - getSub().getKeyStates().put(key, ts); | ||
70 | - } | ||
71 | - | ||
72 | - @Override | ||
73 | - public String toString() { | ||
74 | - return "Subscription{" + | ||
75 | - "sub=" + sub + | ||
76 | - ", local=" + local + | ||
77 | - ", server=" + server + | ||
78 | - '}'; | ||
79 | - } | ||
80 | -} |
@@ -22,7 +22,6 @@ import org.thingsboard.common.util.ThingsBoardThreadFactory; | @@ -22,7 +22,6 @@ import org.thingsboard.common.util.ThingsBoardThreadFactory; | ||
22 | import org.thingsboard.rule.engine.api.RuleChainTransactionService; | 22 | import org.thingsboard.rule.engine.api.RuleChainTransactionService; |
23 | import org.thingsboard.server.common.data.id.EntityId; | 23 | import org.thingsboard.server.common.data.id.EntityId; |
24 | import org.thingsboard.server.common.msg.TbMsg; | 24 | import org.thingsboard.server.common.msg.TbMsg; |
25 | -import org.thingsboard.server.common.msg.cluster.ServerAddress; | ||
26 | import org.thingsboard.server.queue.util.TbRuleEngineComponent; | 25 | import org.thingsboard.server.queue.util.TbRuleEngineComponent; |
27 | import org.thingsboard.server.service.executors.DbCallbackExecutorService; | 26 | import org.thingsboard.server.service.executors.DbCallbackExecutorService; |
28 | 27 | ||
@@ -114,13 +113,6 @@ public class BaseRuleChainTransactionService implements RuleChainTransactionServ | @@ -114,13 +113,6 @@ public class BaseRuleChainTransactionService implements RuleChainTransactionServ | ||
114 | // } | 113 | // } |
115 | } | 114 | } |
116 | 115 | ||
117 | - @Override | ||
118 | - public void onRemoteTransactionMsg(ServerAddress serverAddress, byte[] data) { | ||
119 | - endLocalTransaction(TbMsg.fromBytes(data, null), msg -> { | ||
120 | - }, error -> { | ||
121 | - }); | ||
122 | - } | ||
123 | - | ||
124 | private void addMsgToQueues(BlockingQueue<TbTransactionTask> queue, TbTransactionTask transactionTask) { | 116 | private void addMsgToQueues(BlockingQueue<TbTransactionTask> queue, TbTransactionTask transactionTask) { |
125 | queue.offer(transactionTask); | 117 | queue.offer(transactionTask); |
126 | timeoutQueue.offer(transactionTask); | 118 | timeoutQueue.offer(transactionTask); |
@@ -230,9 +222,4 @@ public class BaseRuleChainTransactionService implements RuleChainTransactionServ | @@ -230,9 +222,4 @@ public class BaseRuleChainTransactionService implements RuleChainTransactionServ | ||
230 | callbackExecutor.executeAsync(task); | 222 | callbackExecutor.executeAsync(task); |
231 | } | 223 | } |
232 | 224 | ||
233 | - private void sendTransactionEventToRemoteServer(TbMsg msg, ServerAddress address) { | ||
234 | - log.trace("[{}][{}] Originator is monitored on other server: {}", msg.getTransactionData().getOriginatorId(), msg.getTransactionData().getTransactionId(), address); | ||
235 | - //TODO 2.5 | ||
236 | -// clusterRpcService.tell(address, ClusterAPIProtos.MessageType.CLUSTER_TRANSACTION_SERVICE_MESSAGE, TbMsg.toByteArray(msg)); | ||
237 | - } | ||
238 | } | 225 | } |
@@ -23,7 +23,7 @@ import org.thingsboard.server.common.msg.TbActorMsg; | @@ -23,7 +23,7 @@ import org.thingsboard.server.common.msg.TbActorMsg; | ||
23 | import org.thingsboard.server.common.msg.aware.DeviceAwareMsg; | 23 | import org.thingsboard.server.common.msg.aware.DeviceAwareMsg; |
24 | import org.thingsboard.server.common.msg.aware.TenantAwareMsg; | 24 | import org.thingsboard.server.common.msg.aware.TenantAwareMsg; |
25 | import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg; | 25 | import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg; |
26 | -import org.thingsboard.server.common.msg.queue.TbMsgCallback; | 26 | +import org.thingsboard.server.common.msg.queue.TbCallback; |
27 | 27 | ||
28 | import java.io.Serializable; | 28 | import java.io.Serializable; |
29 | import java.util.UUID; | 29 | import java.util.UUID; |
@@ -37,9 +37,9 @@ public class TransportToDeviceActorMsgWrapper implements TbActorMsg, DeviceAware | @@ -37,9 +37,9 @@ public class TransportToDeviceActorMsgWrapper implements TbActorMsg, DeviceAware | ||
37 | private final TenantId tenantId; | 37 | private final TenantId tenantId; |
38 | private final DeviceId deviceId; | 38 | private final DeviceId deviceId; |
39 | private final TransportToDeviceActorMsg msg; | 39 | private final TransportToDeviceActorMsg msg; |
40 | - private final TbMsgCallback callback; | 40 | + private final TbCallback callback; |
41 | 41 | ||
42 | - public TransportToDeviceActorMsgWrapper(TransportToDeviceActorMsg msg, TbMsgCallback callback) { | 42 | + public TransportToDeviceActorMsgWrapper(TransportToDeviceActorMsg msg, TbCallback callback) { |
43 | this.msg = msg; | 43 | this.msg = msg; |
44 | this.callback = callback; | 44 | this.callback = callback; |
45 | this.tenantId = new TenantId(new UUID(msg.getSessionInfo().getTenantIdMSB(), msg.getSessionInfo().getTenantIdLSB())); | 45 | this.tenantId = new TenantId(new UUID(msg.getSessionInfo().getTenantIdMSB(), msg.getSessionInfo().getTenantIdLSB())); |
@@ -27,8 +27,8 @@ | @@ -27,8 +27,8 @@ | ||
27 | 27 | ||
28 | <logger name="org.thingsboard.server" level="INFO" /> | 28 | <logger name="org.thingsboard.server" level="INFO" /> |
29 | <logger name="akka" level="INFO" /> | 29 | <logger name="akka" level="INFO" /> |
30 | - <logger name="org.thingsboard.server.service.queue" level="TRACE" /> | ||
31 | - <logger name="org.thingsboard.server.service.transport" level="TRACE" /> | 30 | +<!-- <logger name="org.thingsboard.server.service.queue" level="TRACE" />--> |
31 | +<!-- <logger name="org.thingsboard.server.service.transport" level="TRACE" />--> | ||
32 | 32 | ||
33 | <root level="INFO"> | 33 | <root level="INFO"> |
34 | <appender-ref ref="STDOUT"/> | 34 | <appender-ref ref="STDOUT"/> |
@@ -561,7 +561,7 @@ queue: | @@ -561,7 +561,7 @@ queue: | ||
561 | poll-interval: "${TB_QUEUE_RULE_ENGINE_POLL_INTERVAL_MS:25}" | 561 | poll-interval: "${TB_QUEUE_RULE_ENGINE_POLL_INTERVAL_MS:25}" |
562 | pack-processing-timeout: "${TB_QUEUE_RULE_ENGINE_PACK_PROCESSING_TIMEOUT_MS:60000}" | 562 | pack-processing-timeout: "${TB_QUEUE_RULE_ENGINE_PACK_PROCESSING_TIMEOUT_MS:60000}" |
563 | stats: | 563 | stats: |
564 | - enabled: "${TB_QUEUE_RULE_ENGINE_STATS_ENABLED:false}" | 564 | + enabled: "${TB_QUEUE_RULE_ENGINE_STATS_ENABLED:true}" |
565 | print-interval-ms: "${TB_QUEUE_RULE_ENGINE_STATS_PRINT_INTERVAL_MS:10000}" | 565 | print-interval-ms: "${TB_QUEUE_RULE_ENGINE_STATS_PRINT_INTERVAL_MS:10000}" |
566 | queues: # TODO 2.5: specify correct ENV variable names. | 566 | queues: # TODO 2.5: specify correct ENV variable names. |
567 | - | 567 | - |
@@ -577,7 +577,7 @@ queue: | @@ -577,7 +577,7 @@ queue: | ||
577 | failure-percentage: "${TB_QUEUE_RULE_ENGINE_STRATEGY_FAILURE_PERCENTAGE:0}" # Skip retry if failures or timeouts are less then X percentage of messages; | 577 | failure-percentage: "${TB_QUEUE_RULE_ENGINE_STRATEGY_FAILURE_PERCENTAGE:0}" # Skip retry if failures or timeouts are less then X percentage of messages; |
578 | pause-between-retries: "${TB_QUEUE_RULE_ENGINE_STRATEGY_RETRY_PAUSE:3}"# Time in seconds to wait in consumer thread before retries; | 578 | pause-between-retries: "${TB_QUEUE_RULE_ENGINE_STRATEGY_RETRY_PAUSE:3}"# Time in seconds to wait in consumer thread before retries; |
579 | - | 579 | - |
580 | - name: "HighPriority" | 580 | + name: "${TB_QUEUE_RULE_ENGINE_HP_QUEUE_NAME:HighPriority}" |
581 | topic: "${TB_QUEUE_RULE_ENGINE_TOPIC:tb.rule-engine.hp}" | 581 | topic: "${TB_QUEUE_RULE_ENGINE_TOPIC:tb.rule-engine.hp}" |
582 | poll-interval: "${TB_QUEUE_RULE_ENGINE_POLL_INTERVAL_MS:25}" | 582 | poll-interval: "${TB_QUEUE_RULE_ENGINE_POLL_INTERVAL_MS:25}" |
583 | partitions: "${TB_QUEUE_RULE_ENGINE_PARTITIONS:3}" | 583 | partitions: "${TB_QUEUE_RULE_ENGINE_PARTITIONS:3}" |
@@ -594,7 +594,7 @@ queue: | @@ -594,7 +594,7 @@ queue: | ||
594 | poll_interval: "${TB_QUEUE_CORE_POLL_INTERVAL_MS:25}" | 594 | poll_interval: "${TB_QUEUE_CORE_POLL_INTERVAL_MS:25}" |
595 | 595 | ||
596 | service: | 596 | service: |
597 | - type: "${TB_SERVICE_TYPE:monolith}" # monolith or tb-core or tb-rule-engine or tb-transport | 597 | + type: "${TB_SERVICE_TYPE:monolith}" # monolith or tb-core or tb-rule-engine |
598 | # Unique id for this service (autogenerated if empty) | 598 | # Unique id for this service (autogenerated if empty) |
599 | id: "${TB_SERVICE_ID:}" | 599 | id: "${TB_SERVICE_ID:}" |
600 | tenant_id: "${TB_SERVICE_TENANT_ID:}" # empty or specific tenant id. | 600 | tenant_id: "${TB_SERVICE_TENANT_ID:}" # empty or specific tenant id. |
@@ -35,8 +35,6 @@ import org.thingsboard.server.common.data.security.Authority; | @@ -35,8 +35,6 @@ import org.thingsboard.server.common.data.security.Authority; | ||
35 | import org.thingsboard.server.common.msg.TbMsg; | 35 | import org.thingsboard.server.common.msg.TbMsg; |
36 | import org.thingsboard.server.common.msg.TbMsgDataType; | 36 | import org.thingsboard.server.common.msg.TbMsgDataType; |
37 | import org.thingsboard.server.common.msg.TbMsgMetaData; | 37 | import org.thingsboard.server.common.msg.TbMsgMetaData; |
38 | -import org.thingsboard.server.common.msg.cluster.SendToClusterMsg; | ||
39 | -import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg; | ||
40 | import org.thingsboard.server.controller.AbstractRuleEngineControllerTest; | 38 | import org.thingsboard.server.controller.AbstractRuleEngineControllerTest; |
41 | import org.thingsboard.server.dao.attributes.AttributesService; | 39 | import org.thingsboard.server.dao.attributes.AttributesService; |
42 | 40 |
@@ -39,8 +39,6 @@ import org.thingsboard.server.common.data.security.Authority; | @@ -39,8 +39,6 @@ import org.thingsboard.server.common.data.security.Authority; | ||
39 | import org.thingsboard.server.common.msg.TbMsg; | 39 | import org.thingsboard.server.common.msg.TbMsg; |
40 | import org.thingsboard.server.common.msg.TbMsgDataType; | 40 | import org.thingsboard.server.common.msg.TbMsgDataType; |
41 | import org.thingsboard.server.common.msg.TbMsgMetaData; | 41 | import org.thingsboard.server.common.msg.TbMsgMetaData; |
42 | -import org.thingsboard.server.common.msg.cluster.SendToClusterMsg; | ||
43 | -import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg; | ||
44 | import org.thingsboard.server.controller.AbstractRuleEngineControllerTest; | 42 | import org.thingsboard.server.controller.AbstractRuleEngineControllerTest; |
45 | import org.thingsboard.server.dao.attributes.AttributesService; | 43 | import org.thingsboard.server.dao.attributes.AttributesService; |
46 | 44 |
@@ -34,11 +34,6 @@ public enum MsgType { | @@ -34,11 +34,6 @@ public enum MsgType { | ||
34 | APP_INIT_MSG, | 34 | APP_INIT_MSG, |
35 | 35 | ||
36 | /** | 36 | /** |
37 | - * All messages, could be send to cluster | ||
38 | - */ | ||
39 | - SEND_TO_CLUSTER_MSG, | ||
40 | - | ||
41 | - /** | ||
42 | * ADDED/UPDATED/DELETED events for main entities. | 37 | * ADDED/UPDATED/DELETED events for main entities. |
43 | * | 38 | * |
44 | * See {@link org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg} | 39 | * See {@link org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg} |
@@ -5,7 +5,7 @@ | @@ -5,7 +5,7 @@ | ||
5 | * you may not use this file except in compliance with 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 | 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 | * Unless required by applicable law or agreed to in writing, software | 10 | * Unless required by applicable law or agreed to in writing, software |
11 | * distributed under the License is distributed on an "AS IS" BASIS, | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
@@ -17,7 +17,6 @@ package org.thingsboard.server.common.msg; | @@ -17,7 +17,6 @@ package org.thingsboard.server.common.msg; | ||
17 | 17 | ||
18 | import com.google.protobuf.ByteString; | 18 | import com.google.protobuf.ByteString; |
19 | import com.google.protobuf.InvalidProtocolBufferException; | 19 | import com.google.protobuf.InvalidProtocolBufferException; |
20 | -import lombok.AllArgsConstructor; | ||
21 | import lombok.Builder; | 20 | import lombok.Builder; |
22 | import lombok.Data; | 21 | import lombok.Data; |
23 | import lombok.extern.slf4j.Slf4j; | 22 | import lombok.extern.slf4j.Slf4j; |
@@ -29,7 +28,6 @@ import org.thingsboard.server.common.msg.gen.MsgProtos; | @@ -29,7 +28,6 @@ import org.thingsboard.server.common.msg.gen.MsgProtos; | ||
29 | import org.thingsboard.server.common.msg.queue.TbMsgCallback; | 28 | import org.thingsboard.server.common.msg.queue.TbMsgCallback; |
30 | 29 | ||
31 | import java.io.Serializable; | 30 | import java.io.Serializable; |
32 | -import java.nio.ByteBuffer; | ||
33 | import java.util.UUID; | 31 | import java.util.UUID; |
34 | 32 | ||
35 | /** | 33 | /** |
@@ -33,6 +33,7 @@ public final class QueueToRuleEngineMsg implements TbActorMsg { | @@ -33,6 +33,7 @@ public final class QueueToRuleEngineMsg implements TbActorMsg { | ||
33 | private final TenantId tenantId; | 33 | private final TenantId tenantId; |
34 | private final TbMsg tbMsg; | 34 | private final TbMsg tbMsg; |
35 | private final Set<String> relationTypes; | 35 | private final Set<String> relationTypes; |
36 | + private final String failureMessage; | ||
36 | 37 | ||
37 | @Override | 38 | @Override |
38 | public MsgType getMsgType() { | 39 | public MsgType getMsgType() { |
common/message/src/main/java/org/thingsboard/server/common/msg/queue/RuleEngineException.java
renamed from
common/message/src/main/java/org/thingsboard/server/common/msg/cluster/ServerAddress.java
@@ -13,35 +13,26 @@ | @@ -13,35 +13,26 @@ | ||
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 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 | -import lombok.Data; | ||
19 | -import lombok.EqualsAndHashCode; | 18 | +import com.fasterxml.jackson.core.JsonProcessingException; |
19 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
20 | +import lombok.extern.slf4j.Slf4j; | ||
20 | 21 | ||
21 | -import java.io.Serializable; | 22 | +@Slf4j |
23 | +public class RuleEngineException extends Exception { | ||
24 | + protected static final ObjectMapper mapper = new ObjectMapper(); | ||
22 | 25 | ||
23 | -/** | ||
24 | - * @author Andrew Shvayka | ||
25 | - */ | ||
26 | -@Data | ||
27 | -@EqualsAndHashCode | ||
28 | -public class ServerAddress implements Comparable<ServerAddress>, Serializable { | ||
29 | - | ||
30 | - private final String host; | ||
31 | - private final int port; | ||
32 | - private final ServerType serverType; | ||
33 | - | ||
34 | - @Override | ||
35 | - public int compareTo(ServerAddress o) { | ||
36 | - int result = this.host.compareTo(o.host); | ||
37 | - if (result == 0) { | ||
38 | - result = this.port - o.port; | ||
39 | - } | ||
40 | - return result; | 26 | + public RuleEngineException(String message) { |
27 | + super(message != null ? message : "Unknown"); | ||
41 | } | 28 | } |
42 | 29 | ||
43 | - @Override | ||
44 | - public String toString() { | ||
45 | - return '[' + host + ':' + port + ']'; | 30 | + public String toJsonString() { |
31 | + try { | ||
32 | + return mapper.writeValueAsString(mapper.createObjectNode().put("message", getMessage())); | ||
33 | + } catch (JsonProcessingException e) { | ||
34 | + log.warn("Failed to serialize exception ", e); | ||
35 | + throw new RuntimeException(e); | ||
36 | + } | ||
46 | } | 37 | } |
47 | } | 38 | } |
common/message/src/main/java/org/thingsboard/server/common/msg/queue/RuleNodeException.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.common.msg.queue; | ||
17 | + | ||
18 | +import com.fasterxml.jackson.core.JsonProcessingException; | ||
19 | +import lombok.Getter; | ||
20 | +import lombok.extern.slf4j.Slf4j; | ||
21 | +import org.thingsboard.server.common.data.id.RuleChainId; | ||
22 | +import org.thingsboard.server.common.data.id.RuleNodeId; | ||
23 | +import org.thingsboard.server.common.data.rule.RuleNode; | ||
24 | + | ||
25 | +@Slf4j | ||
26 | +public class RuleNodeException extends RuleEngineException { | ||
27 | + @Getter | ||
28 | + private final String ruleChainName; | ||
29 | + @Getter | ||
30 | + private final String ruleNodeName; | ||
31 | + @Getter | ||
32 | + private final RuleChainId ruleChainId; | ||
33 | + @Getter | ||
34 | + private final RuleNodeId ruleNodeId; | ||
35 | + | ||
36 | + public RuleNodeException(String message, String ruleChainName, RuleNode ruleNode) { | ||
37 | + super(message); | ||
38 | + this.ruleChainName = ruleChainName; | ||
39 | + this.ruleNodeName = ruleNode.getName(); | ||
40 | + this.ruleChainId = ruleNode.getRuleChainId(); | ||
41 | + this.ruleNodeId = ruleNode.getId(); | ||
42 | + } | ||
43 | + | ||
44 | + public String toJsonString() { | ||
45 | + try { | ||
46 | + return mapper.writeValueAsString(mapper.createObjectNode() | ||
47 | + .put("ruleNodeId", ruleNodeId.toString()) | ||
48 | + .put("ruleChainId", ruleChainId.toString()) | ||
49 | + .put("ruleNodeName", ruleNodeName) | ||
50 | + .put("ruleChainName", ruleChainName) | ||
51 | + .put("message", getMessage())); | ||
52 | + } catch (JsonProcessingException e) { | ||
53 | + log.warn("Failed to serialize exception ", e); | ||
54 | + throw new RuntimeException(e); | ||
55 | + } | ||
56 | + } | ||
57 | + | ||
58 | +} |
common/message/src/main/java/org/thingsboard/server/common/msg/queue/TbCallback.java
renamed from
application/src/main/java/org/thingsboard/server/actors/shared/rulechain/SystemRuleChainManager.java
@@ -13,36 +13,25 @@ | @@ -13,36 +13,25 @@ | ||
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | -package org.thingsboard.server.actors.shared.rulechain; | ||
17 | - | ||
18 | -import org.thingsboard.server.actors.ActorSystemContext; | ||
19 | -import org.thingsboard.server.actors.service.DefaultActorService; | ||
20 | -import org.thingsboard.server.common.data.id.TenantId; | ||
21 | -import org.thingsboard.server.common.data.page.PageDataIterable.FetchFunction; | ||
22 | -import org.thingsboard.server.common.data.page.TextPageData; | ||
23 | -import org.thingsboard.server.common.data.rule.RuleChain; | ||
24 | -import org.thingsboard.server.dao.model.ModelConstants; | ||
25 | - | ||
26 | -import java.util.Collections; | ||
27 | - | ||
28 | -public class SystemRuleChainManager extends RuleChainManager { | ||
29 | - | ||
30 | - public SystemRuleChainManager(ActorSystemContext systemContext) { | ||
31 | - super(systemContext); | ||
32 | - } | ||
33 | - | ||
34 | - @Override | ||
35 | - protected FetchFunction<RuleChain> getFetchEntitiesFunction() { | ||
36 | - return link -> new TextPageData<>(Collections.emptyList(), link); | ||
37 | - } | ||
38 | - | ||
39 | - @Override | ||
40 | - protected TenantId getTenantId() { | ||
41 | - return ModelConstants.SYSTEM_TENANT; | ||
42 | - } | ||
43 | - | ||
44 | - @Override | ||
45 | - protected String getDispatcherName() { | ||
46 | - return DefaultActorService.SYSTEM_RULE_DISPATCHER_NAME; | ||
47 | - } | 16 | +package org.thingsboard.server.common.msg.queue; |
17 | + | ||
18 | +public interface TbCallback { | ||
19 | + | ||
20 | + TbCallback EMPTY = new TbCallback() { | ||
21 | + | ||
22 | + @Override | ||
23 | + public void onSuccess() { | ||
24 | + | ||
25 | + } | ||
26 | + | ||
27 | + @Override | ||
28 | + public void onFailure(Throwable t) { | ||
29 | + | ||
30 | + } | ||
31 | + }; | ||
32 | + | ||
33 | + void onSuccess(); | ||
34 | + | ||
35 | + void onFailure(Throwable t); | ||
36 | + | ||
48 | } | 37 | } |
@@ -25,13 +25,13 @@ public interface TbMsgCallback { | @@ -25,13 +25,13 @@ public interface TbMsgCallback { | ||
25 | } | 25 | } |
26 | 26 | ||
27 | @Override | 27 | @Override |
28 | - public void onFailure(Throwable t) { | 28 | + public void onFailure(RuleEngineException e) { |
29 | 29 | ||
30 | } | 30 | } |
31 | }; | 31 | }; |
32 | 32 | ||
33 | void onSuccess(); | 33 | void onSuccess(); |
34 | 34 | ||
35 | - void onFailure(Throwable t); | 35 | + void onFailure(RuleEngineException e); |
36 | 36 | ||
37 | } | 37 | } |
@@ -15,6 +15,8 @@ | @@ -15,6 +15,8 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.queue.common; | 16 | package org.thingsboard.server.queue.common; |
17 | 17 | ||
18 | +import org.thingsboard.server.common.msg.queue.RuleEngineException; | ||
19 | +import org.thingsboard.server.common.msg.queue.TbCallback; | ||
18 | import org.thingsboard.server.common.msg.queue.TbMsgCallback; | 20 | import org.thingsboard.server.common.msg.queue.TbMsgCallback; |
19 | import org.thingsboard.server.queue.TbQueueCallback; | 21 | import org.thingsboard.server.queue.TbQueueCallback; |
20 | import org.thingsboard.server.queue.TbQueueMsgMetadata; | 22 | import org.thingsboard.server.queue.TbQueueMsgMetadata; |
@@ -40,6 +42,6 @@ public class MultipleTbQueueTbMsgCallbackWrapper implements TbQueueCallback { | @@ -40,6 +42,6 @@ public class MultipleTbQueueTbMsgCallbackWrapper implements TbQueueCallback { | ||
40 | 42 | ||
41 | @Override | 43 | @Override |
42 | public void onFailure(Throwable t) { | 44 | public void onFailure(Throwable t) { |
43 | - tbMsgCallback.onFailure(t); | 45 | + tbMsgCallback.onFailure(new RuleEngineException(t.getMessage())); |
44 | } | 46 | } |
45 | } | 47 | } |
@@ -15,12 +15,12 @@ | @@ -15,12 +15,12 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.queue.common; | 16 | package org.thingsboard.server.queue.common; |
17 | 17 | ||
18 | +import org.thingsboard.server.common.msg.queue.RuleEngineException; | ||
19 | +import org.thingsboard.server.common.msg.queue.TbCallback; | ||
18 | import org.thingsboard.server.common.msg.queue.TbMsgCallback; | 20 | import org.thingsboard.server.common.msg.queue.TbMsgCallback; |
19 | import org.thingsboard.server.queue.TbQueueCallback; | 21 | import org.thingsboard.server.queue.TbQueueCallback; |
20 | import org.thingsboard.server.queue.TbQueueMsgMetadata; | 22 | import org.thingsboard.server.queue.TbQueueMsgMetadata; |
21 | 23 | ||
22 | -import java.util.concurrent.atomic.AtomicInteger; | ||
23 | - | ||
24 | public class TbQueueTbMsgCallbackWrapper implements TbQueueCallback { | 24 | public class TbQueueTbMsgCallbackWrapper implements TbQueueCallback { |
25 | 25 | ||
26 | private final TbMsgCallback tbMsgCallback; | 26 | private final TbMsgCallback tbMsgCallback; |
@@ -36,6 +36,6 @@ public class TbQueueTbMsgCallbackWrapper implements TbQueueCallback { | @@ -36,6 +36,6 @@ public class TbQueueTbMsgCallbackWrapper implements TbQueueCallback { | ||
36 | 36 | ||
37 | @Override | 37 | @Override |
38 | public void onFailure(Throwable t) { | 38 | public void onFailure(Throwable t) { |
39 | - tbMsgCallback.onFailure(t); | 39 | + tbMsgCallback.onFailure(new RuleEngineException(t.getMessage())); |
40 | } | 40 | } |
41 | } | 41 | } |
@@ -86,24 +86,6 @@ public class ConsistentHashPartitionService implements PartitionService { | @@ -86,24 +86,6 @@ public class ConsistentHashPartitionService implements PartitionService { | ||
86 | partitionTopics.put(new ServiceQueue(ServiceType.TB_CORE), coreTopic); | 86 | partitionTopics.put(new ServiceQueue(ServiceType.TB_CORE), coreTopic); |
87 | } | 87 | } |
88 | 88 | ||
89 | -// public Set<TopicPartitionInfo> getCurrentPartitions(ServiceType serviceType) { | ||
90 | -// ServiceInfo currentService = serviceInfoProvider.getServiceInfo(); | ||
91 | -// TenantId tenantId = getSystemOrIsolatedTenantId(currentService); | ||
92 | -// ServiceQueueKey serviceQueueKey = new ServiceQueueKey(serviceType, tenantId); | ||
93 | -// List<Integer> partitions = myPartitions.get(serviceQueueKey); | ||
94 | -// Set<TopicPartitionInfo> topicPartitions = new LinkedHashSet<>(); | ||
95 | -// for (Integer partition : partitions) { | ||
96 | -// TopicPartitionInfo.TopicPartitionInfoBuilder tpi = TopicPartitionInfo.builder(); | ||
97 | -// tpi.topic(partitionTopics.get(serviceType)); | ||
98 | -// tpi.partition(partition); | ||
99 | -// if (!tenantId.isNullUid()) { | ||
100 | -// tpi.tenantId(tenantId); | ||
101 | -// } | ||
102 | -// topicPartitions.add(tpi.build()); | ||
103 | -// } | ||
104 | -// return topicPartitions; | ||
105 | -// } | ||
106 | - | ||
107 | @Override | 89 | @Override |
108 | public TopicPartitionInfo resolve(ServiceType serviceType, TenantId tenantId, EntityId entityId) { | 90 | public TopicPartitionInfo resolve(ServiceType serviceType, TenantId tenantId, EntityId entityId) { |
109 | return resolve(new ServiceQueue(serviceType), tenantId, entityId); | 91 | return resolve(new ServiceQueue(serviceType), tenantId, entityId); |
@@ -131,15 +113,7 @@ public class ConsistentHashPartitionService implements PartitionService { | @@ -131,15 +113,7 @@ public class ConsistentHashPartitionService implements PartitionService { | ||
131 | Map<ServiceQueueKey, ConsistentHashCircle<ServiceInfo>> circles = new HashMap<>(); | 113 | Map<ServiceQueueKey, ConsistentHashCircle<ServiceInfo>> circles = new HashMap<>(); |
132 | addNode(circles, currentService); | 114 | addNode(circles, currentService); |
133 | for (ServiceInfo other : otherServices) { | 115 | for (ServiceInfo other : otherServices) { |
134 | - TenantId tenantId = getSystemOrIsolatedTenantId(other); | ||
135 | addNode(circles, other); | 116 | addNode(circles, other); |
136 | - if (!tenantId.isNullUid()) { | ||
137 | - isolatedTenants.putIfAbsent(tenantId, new HashSet<>()); | ||
138 | - for (String serviceType : other.getServiceTypesList()) { | ||
139 | - isolatedTenants.get(tenantId).add(ServiceType.valueOf(serviceType.toUpperCase())); | ||
140 | - } | ||
141 | - | ||
142 | - } | ||
143 | } | 117 | } |
144 | ConcurrentMap<ServiceQueueKey, List<Integer>> oldPartitions = myPartitions; | 118 | ConcurrentMap<ServiceQueueKey, List<Integer>> oldPartitions = myPartitions; |
145 | TenantId myTenantId = getSystemOrIsolatedTenantId(currentService); | 119 | TenantId myTenantId = getSystemOrIsolatedTenantId(currentService); |
@@ -214,6 +188,11 @@ public class ConsistentHashPartitionService implements PartitionService { | @@ -214,6 +188,11 @@ public class ConsistentHashPartitionService implements PartitionService { | ||
214 | } | 188 | } |
215 | } | 189 | } |
216 | 190 | ||
191 | + @Override | ||
192 | + public Set<TenantId> getIsolatedTenants(ServiceType serviceType) { | ||
193 | + throw new RuntimeException("Not Implemented!"); | ||
194 | + } | ||
195 | + | ||
217 | private Map<ServiceQueueKey, List<ServiceInfo>> getServiceKeyListMap(List<ServiceInfo> services) { | 196 | private Map<ServiceQueueKey, List<ServiceInfo>> getServiceKeyListMap(List<ServiceInfo> services) { |
218 | final Map<ServiceQueueKey, List<ServiceInfo>> currentMap = new HashMap<>(); | 197 | final Map<ServiceQueueKey, List<ServiceInfo>> currentMap = new HashMap<>(); |
219 | services.forEach(serviceInfo -> { | 198 | services.forEach(serviceInfo -> { |
@@ -280,6 +259,12 @@ public class ConsistentHashPartitionService implements PartitionService { | @@ -280,6 +259,12 @@ public class ConsistentHashPartitionService implements PartitionService { | ||
280 | 259 | ||
281 | private void addNode(Map<ServiceQueueKey, ConsistentHashCircle<ServiceInfo>> circles, ServiceInfo instance) { | 260 | private void addNode(Map<ServiceQueueKey, ConsistentHashCircle<ServiceInfo>> circles, ServiceInfo instance) { |
282 | TenantId tenantId = getSystemOrIsolatedTenantId(instance); | 261 | TenantId tenantId = getSystemOrIsolatedTenantId(instance); |
262 | + if (!tenantId.isNullUid()) { | ||
263 | + isolatedTenants.putIfAbsent(tenantId, new HashSet<>()); | ||
264 | + for (String serviceType : instance.getServiceTypesList()) { | ||
265 | + isolatedTenants.get(tenantId).add(ServiceType.valueOf(serviceType.toUpperCase())); | ||
266 | + } | ||
267 | + } | ||
283 | for (String serviceTypeStr : instance.getServiceTypesList()) { | 268 | for (String serviceTypeStr : instance.getServiceTypesList()) { |
284 | ServiceType serviceType = ServiceType.valueOf(serviceTypeStr.toUpperCase()); | 269 | ServiceType serviceType = ServiceType.valueOf(serviceTypeStr.toUpperCase()); |
285 | if (ServiceType.TB_RULE_ENGINE.equals(serviceType)) { | 270 | if (ServiceType.TB_RULE_ENGINE.equals(serviceType)) { |
@@ -34,6 +34,7 @@ import java.net.UnknownHostException; | @@ -34,6 +34,7 @@ import java.net.UnknownHostException; | ||
34 | import java.util.Arrays; | 34 | import java.util.Arrays; |
35 | import java.util.Collections; | 35 | import java.util.Collections; |
36 | import java.util.List; | 36 | import java.util.List; |
37 | +import java.util.Optional; | ||
37 | import java.util.UUID; | 38 | import java.util.UUID; |
38 | import java.util.stream.Collectors; | 39 | import java.util.stream.Collectors; |
39 | 40 | ||
@@ -58,6 +59,7 @@ public class DefaultTbServiceInfoProvider implements TbServiceInfoProvider { | @@ -58,6 +59,7 @@ public class DefaultTbServiceInfoProvider implements TbServiceInfoProvider { | ||
58 | 59 | ||
59 | private List<ServiceType> serviceTypes; | 60 | private List<ServiceType> serviceTypes; |
60 | private ServiceInfo serviceInfo; | 61 | private ServiceInfo serviceInfo; |
62 | + private TenantId isolatedTenant; | ||
61 | 63 | ||
62 | @PostConstruct | 64 | @PostConstruct |
63 | public void init() { | 65 | public void init() { |
@@ -80,6 +82,7 @@ public class DefaultTbServiceInfoProvider implements TbServiceInfoProvider { | @@ -80,6 +82,7 @@ public class DefaultTbServiceInfoProvider implements TbServiceInfoProvider { | ||
80 | UUID tenantId; | 82 | UUID tenantId; |
81 | if (!StringUtils.isEmpty(tenantIdStr)) { | 83 | if (!StringUtils.isEmpty(tenantIdStr)) { |
82 | tenantId = UUID.fromString(tenantIdStr); | 84 | tenantId = UUID.fromString(tenantIdStr); |
85 | + isolatedTenant = new TenantId(tenantId); | ||
83 | } else { | 86 | } else { |
84 | tenantId = TenantId.NULL_UUID; | 87 | tenantId = TenantId.NULL_UUID; |
85 | } | 88 | } |
@@ -103,4 +106,14 @@ public class DefaultTbServiceInfoProvider implements TbServiceInfoProvider { | @@ -103,4 +106,14 @@ public class DefaultTbServiceInfoProvider implements TbServiceInfoProvider { | ||
103 | public ServiceInfo getServiceInfo() { | 106 | public ServiceInfo getServiceInfo() { |
104 | return serviceInfo; | 107 | return serviceInfo; |
105 | } | 108 | } |
109 | + | ||
110 | + @Override | ||
111 | + public boolean isService(ServiceType serviceType) { | ||
112 | + return serviceTypes.contains(serviceType); | ||
113 | + } | ||
114 | + | ||
115 | + @Override | ||
116 | + public Optional<TenantId> getIsolatedTenant() { | ||
117 | + return Optional.ofNullable(isolatedTenant); | ||
118 | + } | ||
106 | } | 119 | } |
@@ -47,6 +47,8 @@ public interface PartitionService { | @@ -47,6 +47,8 @@ public interface PartitionService { | ||
47 | */ | 47 | */ |
48 | Set<String> getAllServiceIds(ServiceType serviceType); | 48 | Set<String> getAllServiceIds(ServiceType serviceType); |
49 | 49 | ||
50 | + Set<TenantId> getIsolatedTenants(ServiceType serviceType); | ||
51 | + | ||
50 | /** | 52 | /** |
51 | * Each Service should start a consumer for messages that target individual service instance based on serviceId. | 53 | * Each Service should start a consumer for messages that target individual service instance based on serviceId. |
52 | * This topic is likely to have single partition, and is always assigned to the service. | 54 | * This topic is likely to have single partition, and is always assigned to the service. |
@@ -15,12 +15,20 @@ | @@ -15,12 +15,20 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.queue.discovery; | 16 | package org.thingsboard.server.queue.discovery; |
17 | 17 | ||
18 | +import org.thingsboard.server.common.data.id.TenantId; | ||
19 | +import org.thingsboard.server.common.msg.queue.ServiceType; | ||
18 | import org.thingsboard.server.gen.transport.TransportProtos.ServiceInfo; | 20 | import org.thingsboard.server.gen.transport.TransportProtos.ServiceInfo; |
19 | 21 | ||
22 | +import java.util.Optional; | ||
23 | + | ||
20 | public interface TbServiceInfoProvider { | 24 | public interface TbServiceInfoProvider { |
21 | 25 | ||
22 | String getServiceId(); | 26 | String getServiceId(); |
23 | 27 | ||
24 | ServiceInfo getServiceInfo(); | 28 | ServiceInfo getServiceInfo(); |
25 | 29 | ||
30 | + boolean isService(ServiceType serviceType); | ||
31 | + | ||
32 | + Optional<TenantId> getIsolatedTenant(); | ||
33 | + | ||
26 | } | 34 | } |
@@ -17,7 +17,9 @@ package org.thingsboard.server.queue.settings; | @@ -17,7 +17,9 @@ package org.thingsboard.server.queue.settings; | ||
17 | 17 | ||
18 | import lombok.Data; | 18 | import lombok.Data; |
19 | import lombok.extern.slf4j.Slf4j; | 19 | import lombok.extern.slf4j.Slf4j; |
20 | +import org.springframework.beans.factory.annotation.Autowired; | ||
20 | import org.springframework.beans.factory.annotation.Value; | 21 | import org.springframework.beans.factory.annotation.Value; |
22 | +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; | ||
21 | import org.springframework.boot.context.properties.ConfigurationProperties; | 23 | import org.springframework.boot.context.properties.ConfigurationProperties; |
22 | import org.springframework.context.annotation.Configuration; | 24 | import org.springframework.context.annotation.Configuration; |
23 | 25 | ||
@@ -26,6 +28,7 @@ import java.util.List; | @@ -26,6 +28,7 @@ import java.util.List; | ||
26 | 28 | ||
27 | @Slf4j | 29 | @Slf4j |
28 | @Data | 30 | @Data |
31 | +@EnableAutoConfiguration | ||
29 | @Configuration | 32 | @Configuration |
30 | @ConfigurationProperties(prefix = "queue.rule-engine") | 33 | @ConfigurationProperties(prefix = "queue.rule-engine") |
31 | public class TbQueueRuleEngineSettings { | 34 | public class TbQueueRuleEngineSettings { |
@@ -388,6 +388,7 @@ message ToRuleEngineMsg { | @@ -388,6 +388,7 @@ message ToRuleEngineMsg { | ||
388 | int64 tenantIdLSB = 2; | 388 | int64 tenantIdLSB = 2; |
389 | bytes tbMsg = 3; | 389 | bytes tbMsg = 3; |
390 | repeated string relationTypes = 4; | 390 | repeated string relationTypes = 4; |
391 | + string failureMessage = 5; | ||
391 | } | 392 | } |
392 | 393 | ||
393 | message ToRuleEngineNotificationMsg { | 394 | message ToRuleEngineNotificationMsg { |
@@ -16,7 +16,6 @@ | @@ -16,7 +16,6 @@ | ||
16 | package org.thingsboard.rule.engine.api; | 16 | package org.thingsboard.rule.engine.api; |
17 | 17 | ||
18 | import org.thingsboard.server.common.msg.TbMsg; | 18 | import org.thingsboard.server.common.msg.TbMsg; |
19 | -import org.thingsboard.server.common.msg.cluster.ServerAddress; | ||
20 | 19 | ||
21 | import java.util.function.Consumer; | 20 | import java.util.function.Consumer; |
22 | 21 | ||
@@ -26,6 +25,4 @@ public interface RuleChainTransactionService { | @@ -26,6 +25,4 @@ public interface RuleChainTransactionService { | ||
26 | 25 | ||
27 | void endTransaction(TbMsg msg, Consumer<TbMsg> onSuccess, Consumer<Throwable> onFailure); | 26 | void endTransaction(TbMsg msg, Consumer<TbMsg> onSuccess, Consumer<Throwable> onFailure); |
28 | 27 | ||
29 | - void onRemoteTransactionMsg(ServerAddress serverAddress, byte[] bytes); | ||
30 | - | ||
31 | } | 28 | } |
@@ -26,10 +26,8 @@ import org.thingsboard.server.common.data.asset.Asset; | @@ -26,10 +26,8 @@ import org.thingsboard.server.common.data.asset.Asset; | ||
26 | import org.thingsboard.server.common.data.id.EntityId; | 26 | import org.thingsboard.server.common.data.id.EntityId; |
27 | import org.thingsboard.server.common.data.id.RuleNodeId; | 27 | import org.thingsboard.server.common.data.id.RuleNodeId; |
28 | import org.thingsboard.server.common.data.id.TenantId; | 28 | import org.thingsboard.server.common.data.id.TenantId; |
29 | -import org.thingsboard.server.common.data.rule.RuleNode; | ||
30 | import org.thingsboard.server.common.msg.TbMsg; | 29 | import org.thingsboard.server.common.msg.TbMsg; |
31 | import org.thingsboard.server.common.msg.TbMsgMetaData; | 30 | import org.thingsboard.server.common.msg.TbMsgMetaData; |
32 | -import org.thingsboard.server.common.msg.queue.TbMsgCallback; | ||
33 | import org.thingsboard.server.dao.alarm.AlarmService; | 31 | import org.thingsboard.server.dao.alarm.AlarmService; |
34 | import org.thingsboard.server.dao.asset.AssetService; | 32 | import org.thingsboard.server.dao.asset.AssetService; |
35 | import org.thingsboard.server.dao.attributes.AttributesService; | 33 | import org.thingsboard.server.dao.attributes.AttributesService; |
@@ -116,6 +114,8 @@ public interface TbContext { | @@ -116,6 +114,8 @@ public interface TbContext { | ||
116 | */ | 114 | */ |
117 | void enqueue(TbMsg msg, String queueName, Runnable onSuccess, Consumer<Throwable> onFailure); | 115 | void enqueue(TbMsg msg, String queueName, Runnable onSuccess, Consumer<Throwable> onFailure); |
118 | 116 | ||
117 | + void enqueueForTellFailure(TbMsg msg, String failureMessage); | ||
118 | + | ||
119 | void enqueueForTellNext(TbMsg msg, String relationType); | 119 | void enqueueForTellNext(TbMsg msg, String relationType); |
120 | 120 | ||
121 | void enqueueForTellNext(TbMsg msg, Set<String> relationTypes); | 121 | void enqueueForTellNext(TbMsg msg, Set<String> relationTypes); |
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/flow/TbAckNode.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.rule.engine.flow; | ||
17 | + | ||
18 | +import lombok.extern.slf4j.Slf4j; | ||
19 | +import org.thingsboard.rule.engine.api.EmptyNodeConfiguration; | ||
20 | +import org.thingsboard.rule.engine.api.RuleNode; | ||
21 | +import org.thingsboard.rule.engine.api.TbContext; | ||
22 | +import org.thingsboard.rule.engine.api.TbNode; | ||
23 | +import org.thingsboard.rule.engine.api.TbNodeConfiguration; | ||
24 | +import org.thingsboard.rule.engine.api.TbNodeException; | ||
25 | +import org.thingsboard.rule.engine.api.TbRelationTypes; | ||
26 | +import org.thingsboard.rule.engine.api.util.TbNodeUtils; | ||
27 | +import org.thingsboard.server.common.data.plugin.ComponentType; | ||
28 | +import org.thingsboard.server.common.msg.TbMsg; | ||
29 | + | ||
30 | +@Slf4j | ||
31 | +@RuleNode( | ||
32 | + type = ComponentType.ACTION, | ||
33 | + name = "acknowledge", | ||
34 | + configClazz = EmptyNodeConfiguration.class, | ||
35 | + nodeDescription = "Acknowledges the incoming message", | ||
36 | + nodeDetails = "After acknowledgement, the message is pushed to related rule nodes. Useful if you don't care what happens to this message next.") | ||
37 | + | ||
38 | +public class TbAckNode implements TbNode { | ||
39 | + | ||
40 | + @Override | ||
41 | + public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException { | ||
42 | + } | ||
43 | + | ||
44 | + @Override | ||
45 | + public void onMsg(TbContext ctx, TbMsg msg) { | ||
46 | + ctx.ack(msg); | ||
47 | + ctx.tellSuccess(msg); | ||
48 | + } | ||
49 | + | ||
50 | + @Override | ||
51 | + public void destroy() { | ||
52 | + } | ||
53 | +} |
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.rule.engine.flow; | ||
17 | + | ||
18 | +import lombok.extern.slf4j.Slf4j; | ||
19 | +import org.thingsboard.rule.engine.api.RuleNode; | ||
20 | +import org.thingsboard.rule.engine.api.ScriptEngine; | ||
21 | +import org.thingsboard.rule.engine.api.TbContext; | ||
22 | +import org.thingsboard.rule.engine.api.TbNode; | ||
23 | +import org.thingsboard.rule.engine.api.TbNodeConfiguration; | ||
24 | +import org.thingsboard.rule.engine.api.TbNodeException; | ||
25 | +import org.thingsboard.rule.engine.api.TbRelationTypes; | ||
26 | +import org.thingsboard.rule.engine.api.util.TbNodeUtils; | ||
27 | +import org.thingsboard.server.common.data.plugin.ComponentType; | ||
28 | +import org.thingsboard.server.common.msg.TbMsg; | ||
29 | + | ||
30 | +import static org.thingsboard.common.util.DonAsynchron.withCallback; | ||
31 | + | ||
32 | +@Slf4j | ||
33 | +@RuleNode( | ||
34 | + type = ComponentType.ACTION, | ||
35 | + name = "checkpoint", | ||
36 | + configClazz = TbCheckpointNodeConfiguration.class, | ||
37 | + nodeDescription = "transfers the message to another queue", | ||
38 | + nodeDetails = "After successful transfer incoming message is automatically acknowledged. Queue name is configurable.") | ||
39 | + | ||
40 | +public class TbCheckpointNode implements TbNode { | ||
41 | + | ||
42 | + private TbCheckpointNodeConfiguration config; | ||
43 | + | ||
44 | + @Override | ||
45 | + public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException { | ||
46 | + this.config = TbNodeUtils.convert(configuration, TbCheckpointNodeConfiguration.class); | ||
47 | + } | ||
48 | + | ||
49 | + @Override | ||
50 | + public void onMsg(TbContext ctx, TbMsg msg) { | ||
51 | + ctx.enqueueForTellNext(msg, config.getQueueName(), TbRelationTypes.SUCCESS, () -> ctx.ack(msg), error -> ctx.tellFailure(msg, error)); | ||
52 | + } | ||
53 | + | ||
54 | + @Override | ||
55 | + public void destroy() { | ||
56 | + } | ||
57 | +} |
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/flow/TbCheckpointNodeConfiguration.java
renamed from
common/message/src/main/java/org/thingsboard/server/common/msg/cluster/SendToClusterMsg.java
@@ -13,28 +13,20 @@ | @@ -13,28 +13,20 @@ | ||
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | -package org.thingsboard.server.common.msg.cluster; | 16 | +package org.thingsboard.rule.engine.flow; |
17 | 17 | ||
18 | import lombok.Data; | 18 | import lombok.Data; |
19 | -import org.thingsboard.server.common.data.id.DeviceId; | ||
20 | -import org.thingsboard.server.common.data.id.EntityId; | ||
21 | -import org.thingsboard.server.common.msg.MsgType; | ||
22 | -import org.thingsboard.server.common.msg.TbActorMsg; | 19 | +import org.thingsboard.rule.engine.api.NodeConfiguration; |
23 | 20 | ||
24 | @Data | 21 | @Data |
25 | -public class SendToClusterMsg implements TbActorMsg { | ||
26 | - | ||
27 | - private TbActorMsg msg; | ||
28 | - private EntityId entityId; | ||
29 | - | ||
30 | - public SendToClusterMsg(EntityId entityId, TbActorMsg msg) { | ||
31 | - this.entityId = entityId; | ||
32 | - this.msg = msg; | ||
33 | - } | 22 | +public class TbCheckpointNodeConfiguration implements NodeConfiguration<TbCheckpointNodeConfiguration> { |
34 | 23 | ||
24 | + private String queueName; | ||
35 | 25 | ||
36 | @Override | 26 | @Override |
37 | - public MsgType getMsgType() { | ||
38 | - return MsgType.SEND_TO_CLUSTER_MSG; | 27 | + public TbCheckpointNodeConfiguration defaultConfiguration() { |
28 | + TbCheckpointNodeConfiguration configuration = new TbCheckpointNodeConfiguration(); | ||
29 | + configuration.setQueueName("HighPriority"); | ||
30 | + return configuration; | ||
39 | } | 31 | } |
40 | } | 32 | } |
@@ -116,8 +116,7 @@ public class TbSendRPCRequestNode implements TbNode { | @@ -116,8 +116,7 @@ public class TbSendRPCRequestNode implements TbNode { | ||
116 | ctx.enqueueForTellNext(next, TbRelationTypes.SUCCESS); | 116 | ctx.enqueueForTellNext(next, TbRelationTypes.SUCCESS); |
117 | } else { | 117 | } else { |
118 | TbMsg next = ctx.newMsg(msg.getType(), msg.getOriginator(), msg.getMetaData(), wrap("error", ruleEngineDeviceRpcResponse.getError().get().name())); | 118 | TbMsg next = ctx.newMsg(msg.getType(), msg.getOriginator(), msg.getMetaData(), wrap("error", ruleEngineDeviceRpcResponse.getError().get().name())); |
119 | - ctx.tellFailure(next, new RuntimeException(ruleEngineDeviceRpcResponse.getError().get().name())); | ||
120 | - ctx.enqueueForTellNext(next, TbRelationTypes.FAILURE); | 119 | + ctx.enqueueForTellFailure(next, ruleEngineDeviceRpcResponse.getError().get().name()); |
121 | } | 120 | } |
122 | }); | 121 | }); |
123 | ctx.ack(msg); | 122 | ctx.ack(msg); |
@@ -102,20 +102,44 @@ queue: | @@ -102,20 +102,44 @@ queue: | ||
102 | stats: | 102 | stats: |
103 | enabled: "${TB_QUEUE_CORE_STATS_ENABLED:false}" | 103 | enabled: "${TB_QUEUE_CORE_STATS_ENABLED:false}" |
104 | print_interval_ms: "${TB_QUEUE_CORE_STATS_PRINT_INTERVAL_MS:10000}" | 104 | print_interval_ms: "${TB_QUEUE_CORE_STATS_PRINT_INTERVAL_MS:10000}" |
105 | - rule_engine: | 105 | + rule-engine: |
106 | topic: "${TB_QUEUE_RULE_ENGINE_TOPIC:tb.rule-engine}" | 106 | topic: "${TB_QUEUE_RULE_ENGINE_TOPIC:tb.rule-engine}" |
107 | - poll_interval: "${TB_QUEUE_RULE_ENGINE_POLL_INTERVAL_MS:25}" | ||
108 | - partitions: "${TB_QUEUE_RULE_ENGINE_PARTITIONS:10}" | ||
109 | - pack_processing_timeout: "${TB_QUEUE_RULE_ENGINE_PACK_PROCESSING_TIMEOUT_MS:60000}" | 107 | + poll-interval: "${TB_QUEUE_RULE_ENGINE_POLL_INTERVAL_MS:25}" |
108 | + pack-processing-timeout: "${TB_QUEUE_RULE_ENGINE_PACK_PROCESSING_TIMEOUT_MS:60000}" | ||
110 | stats: | 109 | stats: |
111 | - enabled: "${TB_QUEUE_RULE_ENGINE_STATS_ENABLED:false}" | ||
112 | - print_interval_ms: "${TB_QUEUE_RULE_ENGINE_STATS_PRINT_INTERVAL_MS:10000}" | 110 | + enabled: "${TB_QUEUE_RULE_ENGINE_STATS_ENABLED:true}" |
111 | + print-interval-ms: "${TB_QUEUE_RULE_ENGINE_STATS_PRINT_INTERVAL_MS:10000}" | ||
112 | + queues: # TODO 2.5: specify correct ENV variable names. | ||
113 | + - | ||
114 | + name: "Main" | ||
115 | + topic: "${TB_QUEUE_RULE_ENGINE_TOPIC:tb.rule-engine.main}" | ||
116 | + poll-interval: "${TB_QUEUE_RULE_ENGINE_POLL_INTERVAL_MS:25}" | ||
117 | + partitions: "${TB_QUEUE_RULE_ENGINE_PARTITIONS:10}" | ||
118 | + pack-processing-timeout: "${TB_QUEUE_RULE_ENGINE_PACK_PROCESSING_TIMEOUT_MS:60000}" | ||
119 | + ack-strategy: | ||
120 | + type: "${TB_QUEUE_RULE_ENGINE_STRATEGY_TYPE:RETRY_FAILED_AND_TIMED_OUT}" # SKIP_ALL_FAILURES, RETRY_ALL, RETRY_FAILED, RETRY_TIMED_OUT, RETRY_FAILED_AND_TIMED_OUT | ||
121 | + # For RETRY_ALL, RETRY_FAILED, RETRY_TIMED_OUT, RETRY_FAILED_AND_TIMED_OUT | ||
122 | + retries: "${TB_QUEUE_RULE_ENGINE_STRATEGY_RETRIES:3}" # Number of retries, 0 is unlimited | ||
123 | + failure-percentage: "${TB_QUEUE_RULE_ENGINE_STRATEGY_FAILURE_PERCENTAGE:0}" # Skip retry if failures or timeouts are less then X percentage of messages; | ||
124 | + pause-between-retries: "${TB_QUEUE_RULE_ENGINE_STRATEGY_RETRY_PAUSE:3}"# Time in seconds to wait in consumer thread before retries; | ||
125 | + - | ||
126 | + name: "HighPriority" | ||
127 | + topic: "${TB_QUEUE_RULE_ENGINE_TOPIC:tb.rule-engine.hp}" | ||
128 | + poll-interval: "${TB_QUEUE_RULE_ENGINE_POLL_INTERVAL_MS:25}" | ||
129 | + partitions: "${TB_QUEUE_RULE_ENGINE_PARTITIONS:3}" | ||
130 | + pack-processing-timeout: "${TB_QUEUE_RULE_ENGINE_PACK_PROCESSING_TIMEOUT_MS:60000}" | ||
131 | + ack-strategy: | ||
132 | + type: "${TB_QUEUE_RULE_ENGINE_STRATEGY_TYPE:RETRY_FAILED_AND_TIMED_OUT}" # SKIP_ALL_FAILURES, RETRY_ALL, RETRY_FAILED, RETRY_TIMED_OUT, RETRY_FAILED_AND_TIMED_OUT | ||
133 | + # For RETRY_ALL, RETRY_FAILED, RETRY_TIMED_OUT, RETRY_FAILED_AND_TIMED_OUT | ||
134 | + retries: "${TB_QUEUE_RULE_ENGINE_STRATEGY_RETRIES:0}" # Number of retries, 0 is unlimited | ||
135 | + failure-percentage: "${TB_QUEUE_RULE_ENGINE_STRATEGY_FAILURE_PERCENTAGE:0}" # Skip retry if failures or timeouts are less then X percentage of messages; | ||
136 | + pause-between-retries: "${TB_QUEUE_RULE_ENGINE_STRATEGY_RETRY_PAUSE:1}"# Time in seconds to wait in consumer thread before retries; | ||
113 | transport: | 137 | transport: |
114 | notifications_topic: "${TB_QUEUE_TRANSPORT_NOTIFICATIONS_TOPIC:tb.transport.notifications}" | 138 | notifications_topic: "${TB_QUEUE_TRANSPORT_NOTIFICATIONS_TOPIC:tb.transport.notifications}" |
115 | poll_interval: "${TB_QUEUE_CORE_POLL_INTERVAL_MS:25}" | 139 | poll_interval: "${TB_QUEUE_CORE_POLL_INTERVAL_MS:25}" |
116 | 140 | ||
117 | service: | 141 | service: |
118 | - type: "${TB_SERVICE_TYPE:tb-transport}" # monolith or tb-core or tb-rule-engine or tb-transport | 142 | + type: "${TB_SERVICE_TYPE:tb-transport}" |
119 | # Unique id for this service (autogenerated if empty) | 143 | # Unique id for this service (autogenerated if empty) |
120 | id: "${TB_SERVICE_ID:}" | 144 | id: "${TB_SERVICE_ID:}" |
121 | tenant_id: "${TB_SERVICE_TENANT_ID:}" # empty or specific tenant id. | 145 | tenant_id: "${TB_SERVICE_TENANT_ID:}" # empty or specific tenant id. |