Commit bb1585592badaa1ae00a888d55f34c2eebb3ba69

Authored by Andrii Shvaika
1 parent f572f473

Actor System refactoring

Showing 48 changed files with 796 additions and 683 deletions
@@ -59,6 +59,10 @@ @@ -59,6 +59,10 @@
59 </dependency> 59 </dependency>
60 <dependency> 60 <dependency>
61 <groupId>org.thingsboard.common</groupId> 61 <groupId>org.thingsboard.common</groupId>
  62 + <artifactId>actor</artifactId>
  63 + </dependency>
  64 + <dependency>
  65 + <groupId>org.thingsboard.common</groupId>
62 <artifactId>util</artifactId> 66 <artifactId>util</artifactId>
63 </dependency> 67 </dependency>
64 <dependency> 68 <dependency>
@@ -174,14 +178,6 @@ @@ -174,14 +178,6 @@
174 <artifactId>spring-context-support</artifactId> 178 <artifactId>spring-context-support</artifactId>
175 </dependency> 179 </dependency>
176 <dependency> 180 <dependency>
177 - <groupId>com.typesafe.akka</groupId>  
178 - <artifactId>akka-actor_${scala.version}</artifactId>  
179 - </dependency>  
180 - <dependency>  
181 - <groupId>com.typesafe.akka</groupId>  
182 - <artifactId>akka-slf4j_${scala.version}</artifactId>  
183 - </dependency>  
184 - <dependency>  
185 <groupId>org.slf4j</groupId> 181 <groupId>org.slf4j</groupId>
186 <artifactId>slf4j-api</artifactId> 182 <artifactId>slf4j-api</artifactId>
187 </dependency> 183 </dependency>
@@ -15,9 +15,6 @@ @@ -15,9 +15,6 @@
15 */ 15 */
16 package org.thingsboard.server.actors; 16 package org.thingsboard.server.actors;
17 17
18 -import akka.actor.ActorRef;  
19 -import akka.actor.ActorSystem;  
20 -import akka.actor.Scheduler;  
21 import com.fasterxml.jackson.databind.JsonNode; 18 import com.fasterxml.jackson.databind.JsonNode;
22 import com.fasterxml.jackson.databind.ObjectMapper; 19 import com.fasterxml.jackson.databind.ObjectMapper;
23 import com.fasterxml.jackson.databind.node.ObjectNode; 20 import com.fasterxml.jackson.databind.node.ObjectNode;
@@ -25,8 +22,6 @@ import com.google.common.util.concurrent.FutureCallback; @@ -25,8 +22,6 @@ import com.google.common.util.concurrent.FutureCallback;
25 import com.google.common.util.concurrent.Futures; 22 import com.google.common.util.concurrent.Futures;
26 import com.google.common.util.concurrent.ListenableFuture; 23 import com.google.common.util.concurrent.ListenableFuture;
27 import com.google.common.util.concurrent.MoreExecutors; 24 import com.google.common.util.concurrent.MoreExecutors;
28 -import com.typesafe.config.Config;  
29 -import com.typesafe.config.ConfigFactory;  
30 import lombok.Getter; 25 import lombok.Getter;
31 import lombok.Setter; 26 import lombok.Setter;
32 import lombok.extern.slf4j.Slf4j; 27 import lombok.extern.slf4j.Slf4j;
@@ -91,12 +86,13 @@ import java.io.StringWriter; @@ -91,12 +86,13 @@ import java.io.StringWriter;
91 import java.util.Optional; 86 import java.util.Optional;
92 import java.util.concurrent.ConcurrentHashMap; 87 import java.util.concurrent.ConcurrentHashMap;
93 import java.util.concurrent.ConcurrentMap; 88 import java.util.concurrent.ConcurrentMap;
  89 +import java.util.concurrent.ScheduledExecutorService;
  90 +import java.util.concurrent.TimeUnit;
94 import java.util.concurrent.atomic.AtomicInteger; 91 import java.util.concurrent.atomic.AtomicInteger;
95 92
96 @Slf4j 93 @Slf4j
97 @Component 94 @Component
98 public class ActorSystemContext { 95 public class ActorSystemContext {
99 - private static final String AKKA_CONF_FILE_NAME = "actor-system.conf";  
100 96
101 protected final ObjectMapper mapper = new ObjectMapper(); 97 protected final ObjectMapper mapper = new ObjectMapper();
102 98
@@ -260,14 +256,6 @@ public class ActorSystemContext { @@ -260,14 +256,6 @@ public class ActorSystemContext {
260 @Getter 256 @Getter
261 private long syncSessionTimeout; 257 private long syncSessionTimeout;
262 258
263 - @Value("${actors.queue.enabled}")  
264 - @Getter  
265 - private boolean queuePersistenceEnabled;  
266 -  
267 - @Value("${actors.queue.timeout}")  
268 - @Getter  
269 - private long queuePersistenceTimeout;  
270 -  
271 @Value("${actors.rule.chain.error_persist_frequency}") 259 @Value("${actors.rule.chain.error_persist_frequency}")
272 @Getter 260 @Getter
273 private long ruleChainErrorPersistFrequency; 261 private long ruleChainErrorPersistFrequency;
@@ -327,17 +315,14 @@ public class ActorSystemContext { @@ -327,17 +315,14 @@ public class ActorSystemContext {
327 315
328 @Getter 316 @Getter
329 @Setter 317 @Setter
330 - private ActorSystem actorSystem; 318 + private TbActorSystem actorSystem;
331 319
332 @Setter 320 @Setter
333 - private ActorRef appActor; 321 + private TbActorRef appActor;
334 322
335 @Getter 323 @Getter
336 @Setter 324 @Setter
337 - private ActorRef statsActor;  
338 -  
339 - @Getter  
340 - private final Config config; 325 + private TbActorRef statsActor;
341 326
342 @Autowired(required = false) 327 @Autowired(required = false)
343 @Getter 328 @Getter
@@ -351,14 +336,8 @@ public class ActorSystemContext { @@ -351,14 +336,8 @@ public class ActorSystemContext {
351 @Getter 336 @Getter
352 private RedisTemplate<String, Object> redisTemplate; 337 private RedisTemplate<String, Object> redisTemplate;
353 338
354 - public ActorSystemContext() {  
355 - config = ConfigFactory.parseResources(AKKA_CONF_FILE_NAME).withFallback(ConfigFactory.load());  
356 - }  
357 -  
358 -  
359 -  
360 - public Scheduler getScheduler() {  
361 - return actorSystem.scheduler(); 339 + public ScheduledExecutorService getScheduler() {
  340 + return actorSystem.getScheduler();
362 } 341 }
363 342
364 public void persistError(TenantId tenantId, EntityId entityId, String method, Exception e) { 343 public void persistError(TenantId tenantId, EntityId entityId, String method, Exception e) {
@@ -531,7 +510,18 @@ public class ActorSystemContext { @@ -531,7 +510,18 @@ public class ActorSystemContext {
531 return Exception.class.isInstance(error) ? (Exception) error : new Exception(error); 510 return Exception.class.isInstance(error) ? (Exception) error : new Exception(error);
532 } 511 }
533 512
534 - public void tell(TbActorMsg tbActorMsg, ActorRef sender) {  
535 - appActor.tell(tbActorMsg, sender); 513 + public void tell(TbActorMsg tbActorMsg) {
  514 + appActor.tell(tbActorMsg);
  515 + }
  516 +
  517 +
  518 + public void schedulePeriodicMsgWithDelay(TbActorRef ctx, TbActorMsg msg, long delayInMs, long periodInMs) {
  519 + log.debug("Scheduling periodic msg {} every {} ms with delay {} ms", msg, periodInMs, delayInMs);
  520 + getScheduler().scheduleWithFixedDelay(() -> ctx.tell(msg), delayInMs, periodInMs, TimeUnit.MILLISECONDS);
  521 + }
  522 +
  523 + public void scheduleMsgWithDelay(TbActorRef ctx, TbActorMsg msg, long delayInMs) {
  524 + log.debug("Scheduling msg {} with delay {} ms", msg, delayInMs);
  525 + getScheduler().schedule(() -> ctx.tell(msg), delayInMs, TimeUnit.MILLISECONDS);
536 } 526 }
537 } 527 }
  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;
  17 +
  18 +import lombok.RequiredArgsConstructor;
  19 +import org.thingsboard.server.common.data.EntityType;
  20 +import org.thingsboard.server.common.data.id.EntityId;
  21 +
  22 +import java.util.function.Predicate;
  23 +
  24 +@RequiredArgsConstructor
  25 +public class TbEntityTypeActorIdPredicate implements Predicate<TbActorId> {
  26 +
  27 + private final EntityType entityType;
  28 +
  29 + @Override
  30 + public boolean test(TbActorId actorId) {
  31 + return actorId instanceof TbEntityActorId && testEntityId(((TbEntityActorId) actorId).getEntityId());
  32 + }
  33 +
  34 + protected boolean testEntityId(EntityId entityId) {
  35 + return entityId.getEntityType().equals(entityType);
  36 + }
  37 +}
@@ -15,21 +15,19 @@ @@ -15,21 +15,19 @@
15 */ 15 */
16 package org.thingsboard.server.actors.app; 16 package org.thingsboard.server.actors.app;
17 17
18 -import akka.actor.ActorRef;  
19 -import akka.actor.LocalActorRef;  
20 -import akka.actor.OneForOneStrategy;  
21 -import akka.actor.Props;  
22 -import akka.actor.SupervisorStrategy;  
23 -import akka.actor.Terminated;  
24 -import com.google.common.collect.BiMap;  
25 -import com.google.common.collect.HashBiMap; 18 +import lombok.extern.slf4j.Slf4j;
26 import org.thingsboard.server.actors.ActorSystemContext; 19 import org.thingsboard.server.actors.ActorSystemContext;
  20 +import org.thingsboard.server.actors.TbActor;
  21 +import org.thingsboard.server.actors.TbActorId;
  22 +import org.thingsboard.server.actors.TbActorRef;
  23 +import org.thingsboard.server.actors.TbEntityActorId;
27 import org.thingsboard.server.actors.service.ContextAwareActor; 24 import org.thingsboard.server.actors.service.ContextAwareActor;
28 import org.thingsboard.server.actors.service.ContextBasedCreator; 25 import org.thingsboard.server.actors.service.ContextBasedCreator;
29 import org.thingsboard.server.actors.service.DefaultActorService; 26 import org.thingsboard.server.actors.service.DefaultActorService;
30 import org.thingsboard.server.actors.tenant.TenantActor; 27 import org.thingsboard.server.actors.tenant.TenantActor;
31 import org.thingsboard.server.common.data.EntityType; 28 import org.thingsboard.server.common.data.EntityType;
32 import org.thingsboard.server.common.data.Tenant; 29 import org.thingsboard.server.common.data.Tenant;
  30 +import org.thingsboard.server.common.data.id.EntityId;
33 import org.thingsboard.server.common.data.id.TenantId; 31 import org.thingsboard.server.common.data.id.TenantId;
34 import org.thingsboard.server.common.data.page.PageDataIterable; 32 import org.thingsboard.server.common.data.page.PageDataIterable;
35 import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; 33 import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
@@ -43,38 +41,27 @@ import org.thingsboard.server.common.msg.queue.ServiceType; @@ -43,38 +41,27 @@ import org.thingsboard.server.common.msg.queue.ServiceType;
43 import org.thingsboard.server.dao.model.ModelConstants; 41 import org.thingsboard.server.dao.model.ModelConstants;
44 import org.thingsboard.server.dao.tenant.TenantService; 42 import org.thingsboard.server.dao.tenant.TenantService;
45 import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWrapper; 43 import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWrapper;
46 -import scala.concurrent.duration.Duration;  
47 44
48 import java.util.HashSet; 45 import java.util.HashSet;
49 import java.util.Optional; 46 import java.util.Optional;
50 import java.util.Set; 47 import java.util.Set;
51 48
  49 +@Slf4j
52 public class AppActor extends ContextAwareActor { 50 public class AppActor extends ContextAwareActor {
53 51
54 private static final TenantId SYSTEM_TENANT = new TenantId(ModelConstants.NULL_UUID); 52 private static final TenantId SYSTEM_TENANT = new TenantId(ModelConstants.NULL_UUID);
55 private final TenantService tenantService; 53 private final TenantService tenantService;
56 - private final BiMap<TenantId, ActorRef> tenantActors;  
57 private final Set<TenantId> deletedTenants; 54 private final Set<TenantId> deletedTenants;
58 private boolean ruleChainsInitialized; 55 private boolean ruleChainsInitialized;
59 56
60 private AppActor(ActorSystemContext systemContext) { 57 private AppActor(ActorSystemContext systemContext) {
61 super(systemContext); 58 super(systemContext);
62 this.tenantService = systemContext.getTenantService(); 59 this.tenantService = systemContext.getTenantService();
63 - this.tenantActors = HashBiMap.create();  
64 this.deletedTenants = new HashSet<>(); 60 this.deletedTenants = new HashSet<>();
65 } 61 }
66 62
67 @Override 63 @Override
68 - public SupervisorStrategy supervisorStrategy() {  
69 - return strategy;  
70 - }  
71 -  
72 - @Override  
73 - public void preStart() {  
74 - }  
75 -  
76 - @Override  
77 - protected boolean process(TbActorMsg msg) { 64 + protected boolean doProcess(TbActorMsg msg) {
78 if (!ruleChainsInitialized) { 65 if (!ruleChainsInitialized) {
79 initTenantActors(); 66 initTenantActors();
80 ruleChainsInitialized = true; 67 ruleChainsInitialized = true;
@@ -86,7 +73,7 @@ public class AppActor extends ContextAwareActor { @@ -86,7 +73,7 @@ public class AppActor extends ContextAwareActor {
86 case APP_INIT_MSG: 73 case APP_INIT_MSG:
87 break; 74 break;
88 case PARTITION_CHANGE_MSG: 75 case PARTITION_CHANGE_MSG:
89 - broadcast(msg); 76 + ctx.broadcastToChildren(msg);
90 break; 77 break;
91 case COMPONENT_LIFE_CYCLE_MSG: 78 case COMPONENT_LIFE_CYCLE_MSG:
92 onComponentLifecycleMsg((ComponentLifecycleMsg) msg); 79 onComponentLifecycleMsg((ComponentLifecycleMsg) msg);
@@ -145,19 +132,15 @@ public class AppActor extends ContextAwareActor { @@ -145,19 +132,15 @@ public class AppActor extends ContextAwareActor {
145 msg.getTbMsg().getCallback().onFailure(new RuleEngineException("Message has system tenant id!")); 132 msg.getTbMsg().getCallback().onFailure(new RuleEngineException("Message has system tenant id!"));
146 } else { 133 } else {
147 if (!deletedTenants.contains(msg.getTenantId())) { 134 if (!deletedTenants.contains(msg.getTenantId())) {
148 - getOrCreateTenantActor(msg.getTenantId()).tell(msg, self()); 135 + getOrCreateTenantActor(msg.getTenantId()).tell(msg);
149 } else { 136 } else {
150 msg.getTbMsg().getCallback().onSuccess(); 137 msg.getTbMsg().getCallback().onSuccess();
151 } 138 }
152 } 139 }
153 } 140 }
154 141
155 - protected void broadcast(Object msg) {  
156 - tenantActors.values().forEach(actorRef -> actorRef.tell(msg, ActorRef.noSender()));  
157 - }  
158 -  
159 private void onComponentLifecycleMsg(ComponentLifecycleMsg msg) { 142 private void onComponentLifecycleMsg(ComponentLifecycleMsg msg) {
160 - ActorRef target = null; 143 + TbActorRef target = null;
161 if (SYSTEM_TENANT.equals(msg.getTenantId())) { 144 if (SYSTEM_TENANT.equals(msg.getTenantId())) {
162 log.warn("Message has system tenant id: {}", msg); 145 log.warn("Message has system tenant id: {}", msg);
163 } else { 146 } else {
@@ -166,17 +149,13 @@ public class AppActor extends ContextAwareActor { @@ -166,17 +149,13 @@ public class AppActor extends ContextAwareActor {
166 log.info("[{}] Handling tenant deleted notification: {}", msg.getTenantId(), msg); 149 log.info("[{}] Handling tenant deleted notification: {}", msg.getTenantId(), msg);
167 TenantId tenantId = new TenantId(msg.getEntityId().getId()); 150 TenantId tenantId = new TenantId(msg.getEntityId().getId());
168 deletedTenants.add(tenantId); 151 deletedTenants.add(tenantId);
169 - ActorRef tenantActor = tenantActors.get(tenantId);  
170 - if (tenantActor != null) {  
171 - log.debug("[{}] Deleting tenant actor: {}", msg.getTenantId(), tenantActor);  
172 - context().stop(tenantActor);  
173 - } 152 + ctx.stop(new TbEntityActorId(tenantId));
174 } else { 153 } else {
175 target = getOrCreateTenantActor(msg.getTenantId()); 154 target = getOrCreateTenantActor(msg.getTenantId());
176 } 155 }
177 } 156 }
178 if (target != null) { 157 if (target != null) {
179 - target.tell(msg, ActorRef.noSender()); 158 + target.tell(msg);
180 } else { 159 } else {
181 log.debug("[{}] Invalid component lifecycle msg: {}", msg.getTenantId(), msg); 160 log.debug("[{}] Invalid component lifecycle msg: {}", msg.getTenantId(), msg);
182 } 161 }
@@ -184,7 +163,7 @@ public class AppActor extends ContextAwareActor { @@ -184,7 +163,7 @@ public class AppActor extends ContextAwareActor {
184 163
185 private void onToDeviceActorMsg(TenantAwareMsg msg) { 164 private void onToDeviceActorMsg(TenantAwareMsg msg) {
186 if (!deletedTenants.contains(msg.getTenantId())) { 165 if (!deletedTenants.contains(msg.getTenantId())) {
187 - getOrCreateTenantActor(msg.getTenantId()).tell(msg, ActorRef.noSender()); 166 + getOrCreateTenantActor(msg.getTenantId()).tell(msg);
188 } else { 167 } else {
189 if (msg instanceof TransportToDeviceActorMsgWrapper) { 168 if (msg instanceof TransportToDeviceActorMsgWrapper) {
190 ((TransportToDeviceActorMsgWrapper) msg).getCallback().onSuccess(); 169 ((TransportToDeviceActorMsgWrapper) msg).getCallback().onSuccess();
@@ -192,49 +171,27 @@ public class AppActor extends ContextAwareActor { @@ -192,49 +171,27 @@ public class AppActor extends ContextAwareActor {
192 } 171 }
193 } 172 }
194 173
195 - private ActorRef getOrCreateTenantActor(TenantId tenantId) {  
196 - return tenantActors.computeIfAbsent(tenantId, k -> {  
197 - log.info("[{}] Creating tenant actor.", tenantId);  
198 - ActorRef tenantActor = context().actorOf(Props.create(new TenantActor.ActorCreator(systemContext, tenantId))  
199 - .withDispatcher(DefaultActorService.CORE_DISPATCHER_NAME), tenantId.toString());  
200 - context().watch(tenantActor);  
201 - log.info("[{}] Created tenant actor: {}.", tenantId, tenantActor);  
202 - return tenantActor;  
203 - });  
204 - }  
205 -  
206 - @Override  
207 - protected void processTermination(Terminated message) {  
208 - ActorRef terminated = message.actor();  
209 - if (terminated instanceof LocalActorRef) {  
210 - boolean removed = tenantActors.inverse().remove(terminated) != null;  
211 - if (removed) {  
212 - log.debug("[{}] Removed actor:", terminated);  
213 - }  
214 - } else {  
215 - throw new IllegalStateException("Remote actors are not supported!");  
216 - } 174 + private TbActorRef getOrCreateTenantActor(TenantId tenantId) {
  175 + return ctx.getOrCreateChildActor(new TbEntityActorId(tenantId),
  176 + () -> DefaultActorService.TENANT_DISPATCHER_NAME,
  177 + () -> new TenantActor.ActorCreator(systemContext, tenantId));
217 } 178 }
218 179
219 - public static class ActorCreator extends ContextBasedCreator<AppActor> {  
220 - private static final long serialVersionUID = 1L; 180 + public static class ActorCreator extends ContextBasedCreator {
221 181
222 public ActorCreator(ActorSystemContext context) { 182 public ActorCreator(ActorSystemContext context) {
223 super(context); 183 super(context);
224 } 184 }
225 185
226 @Override 186 @Override
227 - public AppActor create() { 187 + public TbActorId createActorId() {
  188 + return new TbEntityActorId(new TenantId(EntityId.NULL_UUID));
  189 + }
  190 +
  191 + @Override
  192 + public TbActor createActor() {
228 return new AppActor(context); 193 return new AppActor(context);
229 } 194 }
230 } 195 }
231 196
232 - private final SupervisorStrategy strategy = new OneForOneStrategy(3, Duration.create("1 minute"), t -> {  
233 - log.warn("Unknown failure", t);  
234 - if (t instanceof RuntimeException) {  
235 - return SupervisorStrategy.restart();  
236 - } else {  
237 - return SupervisorStrategy.stop();  
238 - }  
239 - });  
240 } 197 }
@@ -15,9 +15,11 @@ @@ -15,9 +15,11 @@
15 */ 15 */
16 package org.thingsboard.server.actors.device; 16 package org.thingsboard.server.actors.device;
17 17
  18 +import lombok.extern.slf4j.Slf4j;
18 import org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg; 19 import org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg;
19 import org.thingsboard.rule.engine.api.msg.DeviceNameOrTypeUpdateMsg; 20 import org.thingsboard.rule.engine.api.msg.DeviceNameOrTypeUpdateMsg;
20 import org.thingsboard.server.actors.ActorSystemContext; 21 import org.thingsboard.server.actors.ActorSystemContext;
  22 +import org.thingsboard.server.actors.TbActorCtx;
21 import org.thingsboard.server.actors.service.ContextAwareActor; 23 import org.thingsboard.server.actors.service.ContextAwareActor;
22 import org.thingsboard.server.common.data.id.DeviceId; 24 import org.thingsboard.server.common.data.id.DeviceId;
23 import org.thingsboard.server.common.data.id.TenantId; 25 import org.thingsboard.server.common.data.id.TenantId;
@@ -26,6 +28,7 @@ import org.thingsboard.server.common.msg.timeout.DeviceActorServerSideRpcTimeout @@ -26,6 +28,7 @@ import org.thingsboard.server.common.msg.timeout.DeviceActorServerSideRpcTimeout
26 import org.thingsboard.server.service.rpc.ToDeviceRpcRequestActorMsg; 28 import org.thingsboard.server.service.rpc.ToDeviceRpcRequestActorMsg;
27 import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWrapper; 29 import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWrapper;
28 30
  31 +@Slf4j
29 public class DeviceActor extends ContextAwareActor { 32 public class DeviceActor extends ContextAwareActor {
30 33
31 private final DeviceActorMessageProcessor processor; 34 private final DeviceActorMessageProcessor processor;
@@ -36,10 +39,11 @@ public class DeviceActor extends ContextAwareActor { @@ -36,10 +39,11 @@ public class DeviceActor extends ContextAwareActor {
36 } 39 }
37 40
38 @Override 41 @Override
39 - public void preStart() { 42 + public void init(TbActorCtx ctx) {
  43 + super.init(ctx);
40 log.debug("[{}][{}] Starting device actor.", processor.tenantId, processor.deviceId); 44 log.debug("[{}][{}] Starting device actor.", processor.tenantId, processor.deviceId);
41 try { 45 try {
42 - processor.initSessionTimeout(context()); 46 + processor.initSessionTimeout(ctx);
43 log.debug("[{}][{}] Device actor started.", processor.tenantId, processor.deviceId); 47 log.debug("[{}][{}] Device actor started.", processor.tenantId, processor.deviceId);
44 } catch (Exception e) { 48 } catch (Exception e) {
45 log.warn("[{}][{}] Unknown failure", processor.tenantId, processor.deviceId, e); 49 log.warn("[{}][{}] Unknown failure", processor.tenantId, processor.deviceId, e);
@@ -47,18 +51,13 @@ public class DeviceActor extends ContextAwareActor { @@ -47,18 +51,13 @@ public class DeviceActor extends ContextAwareActor {
47 } 51 }
48 52
49 @Override 53 @Override
50 - public void postStop() {  
51 -  
52 - }  
53 -  
54 - @Override  
55 - protected boolean process(TbActorMsg msg) { 54 + protected boolean doProcess(TbActorMsg msg) {
56 switch (msg.getMsgType()) { 55 switch (msg.getMsgType()) {
57 case TRANSPORT_TO_DEVICE_ACTOR_MSG: 56 case TRANSPORT_TO_DEVICE_ACTOR_MSG:
58 - processor.process(context(), (TransportToDeviceActorMsgWrapper) msg); 57 + processor.process(ctx, (TransportToDeviceActorMsgWrapper) msg);
59 break; 58 break;
60 case DEVICE_ATTRIBUTES_UPDATE_TO_DEVICE_ACTOR_MSG: 59 case DEVICE_ATTRIBUTES_UPDATE_TO_DEVICE_ACTOR_MSG:
61 - processor.processAttributesUpdate(context(), (DeviceAttributesEventNotificationMsg) msg); 60 + processor.processAttributesUpdate(ctx, (DeviceAttributesEventNotificationMsg) msg);
62 break; 61 break;
63 case DEVICE_CREDENTIALS_UPDATE_TO_DEVICE_ACTOR_MSG: 62 case DEVICE_CREDENTIALS_UPDATE_TO_DEVICE_ACTOR_MSG:
64 processor.processCredentialsUpdate(); 63 processor.processCredentialsUpdate();
@@ -67,10 +66,10 @@ public class DeviceActor extends ContextAwareActor { @@ -67,10 +66,10 @@ public class DeviceActor extends ContextAwareActor {
67 processor.processNameOrTypeUpdate((DeviceNameOrTypeUpdateMsg) msg); 66 processor.processNameOrTypeUpdate((DeviceNameOrTypeUpdateMsg) msg);
68 break; 67 break;
69 case DEVICE_RPC_REQUEST_TO_DEVICE_ACTOR_MSG: 68 case DEVICE_RPC_REQUEST_TO_DEVICE_ACTOR_MSG:
70 - processor.processRpcRequest(context(), (ToDeviceRpcRequestActorMsg) msg); 69 + processor.processRpcRequest(ctx, (ToDeviceRpcRequestActorMsg) msg);
71 break; 70 break;
72 case DEVICE_ACTOR_SERVER_SIDE_RPC_TIMEOUT_MSG: 71 case DEVICE_ACTOR_SERVER_SIDE_RPC_TIMEOUT_MSG:
73 - processor.processServerSideRpcTimeout(context(), (DeviceActorServerSideRpcTimeoutMsg) msg); 72 + processor.processServerSideRpcTimeout(ctx, (DeviceActorServerSideRpcTimeoutMsg) msg);
74 break; 73 break;
75 case SESSION_TIMEOUT_MSG: 74 case SESSION_TIMEOUT_MSG:
76 processor.checkSessionsTimeout(); 75 processor.checkSessionsTimeout();
@@ -16,12 +16,14 @@ @@ -16,12 +16,14 @@
16 package org.thingsboard.server.actors.device; 16 package org.thingsboard.server.actors.device;
17 17
18 import org.thingsboard.server.actors.ActorSystemContext; 18 import org.thingsboard.server.actors.ActorSystemContext;
  19 +import org.thingsboard.server.actors.TbActor;
  20 +import org.thingsboard.server.actors.TbActorId;
  21 +import org.thingsboard.server.actors.TbEntityActorId;
19 import org.thingsboard.server.actors.service.ContextBasedCreator; 22 import org.thingsboard.server.actors.service.ContextBasedCreator;
20 import org.thingsboard.server.common.data.id.DeviceId; 23 import org.thingsboard.server.common.data.id.DeviceId;
21 import org.thingsboard.server.common.data.id.TenantId; 24 import org.thingsboard.server.common.data.id.TenantId;
22 25
23 -public class DeviceActorCreator extends ContextBasedCreator<DeviceActor> {  
24 - private static final long serialVersionUID = 1L; 26 +public class DeviceActorCreator extends ContextBasedCreator {
25 27
26 private final TenantId tenantId; 28 private final TenantId tenantId;
27 private final DeviceId deviceId; 29 private final DeviceId deviceId;
@@ -33,7 +35,13 @@ public class DeviceActorCreator extends ContextBasedCreator<DeviceActor> { @@ -33,7 +35,13 @@ public class DeviceActorCreator extends ContextBasedCreator<DeviceActor> {
33 } 35 }
34 36
35 @Override 37 @Override
36 - public DeviceActor create() { 38 + public TbActorId createActorId() {
  39 + return new TbEntityActorId(deviceId);
  40 + }
  41 +
  42 + @Override
  43 + public TbActor createActor() {
37 return new DeviceActor(context, tenantId, deviceId); 44 return new DeviceActor(context, tenantId, deviceId);
38 } 45 }
  46 +
39 } 47 }
@@ -15,7 +15,6 @@ @@ -15,7 +15,6 @@
15 */ 15 */
16 package org.thingsboard.server.actors.device; 16 package org.thingsboard.server.actors.device;
17 17
18 -import akka.actor.ActorContext;  
19 import com.google.common.util.concurrent.FutureCallback; 18 import com.google.common.util.concurrent.FutureCallback;
20 import com.google.common.util.concurrent.Futures; 19 import com.google.common.util.concurrent.Futures;
21 import com.google.common.util.concurrent.ListenableFuture; 20 import com.google.common.util.concurrent.ListenableFuture;
@@ -27,6 +26,7 @@ import org.thingsboard.rule.engine.api.RpcError; @@ -27,6 +26,7 @@ import org.thingsboard.rule.engine.api.RpcError;
27 import org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg; 26 import org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg;
28 import org.thingsboard.rule.engine.api.msg.DeviceNameOrTypeUpdateMsg; 27 import org.thingsboard.rule.engine.api.msg.DeviceNameOrTypeUpdateMsg;
29 import org.thingsboard.server.actors.ActorSystemContext; 28 import org.thingsboard.server.actors.ActorSystemContext;
  29 +import org.thingsboard.server.actors.TbActorCtx;
30 import org.thingsboard.server.actors.shared.AbstractContextAwareMsgProcessor; 30 import org.thingsboard.server.actors.shared.AbstractContextAwareMsgProcessor;
31 import org.thingsboard.server.common.data.Device; 31 import org.thingsboard.server.common.data.Device;
32 import org.thingsboard.server.common.data.id.DeviceId; 32 import org.thingsboard.server.common.data.id.DeviceId;
@@ -127,7 +127,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { @@ -127,7 +127,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
127 } 127 }
128 } 128 }
129 129
130 - void processRpcRequest(ActorContext context, ToDeviceRpcRequestActorMsg msg) { 130 + void processRpcRequest(TbActorCtx context, ToDeviceRpcRequestActorMsg msg) {
131 ToDeviceRpcRequest request = msg.getMsg(); 131 ToDeviceRpcRequest request = msg.getMsg();
132 ToDeviceRpcRequestBody body = request.getBody(); 132 ToDeviceRpcRequestBody body = request.getBody();
133 ToDeviceRpcRequestMsg rpcRequest = ToDeviceRpcRequestMsg.newBuilder().setRequestId( 133 ToDeviceRpcRequestMsg rpcRequest = ToDeviceRpcRequestMsg.newBuilder().setRequestId(
@@ -162,13 +162,13 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { @@ -162,13 +162,13 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
162 } 162 }
163 } 163 }
164 164
165 - private void registerPendingRpcRequest(ActorContext context, ToDeviceRpcRequestActorMsg msg, boolean sent, ToDeviceRpcRequestMsg rpcRequest, long timeout) { 165 + private void registerPendingRpcRequest(TbActorCtx context, ToDeviceRpcRequestActorMsg msg, boolean sent, ToDeviceRpcRequestMsg rpcRequest, long timeout) {
166 toDeviceRpcPendingMap.put(rpcRequest.getRequestId(), new ToDeviceRpcRequestMetadata(msg, sent)); 166 toDeviceRpcPendingMap.put(rpcRequest.getRequestId(), new ToDeviceRpcRequestMetadata(msg, sent));
167 DeviceActorServerSideRpcTimeoutMsg timeoutMsg = new DeviceActorServerSideRpcTimeoutMsg(rpcRequest.getRequestId(), timeout); 167 DeviceActorServerSideRpcTimeoutMsg timeoutMsg = new DeviceActorServerSideRpcTimeoutMsg(rpcRequest.getRequestId(), timeout);
168 scheduleMsgWithDelay(context, timeoutMsg, timeoutMsg.getTimeout()); 168 scheduleMsgWithDelay(context, timeoutMsg, timeoutMsg.getTimeout());
169 } 169 }
170 170
171 - void processServerSideRpcTimeout(ActorContext context, DeviceActorServerSideRpcTimeoutMsg msg) { 171 + void processServerSideRpcTimeout(TbActorCtx context, DeviceActorServerSideRpcTimeoutMsg msg) {
172 ToDeviceRpcRequestMetadata requestMd = toDeviceRpcPendingMap.remove(msg.getId()); 172 ToDeviceRpcRequestMetadata requestMd = toDeviceRpcPendingMap.remove(msg.getId());
173 if (requestMd != null) { 173 if (requestMd != null) {
174 log.debug("[{}] RPC request [{}] timeout detected!", deviceId, msg.getId()); 174 log.debug("[{}] RPC request [{}] timeout detected!", deviceId, msg.getId());
@@ -177,7 +177,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { @@ -177,7 +177,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
177 } 177 }
178 } 178 }
179 179
180 - private void sendPendingRequests(ActorContext context, UUID sessionId, SessionInfoProto sessionInfo) { 180 + private void sendPendingRequests(TbActorCtx context, UUID sessionId, SessionInfoProto sessionInfo) {
181 SessionType sessionType = getSessionType(sessionId); 181 SessionType sessionType = getSessionType(sessionId);
182 if (!toDeviceRpcPendingMap.isEmpty()) { 182 if (!toDeviceRpcPendingMap.isEmpty()) {
183 log.debug("[{}] Pushing {} pending RPC messages to new async session [{}]", deviceId, toDeviceRpcPendingMap.size(), sessionId); 183 log.debug("[{}] Pushing {} pending RPC messages to new async session [{}]", deviceId, toDeviceRpcPendingMap.size(), sessionId);
@@ -198,7 +198,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { @@ -198,7 +198,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
198 sentOneWayIds.forEach(toDeviceRpcPendingMap::remove); 198 sentOneWayIds.forEach(toDeviceRpcPendingMap::remove);
199 } 199 }
200 200
201 - private Consumer<Map.Entry<Integer, ToDeviceRpcRequestMetadata>> processPendingRpc(ActorContext context, UUID sessionId, String nodeId, Set<Integer> sentOneWayIds) { 201 + private Consumer<Map.Entry<Integer, ToDeviceRpcRequestMetadata>> processPendingRpc(TbActorCtx context, UUID sessionId, String nodeId, Set<Integer> sentOneWayIds) {
202 return entry -> { 202 return entry -> {
203 ToDeviceRpcRequest request = entry.getValue().getMsg().getMsg(); 203 ToDeviceRpcRequest request = entry.getValue().getMsg().getMsg();
204 ToDeviceRpcRequestBody body = request.getBody(); 204 ToDeviceRpcRequestBody body = request.getBody();
@@ -212,7 +212,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { @@ -212,7 +212,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
212 }; 212 };
213 } 213 }
214 214
215 - void process(ActorContext context, TransportToDeviceActorMsgWrapper wrapper) { 215 + void process(TbActorCtx context, TransportToDeviceActorMsgWrapper wrapper) {
216 TransportToDeviceActorMsg msg = wrapper.getMsg(); 216 TransportToDeviceActorMsg msg = wrapper.getMsg();
217 TbCallback callback = wrapper.getCallback(); 217 TbCallback callback = wrapper.getCallback();
218 if (msg.hasSessionEvent()) { 218 if (msg.hasSessionEvent()) {
@@ -239,7 +239,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { @@ -239,7 +239,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
239 callback.onSuccess(); 239 callback.onSuccess();
240 } 240 }
241 241
242 - private void handleClaimDeviceMsg(ActorContext context, SessionInfoProto sessionInfo, TransportProtos.ClaimDeviceMsg msg) { 242 + private void handleClaimDeviceMsg(TbActorCtx context, SessionInfoProto sessionInfo, TransportProtos.ClaimDeviceMsg msg) {
243 DeviceId deviceId = new DeviceId(new UUID(msg.getDeviceIdMSB(), msg.getDeviceIdLSB())); 243 DeviceId deviceId = new DeviceId(new UUID(msg.getDeviceIdMSB(), msg.getDeviceIdLSB()));
244 systemContext.getClaimDevicesService().registerClaimingInfo(tenantId, deviceId, msg.getSecretKey(), msg.getDurationMs()); 244 systemContext.getClaimDevicesService().registerClaimingInfo(tenantId, deviceId, msg.getSecretKey(), msg.getDurationMs());
245 } 245 }
@@ -252,7 +252,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { @@ -252,7 +252,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
252 systemContext.getDeviceStateService().onDeviceDisconnect(deviceId); 252 systemContext.getDeviceStateService().onDeviceDisconnect(deviceId);
253 } 253 }
254 254
255 - private void handleGetAttributesRequest(ActorContext context, SessionInfoProto sessionInfo, GetAttributeRequestMsg request) { 255 + private void handleGetAttributesRequest(TbActorCtx context, SessionInfoProto sessionInfo, GetAttributeRequestMsg request) {
256 int requestId = request.getRequestId(); 256 int requestId = request.getRequestId();
257 Futures.addCallback(getAttributesKvEntries(request), new FutureCallback<List<List<AttributeKvEntry>>>() { 257 Futures.addCallback(getAttributesKvEntries(request), new FutureCallback<List<List<AttributeKvEntry>>>() {
258 @Override 258 @Override
@@ -310,7 +310,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { @@ -310,7 +310,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
310 return sessions.containsKey(sessionId) ? SessionType.ASYNC : SessionType.SYNC; 310 return sessions.containsKey(sessionId) ? SessionType.ASYNC : SessionType.SYNC;
311 } 311 }
312 312
313 - void processAttributesUpdate(ActorContext context, DeviceAttributesEventNotificationMsg msg) { 313 + void processAttributesUpdate(TbActorCtx context, DeviceAttributesEventNotificationMsg msg) {
314 if (attributeSubscriptions.size() > 0) { 314 if (attributeSubscriptions.size() > 0) {
315 boolean hasNotificationData = false; 315 boolean hasNotificationData = false;
316 AttributeUpdateNotificationMsg.Builder notification = AttributeUpdateNotificationMsg.newBuilder(); 316 AttributeUpdateNotificationMsg.Builder notification = AttributeUpdateNotificationMsg.newBuilder();
@@ -349,7 +349,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { @@ -349,7 +349,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
349 } 349 }
350 } 350 }
351 351
352 - private void processRpcResponses(ActorContext context, SessionInfoProto sessionInfo, ToDeviceRpcResponseMsg responseMsg) { 352 + private void processRpcResponses(TbActorCtx context, SessionInfoProto sessionInfo, ToDeviceRpcResponseMsg responseMsg) {
353 UUID sessionId = getSessionId(sessionInfo); 353 UUID sessionId = getSessionId(sessionInfo);
354 log.debug("[{}] Processing rpc command response [{}]", deviceId, sessionId); 354 log.debug("[{}] Processing rpc command response [{}]", deviceId, sessionId);
355 ToDeviceRpcRequestMetadata requestMd = toDeviceRpcPendingMap.remove(responseMsg.getRequestId()); 355 ToDeviceRpcRequestMetadata requestMd = toDeviceRpcPendingMap.remove(responseMsg.getRequestId());
@@ -362,7 +362,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { @@ -362,7 +362,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
362 } 362 }
363 } 363 }
364 364
365 - private void processSubscriptionCommands(ActorContext context, SessionInfoProto sessionInfo, SubscribeToAttributeUpdatesMsg subscribeCmd) { 365 + private void processSubscriptionCommands(TbActorCtx context, SessionInfoProto sessionInfo, SubscribeToAttributeUpdatesMsg subscribeCmd) {
366 UUID sessionId = getSessionId(sessionInfo); 366 UUID sessionId = getSessionId(sessionInfo);
367 if (subscribeCmd.getUnsubscribe()) { 367 if (subscribeCmd.getUnsubscribe()) {
368 log.debug("[{}] Canceling attributes subscription for session [{}]", deviceId, sessionId); 368 log.debug("[{}] Canceling attributes subscription for session [{}]", deviceId, sessionId);
@@ -383,7 +383,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { @@ -383,7 +383,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
383 return new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB()); 383 return new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB());
384 } 384 }
385 385
386 - private void processSubscriptionCommands(ActorContext context, SessionInfoProto sessionInfo, SubscribeToRPCMsg subscribeCmd) { 386 + private void processSubscriptionCommands(TbActorCtx context, SessionInfoProto sessionInfo, SubscribeToRPCMsg subscribeCmd) {
387 UUID sessionId = getSessionId(sessionInfo); 387 UUID sessionId = getSessionId(sessionInfo);
388 if (subscribeCmd.getUnsubscribe()) { 388 if (subscribeCmd.getUnsubscribe()) {
389 log.debug("[{}] Canceling rpc subscription for session [{}]", deviceId, sessionId); 389 log.debug("[{}] Canceling rpc subscription for session [{}]", deviceId, sessionId);
@@ -433,7 +433,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { @@ -433,7 +433,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
433 } 433 }
434 } 434 }
435 435
436 - private void handleSessionActivity(ActorContext context, SessionInfoProto sessionInfoProto, SubscriptionInfoProto subscriptionInfo) { 436 + private void handleSessionActivity(TbActorCtx context, SessionInfoProto sessionInfoProto, SubscriptionInfoProto subscriptionInfo) {
437 UUID sessionId = getSessionId(sessionInfoProto); 437 UUID sessionId = getSessionId(sessionInfoProto);
438 SessionInfoMetaData sessionMD = sessions.computeIfAbsent(sessionId, 438 SessionInfoMetaData sessionMD = sessions.computeIfAbsent(sessionId,
439 id -> new SessionInfoMetaData(new SessionInfo(SessionType.ASYNC, sessionInfoProto.getNodeId()), 0L)); 439 id -> new SessionInfoMetaData(new SessionInfo(SessionType.ASYNC, sessionInfoProto.getNodeId()), 0L));
@@ -612,8 +612,8 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { @@ -612,8 +612,8 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
612 .addAllSessions(sessionsList).build().toByteArray()); 612 .addAllSessions(sessionsList).build().toByteArray());
613 } 613 }
614 614
615 - void initSessionTimeout(ActorContext context) {  
616 - schedulePeriodicMsgWithDelay(context, SessionTimeoutCheckMsg.instance(), systemContext.getSessionInactivityTimeout(), systemContext.getSessionInactivityTimeout()); 615 + void initSessionTimeout(TbActorCtx ctx) {
  616 + schedulePeriodicMsgWithDelay(ctx, SessionTimeoutCheckMsg.instance(), systemContext.getSessionInactivityTimeout(), systemContext.getSessionInactivityTimeout());
617 } 617 }
618 618
619 void checkSessionsTimeout() { 619 void checkSessionsTimeout() {
@@ -15,7 +15,6 @@ @@ -15,7 +15,6 @@
15 */ 15 */
16 package org.thingsboard.server.actors.ruleChain; 16 package org.thingsboard.server.actors.ruleChain;
17 17
18 -import akka.actor.ActorRef;  
19 import com.datastax.driver.core.ResultSetFuture; 18 import com.datastax.driver.core.ResultSetFuture;
20 import com.fasterxml.jackson.core.JsonProcessingException; 19 import com.fasterxml.jackson.core.JsonProcessingException;
21 import com.fasterxml.jackson.databind.ObjectMapper; 20 import com.fasterxml.jackson.databind.ObjectMapper;
@@ -30,6 +29,7 @@ import org.thingsboard.rule.engine.api.ScriptEngine; @@ -30,6 +29,7 @@ import org.thingsboard.rule.engine.api.ScriptEngine;
30 import org.thingsboard.rule.engine.api.TbContext; 29 import org.thingsboard.rule.engine.api.TbContext;
31 import org.thingsboard.rule.engine.api.TbRelationTypes; 30 import org.thingsboard.rule.engine.api.TbRelationTypes;
32 import org.thingsboard.server.actors.ActorSystemContext; 31 import org.thingsboard.server.actors.ActorSystemContext;
  32 +import org.thingsboard.server.actors.TbActorRef;
33 import org.thingsboard.server.common.data.Customer; 33 import org.thingsboard.server.common.data.Customer;
34 import org.thingsboard.server.common.data.DataConstants; 34 import org.thingsboard.server.common.data.DataConstants;
35 import org.thingsboard.server.common.data.Device; 35 import org.thingsboard.server.common.data.Device;
@@ -40,6 +40,7 @@ import org.thingsboard.server.common.data.id.RuleChainId; @@ -40,6 +40,7 @@ import org.thingsboard.server.common.data.id.RuleChainId;
40 import org.thingsboard.server.common.data.id.RuleNodeId; 40 import org.thingsboard.server.common.data.id.RuleNodeId;
41 import org.thingsboard.server.common.data.id.TenantId; 41 import org.thingsboard.server.common.data.id.TenantId;
42 import org.thingsboard.server.common.data.rule.RuleNode; 42 import org.thingsboard.server.common.data.rule.RuleNode;
  43 +import org.thingsboard.server.common.msg.TbActorMsg;
43 import org.thingsboard.server.common.msg.TbMsg; 44 import org.thingsboard.server.common.msg.TbMsg;
44 import org.thingsboard.server.common.msg.TbMsgMetaData; 45 import org.thingsboard.server.common.msg.TbMsgMetaData;
45 import org.thingsboard.server.common.msg.queue.ServiceType; 46 import org.thingsboard.server.common.msg.queue.ServiceType;
@@ -62,7 +63,6 @@ import org.thingsboard.server.gen.transport.TransportProtos; @@ -62,7 +63,6 @@ import org.thingsboard.server.gen.transport.TransportProtos;
62 import org.thingsboard.server.queue.TbQueueCallback; 63 import org.thingsboard.server.queue.TbQueueCallback;
63 import org.thingsboard.server.queue.TbQueueMsgMetadata; 64 import org.thingsboard.server.queue.TbQueueMsgMetadata;
64 import org.thingsboard.server.service.script.RuleNodeJsScriptEngine; 65 import org.thingsboard.server.service.script.RuleNodeJsScriptEngine;
65 -import scala.concurrent.duration.Duration;  
66 66
67 import java.util.Collections; 67 import java.util.Collections;
68 import java.util.Set; 68 import java.util.Set;
@@ -104,7 +104,7 @@ class DefaultTbContext implements TbContext { @@ -104,7 +104,7 @@ class DefaultTbContext implements TbContext {
104 if (nodeCtx.getSelf().isDebugMode()) { 104 if (nodeCtx.getSelf().isDebugMode()) {
105 relationTypes.forEach(relationType -> mainCtx.persistDebugOutput(nodeCtx.getTenantId(), nodeCtx.getSelf().getId(), msg, relationType, th)); 105 relationTypes.forEach(relationType -> mainCtx.persistDebugOutput(nodeCtx.getTenantId(), nodeCtx.getSelf().getId(), msg, relationType, th));
106 } 106 }
107 - nodeCtx.getChainActor().tell(new RuleNodeToRuleChainTellNextMsg(nodeCtx.getSelf().getId(), relationTypes, msg, th != null ? th.getMessage() : null), nodeCtx.getSelfActor()); 107 + nodeCtx.getChainActor().tell(new RuleNodeToRuleChainTellNextMsg(nodeCtx.getSelf().getId(), relationTypes, msg, th != null ? th.getMessage() : null));
108 } 108 }
109 109
110 @Override 110 @Override
@@ -130,7 +130,7 @@ class DefaultTbContext implements TbContext { @@ -130,7 +130,7 @@ class DefaultTbContext implements TbContext {
130 .setTenantIdMSB(getTenantId().getId().getMostSignificantBits()) 130 .setTenantIdMSB(getTenantId().getId().getMostSignificantBits())
131 .setTenantIdLSB(getTenantId().getId().getLeastSignificantBits()) 131 .setTenantIdLSB(getTenantId().getId().getLeastSignificantBits())
132 .setTbMsg(TbMsg.toByteString(tbMsg)).build(); 132 .setTbMsg(TbMsg.toByteString(tbMsg)).build();
133 - mainCtx.getClusterService().pushMsgToRuleEngine(tpi, tbMsg.getId(), msg, new SimpleTbQueueCallback(onSuccess, onFailure)); 133 + mainCtx.getClusterService().pushMsgToRuleEngine(tpi, tbMsg.getId(), msg, new SimpleTbQueueCallback(onSuccess, onFailure));
134 } 134 }
135 135
136 @Override 136 @Override
@@ -187,7 +187,7 @@ class DefaultTbContext implements TbContext { @@ -187,7 +187,7 @@ class DefaultTbContext implements TbContext {
187 if (failureMessage != null) { 187 if (failureMessage != null) {
188 msg.setFailureMessage(failureMessage); 188 msg.setFailureMessage(failureMessage);
189 } 189 }
190 - mainCtx.getClusterService().pushMsgToRuleEngine(tpi, tbMsg.getId(), msg.build(), new SimpleTbQueueCallback(onSuccess, onFailure)); 190 + mainCtx.getClusterService().pushMsgToRuleEngine(tpi, tbMsg.getId(), msg.build(), new SimpleTbQueueCallback(onSuccess, onFailure));
191 } 191 }
192 192
193 @Override 193 @Override
@@ -203,8 +203,8 @@ class DefaultTbContext implements TbContext { @@ -203,8 +203,8 @@ class DefaultTbContext implements TbContext {
203 return mainCtx.resolve(ServiceType.TB_RULE_ENGINE, getTenantId(), entityId).isMyPartition(); 203 return mainCtx.resolve(ServiceType.TB_RULE_ENGINE, getTenantId(), entityId).isMyPartition();
204 } 204 }
205 205
206 - private void scheduleMsgWithDelay(Object msg, long delayInMs, ActorRef target) {  
207 - mainCtx.getScheduler().scheduleOnce(Duration.create(delayInMs, TimeUnit.MILLISECONDS), target, msg, mainCtx.getActorSystem().dispatcher(), nodeCtx.getSelfActor()); 206 + private void scheduleMsgWithDelay(TbActorMsg msg, long delayInMs, TbActorRef target) {
  207 + mainCtx.scheduleMsgWithDelay(target, msg, delayInMs);
208 } 208 }
209 209
210 @Override 210 @Override
@@ -213,7 +213,7 @@ class DefaultTbContext implements TbContext { @@ -213,7 +213,7 @@ class DefaultTbContext implements TbContext {
213 mainCtx.persistDebugOutput(nodeCtx.getTenantId(), nodeCtx.getSelf().getId(), msg, TbRelationTypes.FAILURE, th); 213 mainCtx.persistDebugOutput(nodeCtx.getTenantId(), nodeCtx.getSelf().getId(), msg, TbRelationTypes.FAILURE, th);
214 } 214 }
215 nodeCtx.getChainActor().tell(new RuleNodeToRuleChainTellNextMsg(nodeCtx.getSelf().getId(), Collections.singleton(TbRelationTypes.FAILURE), 215 nodeCtx.getChainActor().tell(new RuleNodeToRuleChainTellNextMsg(nodeCtx.getSelf().getId(), Collections.singleton(TbRelationTypes.FAILURE),
216 - msg, th != null ? th.getMessage() : null), nodeCtx.getSelfActor()); 216 + msg, th != null ? th.getMessage() : null));
217 } 217 }
218 218
219 public void updateSelf(RuleNode self) { 219 public void updateSelf(RuleNode self) {
@@ -15,9 +15,11 @@ @@ -15,9 +15,11 @@
15 */ 15 */
16 package org.thingsboard.server.actors.ruleChain; 16 package org.thingsboard.server.actors.ruleChain;
17 17
18 -import akka.actor.OneForOneStrategy;  
19 -import akka.actor.SupervisorStrategy;  
20 import org.thingsboard.server.actors.ActorSystemContext; 18 import org.thingsboard.server.actors.ActorSystemContext;
  19 +import org.thingsboard.server.actors.TbActor;
  20 +import org.thingsboard.server.actors.TbActorCtx;
  21 +import org.thingsboard.server.actors.TbActorId;
  22 +import org.thingsboard.server.actors.TbEntityActorId;
21 import org.thingsboard.server.actors.service.ComponentActor; 23 import org.thingsboard.server.actors.service.ComponentActor;
22 import org.thingsboard.server.actors.service.ContextBasedCreator; 24 import org.thingsboard.server.actors.service.ContextBasedCreator;
23 import org.thingsboard.server.common.data.id.RuleChainId; 25 import org.thingsboard.server.common.data.id.RuleChainId;
@@ -27,18 +29,24 @@ import org.thingsboard.server.common.msg.TbActorMsg; @@ -27,18 +29,24 @@ import org.thingsboard.server.common.msg.TbActorMsg;
27 import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; 29 import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg;
28 import org.thingsboard.server.common.msg.queue.PartitionChangeMsg; 30 import org.thingsboard.server.common.msg.queue.PartitionChangeMsg;
29 import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg; 31 import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg;
30 -import scala.concurrent.duration.Duration;  
31 32
32 public class RuleChainActor extends ComponentActor<RuleChainId, RuleChainActorMessageProcessor> { 33 public class RuleChainActor extends ComponentActor<RuleChainId, RuleChainActorMessageProcessor> {
33 34
  35 + private final RuleChain ruleChain;
  36 +
34 private RuleChainActor(ActorSystemContext systemContext, TenantId tenantId, RuleChain ruleChain) { 37 private RuleChainActor(ActorSystemContext systemContext, TenantId tenantId, RuleChain ruleChain) {
35 super(systemContext, tenantId, ruleChain.getId()); 38 super(systemContext, tenantId, ruleChain.getId());
36 - setProcessor(new RuleChainActorMessageProcessor(tenantId, ruleChain, systemContext,  
37 - context().parent(), context().self())); 39 + this.ruleChain = ruleChain;
38 } 40 }
39 41
40 @Override 42 @Override
41 - protected boolean process(TbActorMsg msg) { 43 + protected RuleChainActorMessageProcessor createProcessor(TbActorCtx ctx) {
  44 + return new RuleChainActorMessageProcessor(tenantId, ruleChain, systemContext,
  45 + ctx.getParentRef(), ctx);
  46 + }
  47 +
  48 + @Override
  49 + protected boolean doProcess(TbActorMsg msg) {
42 switch (msg.getMsgType()) { 50 switch (msg.getMsgType()) {
43 case COMPONENT_LIFE_CYCLE_MSG: 51 case COMPONENT_LIFE_CYCLE_MSG:
44 onComponentLifecycleMsg((ComponentLifecycleMsg) msg); 52 onComponentLifecycleMsg((ComponentLifecycleMsg) msg);
@@ -64,7 +72,7 @@ public class RuleChainActor extends ComponentActor<RuleChainId, RuleChainActorMe @@ -64,7 +72,7 @@ public class RuleChainActor extends ComponentActor<RuleChainId, RuleChainActorMe
64 return true; 72 return true;
65 } 73 }
66 74
67 - public static class ActorCreator extends ContextBasedCreator<RuleChainActor> { 75 + public static class ActorCreator extends ContextBasedCreator {
68 private static final long serialVersionUID = 1L; 76 private static final long serialVersionUID = 1L;
69 77
70 private final TenantId tenantId; 78 private final TenantId tenantId;
@@ -77,7 +85,12 @@ public class RuleChainActor extends ComponentActor<RuleChainId, RuleChainActorMe @@ -77,7 +85,12 @@ public class RuleChainActor extends ComponentActor<RuleChainId, RuleChainActorMe
77 } 85 }
78 86
79 @Override 87 @Override
80 - public RuleChainActor create() { 88 + public TbActorId createActorId() {
  89 + return new TbEntityActorId(ruleChain.getId());
  90 + }
  91 +
  92 + @Override
  93 + public TbActor createActor() {
81 return new RuleChainActor(context, tenantId, ruleChain); 94 return new RuleChainActor(context, tenantId, ruleChain);
82 } 95 }
83 } 96 }
@@ -87,13 +100,4 @@ public class RuleChainActor extends ComponentActor<RuleChainId, RuleChainActorMe @@ -87,13 +100,4 @@ public class RuleChainActor extends ComponentActor<RuleChainId, RuleChainActorMe
87 return systemContext.getRuleChainErrorPersistFrequency(); 100 return systemContext.getRuleChainErrorPersistFrequency();
88 } 101 }
89 102
90 - @Override  
91 - public SupervisorStrategy supervisorStrategy() {  
92 - return strategy;  
93 - }  
94 -  
95 - private final SupervisorStrategy strategy = new OneForOneStrategy(3, Duration.create("1 minute"), t -> {  
96 - logAndPersist("Unknown Failure", ActorSystemContext.toException(t));  
97 - return SupervisorStrategy.resume();  
98 - });  
99 } 103 }
@@ -15,12 +15,12 @@ @@ -15,12 +15,12 @@
15 */ 15 */
16 package org.thingsboard.server.actors.ruleChain; 16 package org.thingsboard.server.actors.ruleChain;
17 17
18 -import akka.actor.ActorContext;  
19 -import akka.actor.ActorRef;  
20 -import akka.actor.Props;  
21 import lombok.extern.slf4j.Slf4j; 18 import lombok.extern.slf4j.Slf4j;
22 import org.thingsboard.rule.engine.api.TbRelationTypes; 19 import org.thingsboard.rule.engine.api.TbRelationTypes;
23 import org.thingsboard.server.actors.ActorSystemContext; 20 import org.thingsboard.server.actors.ActorSystemContext;
  21 +import org.thingsboard.server.actors.TbActorCtx;
  22 +import org.thingsboard.server.actors.TbActorRef;
  23 +import org.thingsboard.server.actors.TbEntityActorId;
24 import org.thingsboard.server.actors.service.DefaultActorService; 24 import org.thingsboard.server.actors.service.DefaultActorService;
25 import org.thingsboard.server.actors.shared.ComponentMsgProcessor; 25 import org.thingsboard.server.actors.shared.ComponentMsgProcessor;
26 import org.thingsboard.server.common.data.EntityType; 26 import org.thingsboard.server.common.data.EntityType;
@@ -62,8 +62,8 @@ import java.util.stream.Collectors; @@ -62,8 +62,8 @@ import java.util.stream.Collectors;
62 @Slf4j 62 @Slf4j
63 public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleChainId> { 63 public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleChainId> {
64 64
65 - private final ActorRef parent;  
66 - private final ActorRef self; 65 + private final TbActorRef parent;
  66 + private final TbActorRef self;
67 private final Map<RuleNodeId, RuleNodeCtx> nodeActors; 67 private final Map<RuleNodeId, RuleNodeCtx> nodeActors;
68 private final Map<RuleNodeId, List<RuleNodeRelation>> nodeRoutes; 68 private final Map<RuleNodeId, List<RuleNodeRelation>> nodeRoutes;
69 private final RuleChainService service; 69 private final RuleChainService service;
@@ -75,7 +75,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh @@ -75,7 +75,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh
75 private boolean started; 75 private boolean started;
76 76
77 RuleChainActorMessageProcessor(TenantId tenantId, RuleChain ruleChain, ActorSystemContext systemContext 77 RuleChainActorMessageProcessor(TenantId tenantId, RuleChain ruleChain, ActorSystemContext systemContext
78 - , ActorRef parent, ActorRef self) { 78 + , TbActorRef parent, TbActorRef self) {
79 super(systemContext, tenantId, ruleChain.getId()); 79 super(systemContext, tenantId, ruleChain.getId());
80 this.ruleChainName = ruleChain.getName(); 80 this.ruleChainName = ruleChain.getName();
81 this.parent = parent; 81 this.parent = parent;
@@ -92,7 +92,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh @@ -92,7 +92,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh
92 } 92 }
93 93
94 @Override 94 @Override
95 - public void start(ActorContext context) { 95 + public void start(TbActorCtx context) {
96 if (!started) { 96 if (!started) {
97 RuleChain ruleChain = service.findRuleChainById(tenantId, entityId); 97 RuleChain ruleChain = service.findRuleChainById(tenantId, entityId);
98 if (ruleChain != null) { 98 if (ruleChain != null) {
@@ -101,7 +101,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh @@ -101,7 +101,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh
101 // Creating and starting the actors; 101 // Creating and starting the actors;
102 for (RuleNode ruleNode : ruleNodeList) { 102 for (RuleNode ruleNode : ruleNodeList) {
103 log.trace("[{}][{}] Creating rule node [{}]: {}", entityId, ruleNode.getId(), ruleNode.getName(), ruleNode); 103 log.trace("[{}][{}] Creating rule node [{}]: {}", entityId, ruleNode.getId(), ruleNode.getName(), ruleNode);
104 - ActorRef ruleNodeActor = createRuleNodeActor(context, ruleNode); 104 + TbActorRef ruleNodeActor = createRuleNodeActor(context, ruleNode);
105 nodeActors.put(ruleNode.getId(), new RuleNodeCtx(tenantId, self, ruleNodeActor, ruleNode)); 105 nodeActors.put(ruleNode.getId(), new RuleNodeCtx(tenantId, self, ruleNodeActor, ruleNode));
106 } 106 }
107 initRoutes(ruleChain, ruleNodeList); 107 initRoutes(ruleChain, ruleNodeList);
@@ -113,7 +113,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh @@ -113,7 +113,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh
113 } 113 }
114 114
115 @Override 115 @Override
116 - public void onUpdate(ActorContext context) { 116 + public void onUpdate(TbActorCtx context) {
117 RuleChain ruleChain = service.findRuleChainById(tenantId, entityId); 117 RuleChain ruleChain = service.findRuleChainById(tenantId, entityId);
118 if (ruleChain != null) { 118 if (ruleChain != null) {
119 ruleChainName = ruleChain.getName(); 119 ruleChainName = ruleChain.getName();
@@ -123,12 +123,12 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh @@ -123,12 +123,12 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh
123 RuleNodeCtx existing = nodeActors.get(ruleNode.getId()); 123 RuleNodeCtx existing = nodeActors.get(ruleNode.getId());
124 if (existing == null) { 124 if (existing == null) {
125 log.trace("[{}][{}] Creating rule node [{}]: {}", entityId, ruleNode.getId(), ruleNode.getName(), ruleNode); 125 log.trace("[{}][{}] Creating rule node [{}]: {}", entityId, ruleNode.getId(), ruleNode.getName(), ruleNode);
126 - ActorRef ruleNodeActor = createRuleNodeActor(context, ruleNode); 126 + TbActorRef ruleNodeActor = createRuleNodeActor(context, ruleNode);
127 nodeActors.put(ruleNode.getId(), new RuleNodeCtx(tenantId, self, ruleNodeActor, ruleNode)); 127 nodeActors.put(ruleNode.getId(), new RuleNodeCtx(tenantId, self, ruleNodeActor, ruleNode));
128 } else { 128 } else {
129 log.trace("[{}][{}] Updating rule node [{}]: {}", entityId, ruleNode.getId(), ruleNode.getName(), ruleNode); 129 log.trace("[{}][{}] Updating rule node [{}]: {}", entityId, ruleNode.getId(), ruleNode.getName(), ruleNode);
130 existing.setSelf(ruleNode); 130 existing.setSelf(ruleNode);
131 - existing.getSelfActor().tell(new ComponentLifecycleMsg(tenantId, existing.getSelf().getId(), ComponentLifecycleEvent.UPDATED), self); 131 + existing.getSelfActor().tell(new ComponentLifecycleMsg(tenantId, existing.getSelf().getId(), ComponentLifecycleEvent.UPDATED));
132 } 132 }
133 } 133 }
134 134
@@ -137,7 +137,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh @@ -137,7 +137,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh
137 removedRules.forEach(ruleNodeId -> { 137 removedRules.forEach(ruleNodeId -> {
138 log.trace("[{}][{}] Removing rule node [{}]", tenantId, entityId, ruleNodeId); 138 log.trace("[{}][{}] Removing rule node [{}]", tenantId, entityId, ruleNodeId);
139 RuleNodeCtx removed = nodeActors.remove(ruleNodeId); 139 RuleNodeCtx removed = nodeActors.remove(ruleNodeId);
140 - removed.getSelfActor().tell(new ComponentLifecycleMsg(tenantId, removed.getSelf().getId(), ComponentLifecycleEvent.DELETED), self); 140 + removed.getSelfActor().tell(new ComponentLifecycleMsg(tenantId, removed.getSelf().getId(), ComponentLifecycleEvent.DELETED));
141 }); 141 });
142 142
143 initRoutes(ruleChain, ruleNodeList); 143 initRoutes(ruleChain, ruleNodeList);
@@ -145,26 +145,23 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh @@ -145,26 +145,23 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh
145 } 145 }
146 146
147 @Override 147 @Override
148 - public void stop(ActorContext context) { 148 + public void stop(TbActorCtx ctx) {
149 log.trace("[{}][{}] Stopping rule chain with {} nodes", tenantId, entityId, nodeActors.size()); 149 log.trace("[{}][{}] Stopping rule chain with {} nodes", tenantId, entityId, nodeActors.size());
150 - nodeActors.values().stream().map(RuleNodeCtx::getSelfActor).forEach(context::stop); 150 + nodeActors.values().stream().map(RuleNodeCtx::getSelfActor).map(TbActorRef::getActorId).forEach(ctx::stop);
151 nodeActors.clear(); 151 nodeActors.clear();
152 nodeRoutes.clear(); 152 nodeRoutes.clear();
153 - context.stop(self);  
154 started = false; 153 started = false;
155 } 154 }
156 155
157 @Override 156 @Override
158 public void onPartitionChangeMsg(PartitionChangeMsg msg) { 157 public void onPartitionChangeMsg(PartitionChangeMsg msg) {
159 - nodeActors.values().stream().map(RuleNodeCtx::getSelfActor).forEach(actorRef -> actorRef.tell(msg, self)); 158 + nodeActors.values().stream().map(RuleNodeCtx::getSelfActor).forEach(actorRef -> actorRef.tell(msg));
160 } 159 }
161 160
162 - private ActorRef createRuleNodeActor(ActorContext context, RuleNode ruleNode) {  
163 - String dispatcherName = tenantId.getId().equals(EntityId.NULL_UUID) ?  
164 - DefaultActorService.SYSTEM_RULE_DISPATCHER_NAME : DefaultActorService.TENANT_RULE_DISPATCHER_NAME;  
165 - return context.actorOf(  
166 - Props.create(new RuleNodeActor.ActorCreator(systemContext, tenantId, entityId, ruleNode.getName(), ruleNode.getId()))  
167 - .withDispatcher(dispatcherName), ruleNode.getId().toString()); 161 + private TbActorRef createRuleNodeActor(TbActorCtx ctx, RuleNode ruleNode) {
  162 + return ctx.getOrCreateChildActor(new TbEntityActorId(ruleNode.getId()),
  163 + () -> DefaultActorService.RULE_DISPATCHER_NAME,
  164 + () -> new RuleNodeActor.ActorCreator(systemContext, tenantId, entityId, ruleNode.getName(), ruleNode.getId()));
168 } 165 }
169 166
170 private void initRoutes(RuleChain ruleChain, List<RuleNode> ruleNodeList) { 167 private void initRoutes(RuleChain ruleChain, List<RuleNode> ruleNodeList) {
@@ -303,7 +300,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh @@ -303,7 +300,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh
303 pushMsgToNode(nodeActors.get(new RuleNodeId(target.getId())), msg, fromRelationType); 300 pushMsgToNode(nodeActors.get(new RuleNodeId(target.getId())), msg, fromRelationType);
304 break; 301 break;
305 case RULE_CHAIN: 302 case RULE_CHAIN:
306 - parent.tell(new RuleChainToRuleChainMsg(new RuleChainId(target.getId()), entityId, msg, fromRelationType), self); 303 + parent.tell(new RuleChainToRuleChainMsg(new RuleChainId(target.getId()), entityId, msg, fromRelationType));
307 break; 304 break;
308 } 305 }
309 } else { 306 } else {
@@ -334,7 +331,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh @@ -334,7 +331,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh
334 331
335 private void pushMsgToNode(RuleNodeCtx nodeCtx, TbMsg msg, String fromRelationType) { 332 private void pushMsgToNode(RuleNodeCtx nodeCtx, TbMsg msg, String fromRelationType) {
336 if (nodeCtx != null) { 333 if (nodeCtx != null) {
337 - nodeCtx.getSelfActor().tell(new RuleChainToRuleNodeMsg(new DefaultTbContext(systemContext, nodeCtx), msg, fromRelationType), self); 334 + nodeCtx.getSelfActor().tell(new RuleChainToRuleNodeMsg(new DefaultTbContext(systemContext, nodeCtx), msg, fromRelationType));
338 } else { 335 } else {
339 log.error("[{}][{}] RuleNodeCtx is empty", entityId, ruleChainName); 336 log.error("[{}][{}] RuleNodeCtx is empty", entityId, ruleChainName);
340 msg.getCallback().onFailure(new RuleEngineException("Rule Node CTX is empty")); 337 msg.getCallback().onFailure(new RuleEngineException("Rule Node CTX is empty"));
@@ -15,21 +15,22 @@ @@ -15,21 +15,22 @@
15 */ 15 */
16 package org.thingsboard.server.actors.ruleChain; 16 package org.thingsboard.server.actors.ruleChain;
17 17
18 -import akka.actor.ActorContext;  
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; 18 import lombok.Getter;
  19 +import lombok.extern.slf4j.Slf4j;
24 import org.thingsboard.server.actors.ActorSystemContext; 20 import org.thingsboard.server.actors.ActorSystemContext;
  21 +import org.thingsboard.server.actors.TbActorRef;
  22 +import org.thingsboard.server.actors.TbEntityActorId;
  23 +import org.thingsboard.server.actors.TbEntityTypeActorIdPredicate;
25 import org.thingsboard.server.actors.service.ContextAwareActor; 24 import org.thingsboard.server.actors.service.ContextAwareActor;
26 import org.thingsboard.server.actors.service.DefaultActorService; 25 import org.thingsboard.server.actors.service.DefaultActorService;
  26 +import org.thingsboard.server.actors.tenant.TenantActor;
27 import org.thingsboard.server.common.data.EntityType; 27 import org.thingsboard.server.common.data.EntityType;
28 import org.thingsboard.server.common.data.id.EntityId; 28 import org.thingsboard.server.common.data.id.EntityId;
29 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; 30 import org.thingsboard.server.common.data.id.TenantId;
31 import org.thingsboard.server.common.data.page.PageDataIterable; 31 import org.thingsboard.server.common.data.page.PageDataIterable;
32 import org.thingsboard.server.common.data.rule.RuleChain; 32 import org.thingsboard.server.common.data.rule.RuleChain;
  33 +import org.thingsboard.server.common.msg.TbActorMsg;
33 import org.thingsboard.server.dao.rule.RuleChainService; 34 import org.thingsboard.server.dao.rule.RuleChainService;
34 35
35 import java.util.function.Function; 36 import java.util.function.Function;
@@ -37,20 +38,19 @@ import java.util.function.Function; @@ -37,20 +38,19 @@ import java.util.function.Function;
37 /** 38 /**
38 * Created by ashvayka on 15.03.18. 39 * Created by ashvayka on 15.03.18.
39 */ 40 */
  41 +@Slf4j
40 public abstract class RuleChainManagerActor extends ContextAwareActor { 42 public abstract class RuleChainManagerActor extends ContextAwareActor {
41 43
42 protected final TenantId tenantId; 44 protected final TenantId tenantId;
43 private final RuleChainService ruleChainService; 45 private final RuleChainService ruleChainService;
44 - private final BiMap<RuleChainId, ActorRef> actors;  
45 @Getter 46 @Getter
46 protected RuleChain rootChain; 47 protected RuleChain rootChain;
47 @Getter 48 @Getter
48 - protected ActorRef rootChainActor; 49 + protected TbActorRef rootChainActor;
49 50
50 public RuleChainManagerActor(ActorSystemContext systemContext, TenantId tenantId) { 51 public RuleChainManagerActor(ActorSystemContext systemContext, TenantId tenantId) {
51 super(systemContext); 52 super(systemContext);
52 this.tenantId = tenantId; 53 this.tenantId = tenantId;
53 - this.actors = HashBiMap.create();  
54 this.ruleChainService = systemContext.getRuleChainService(); 54 this.ruleChainService = systemContext.getRuleChainService();
55 } 55 }
56 56
@@ -58,46 +58,41 @@ public abstract class RuleChainManagerActor extends ContextAwareActor { @@ -58,46 +58,41 @@ public abstract class RuleChainManagerActor extends ContextAwareActor {
58 for (RuleChain ruleChain : new PageDataIterable<>(link -> ruleChainService.findTenantRuleChains(tenantId, link), ContextAwareActor.ENTITY_PACK_LIMIT)) { 58 for (RuleChain ruleChain : new PageDataIterable<>(link -> ruleChainService.findTenantRuleChains(tenantId, link), ContextAwareActor.ENTITY_PACK_LIMIT)) {
59 RuleChainId ruleChainId = ruleChain.getId(); 59 RuleChainId ruleChainId = ruleChain.getId();
60 log.debug("[{}|{}] Creating rule chain actor", ruleChainId.getEntityType(), 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); 61 + TbActorRef actorRef = getOrCreateActor(ruleChainId, id -> ruleChain);
63 visit(ruleChain, actorRef); 62 visit(ruleChain, actorRef);
64 log.debug("[{}|{}] Rule Chain actor created.", ruleChainId.getEntityType(), ruleChainId.getId()); 63 log.debug("[{}|{}] Rule Chain actor created.", ruleChainId.getEntityType(), ruleChainId.getId());
65 } 64 }
66 } 65 }
67 66
68 - protected void visit(RuleChain entity, ActorRef actorRef) { 67 + protected void visit(RuleChain entity, TbActorRef actorRef) {
69 if (entity != null && entity.isRoot()) { 68 if (entity != null && entity.isRoot()) {
70 rootChain = entity; 69 rootChain = entity;
71 rootChainActor = actorRef; 70 rootChainActor = actorRef;
72 } 71 }
73 } 72 }
74 73
75 - public ActorRef getOrCreateActor(akka.actor.ActorContext context, RuleChainId ruleChainId) {  
76 - return getOrCreateActor(context, ruleChainId, eId -> ruleChainService.findRuleChainById(TenantId.SYS_TENANT_ID, eId)); 74 + protected TbActorRef getOrCreateActor(RuleChainId ruleChainId) {
  75 + return getOrCreateActor(ruleChainId, eId -> ruleChainService.findRuleChainById(TenantId.SYS_TENANT_ID, eId));
77 } 76 }
78 77
79 - public ActorRef getOrCreateActor(akka.actor.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 - }); 78 + protected TbActorRef getOrCreateActor(RuleChainId ruleChainId, Function<RuleChainId, RuleChain> provider) {
  79 + return ctx.getOrCreateChildActor(new TbEntityActorId(ruleChainId),
  80 + () -> DefaultActorService.RULE_DISPATCHER_NAME,
  81 + () -> {
  82 + RuleChain ruleChain = provider.apply(ruleChainId);
  83 + return new RuleChainActor.ActorCreator(systemContext, tenantId, ruleChain);
  84 + });
85 } 85 }
86 86
87 - protected ActorRef getEntityActorRef(EntityId entityId) {  
88 - ActorRef target = null; 87 + protected TbActorRef getEntityActorRef(EntityId entityId) {
  88 + TbActorRef target = null;
89 if (entityId.getEntityType() == EntityType.RULE_CHAIN) { 89 if (entityId.getEntityType() == EntityType.RULE_CHAIN) {
90 - target = getOrCreateActor(this.context(), (RuleChainId) entityId); 90 + target = getOrCreateActor((RuleChainId) entityId);
91 } 91 }
92 return target; 92 return target;
93 } 93 }
94 94
95 - protected void broadcast(Object msg) {  
96 - actors.values().forEach(actorRef -> actorRef.tell(msg, ActorRef.noSender())); 95 + protected void broadcast(TbActorMsg msg) {
  96 + ctx.broadcastToChildren(msg, new TbEntityTypeActorIdPredicate(EntityType.RULE_CHAIN));
97 } 97 }
98 -  
99 - public ActorRef get(RuleChainId id) {  
100 - return actors.get(id);  
101 - }  
102 -  
103 } 98 }
@@ -15,31 +15,43 @@ @@ -15,31 +15,43 @@
15 */ 15 */
16 package org.thingsboard.server.actors.ruleChain; 16 package org.thingsboard.server.actors.ruleChain;
17 17
  18 +import lombok.extern.slf4j.Slf4j;
18 import org.thingsboard.server.actors.ActorSystemContext; 19 import org.thingsboard.server.actors.ActorSystemContext;
  20 +import org.thingsboard.server.actors.TbActor;
  21 +import org.thingsboard.server.actors.TbActorCtx;
  22 +import org.thingsboard.server.actors.TbActorId;
  23 +import org.thingsboard.server.actors.TbEntityActorId;
19 import org.thingsboard.server.actors.service.ComponentActor; 24 import org.thingsboard.server.actors.service.ComponentActor;
20 import org.thingsboard.server.actors.service.ContextBasedCreator; 25 import org.thingsboard.server.actors.service.ContextBasedCreator;
21 import org.thingsboard.server.common.data.id.RuleChainId; 26 import org.thingsboard.server.common.data.id.RuleChainId;
22 import org.thingsboard.server.common.data.id.RuleNodeId; 27 import org.thingsboard.server.common.data.id.RuleNodeId;
23 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.RuleChain;
24 import org.thingsboard.server.common.msg.TbActorMsg; 30 import org.thingsboard.server.common.msg.TbActorMsg;
25 import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; 31 import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg;
26 import org.thingsboard.server.common.msg.queue.PartitionChangeMsg; 32 import org.thingsboard.server.common.msg.queue.PartitionChangeMsg;
27 33
  34 +@Slf4j
28 public class RuleNodeActor extends ComponentActor<RuleNodeId, RuleNodeActorMessageProcessor> { 35 public class RuleNodeActor extends ComponentActor<RuleNodeId, RuleNodeActorMessageProcessor> {
29 36
30 private final String ruleChainName; 37 private final String ruleChainName;
31 private final RuleChainId ruleChainId; 38 private final RuleChainId ruleChainId;
  39 + private final RuleNodeId ruleNodeId;
32 40
33 private RuleNodeActor(ActorSystemContext systemContext, TenantId tenantId, RuleChainId ruleChainId, String ruleChainName, RuleNodeId ruleNodeId) { 41 private RuleNodeActor(ActorSystemContext systemContext, TenantId tenantId, RuleChainId ruleChainId, String ruleChainName, RuleNodeId ruleNodeId) {
34 super(systemContext, tenantId, ruleNodeId); 42 super(systemContext, tenantId, ruleNodeId);
35 this.ruleChainName = ruleChainName; 43 this.ruleChainName = ruleChainName;
36 this.ruleChainId = ruleChainId; 44 this.ruleChainId = ruleChainId;
37 - setProcessor(new RuleNodeActorMessageProcessor(tenantId, this.ruleChainName, ruleNodeId, systemContext,  
38 - context().parent(), context().self())); 45 + this.ruleNodeId = ruleNodeId;
39 } 46 }
40 47
41 @Override 48 @Override
42 - protected boolean process(TbActorMsg msg) { 49 + protected RuleNodeActorMessageProcessor createProcessor(TbActorCtx ctx) {
  50 + return new RuleNodeActorMessageProcessor(tenantId, this.ruleChainName, ruleNodeId, systemContext, ctx.getParentRef(), ctx);
  51 + }
  52 +
  53 + @Override
  54 + protected boolean doProcess(TbActorMsg msg) {
43 switch (msg.getMsgType()) { 55 switch (msg.getMsgType()) {
44 case COMPONENT_LIFE_CYCLE_MSG: 56 case COMPONENT_LIFE_CYCLE_MSG:
45 onComponentLifecycleMsg((ComponentLifecycleMsg) msg); 57 onComponentLifecycleMsg((ComponentLifecycleMsg) msg);
@@ -93,8 +105,7 @@ public class RuleNodeActor extends ComponentActor<RuleNodeId, RuleNodeActorMessa @@ -93,8 +105,7 @@ public class RuleNodeActor extends ComponentActor<RuleNodeId, RuleNodeActorMessa
93 logAndPersist("onRuleMsg", ActorSystemContext.toException(msg.getError())); 105 logAndPersist("onRuleMsg", ActorSystemContext.toException(msg.getError()));
94 } 106 }
95 107
96 - public static class ActorCreator extends ContextBasedCreator<RuleNodeActor> {  
97 - private static final long serialVersionUID = 1L; 108 + public static class ActorCreator extends ContextBasedCreator {
98 109
99 private final TenantId tenantId; 110 private final TenantId tenantId;
100 private final RuleChainId ruleChainId; 111 private final RuleChainId ruleChainId;
@@ -111,7 +122,12 @@ public class RuleNodeActor extends ComponentActor<RuleNodeId, RuleNodeActorMessa @@ -111,7 +122,12 @@ public class RuleNodeActor extends ComponentActor<RuleNodeId, RuleNodeActorMessa
111 } 122 }
112 123
113 @Override 124 @Override
114 - public RuleNodeActor create() throws Exception { 125 + public TbActorId createActorId() {
  126 + return new TbEntityActorId(ruleNodeId);
  127 + }
  128 +
  129 + @Override
  130 + public TbActor createActor() {
115 return new RuleNodeActor(context, tenantId, ruleChainId, ruleChainName, ruleNodeId); 131 return new RuleNodeActor(context, tenantId, ruleChainId, ruleChainName, ruleNodeId);
116 } 132 }
117 } 133 }
@@ -15,11 +15,11 @@ @@ -15,11 +15,11 @@
15 */ 15 */
16 package org.thingsboard.server.actors.ruleChain; 16 package org.thingsboard.server.actors.ruleChain;
17 17
18 -import akka.actor.ActorContext;  
19 -import akka.actor.ActorRef;  
20 import org.thingsboard.rule.engine.api.TbNode; 18 import org.thingsboard.rule.engine.api.TbNode;
21 import org.thingsboard.rule.engine.api.TbNodeConfiguration; 19 import org.thingsboard.rule.engine.api.TbNodeConfiguration;
22 import org.thingsboard.server.actors.ActorSystemContext; 20 import org.thingsboard.server.actors.ActorSystemContext;
  21 +import org.thingsboard.server.actors.TbActorCtx;
  22 +import org.thingsboard.server.actors.TbActorRef;
23 import org.thingsboard.server.actors.shared.ComponentMsgProcessor; 23 import org.thingsboard.server.actors.shared.ComponentMsgProcessor;
24 import org.thingsboard.server.common.data.id.RuleNodeId; 24 import org.thingsboard.server.common.data.id.RuleNodeId;
25 import org.thingsboard.server.common.data.id.TenantId; 25 import org.thingsboard.server.common.data.id.TenantId;
@@ -34,13 +34,13 @@ import org.thingsboard.server.common.msg.queue.RuleNodeException; @@ -34,13 +34,13 @@ import org.thingsboard.server.common.msg.queue.RuleNodeException;
34 public class RuleNodeActorMessageProcessor extends ComponentMsgProcessor<RuleNodeId> { 34 public class RuleNodeActorMessageProcessor extends ComponentMsgProcessor<RuleNodeId> {
35 35
36 private final String ruleChainName; 36 private final String ruleChainName;
37 - private final ActorRef self; 37 + private final TbActorRef self;
38 private RuleNode ruleNode; 38 private RuleNode ruleNode;
39 private TbNode tbNode; 39 private TbNode tbNode;
40 private DefaultTbContext defaultCtx; 40 private DefaultTbContext defaultCtx;
41 41
42 RuleNodeActorMessageProcessor(TenantId tenantId, String ruleChainName, RuleNodeId ruleNodeId, ActorSystemContext systemContext 42 RuleNodeActorMessageProcessor(TenantId tenantId, String ruleChainName, RuleNodeId ruleNodeId, ActorSystemContext systemContext
43 - , ActorRef parent, ActorRef self) { 43 + , TbActorRef parent, TbActorRef self) {
44 super(systemContext, tenantId, ruleNodeId); 44 super(systemContext, tenantId, ruleNodeId);
45 this.ruleChainName = ruleChainName; 45 this.ruleChainName = ruleChainName;
46 this.self = self; 46 this.self = self;
@@ -49,7 +49,7 @@ public class RuleNodeActorMessageProcessor extends ComponentMsgProcessor<RuleNod @@ -49,7 +49,7 @@ public class RuleNodeActorMessageProcessor extends ComponentMsgProcessor<RuleNod
49 } 49 }
50 50
51 @Override 51 @Override
52 - public void start(ActorContext context) throws Exception { 52 + public void start(TbActorCtx context) throws Exception {
53 tbNode = initComponent(ruleNode); 53 tbNode = initComponent(ruleNode);
54 if (tbNode != null) { 54 if (tbNode != null) {
55 state = ComponentLifecycleState.ACTIVE; 55 state = ComponentLifecycleState.ACTIVE;
@@ -57,7 +57,7 @@ public class RuleNodeActorMessageProcessor extends ComponentMsgProcessor<RuleNod @@ -57,7 +57,7 @@ public class RuleNodeActorMessageProcessor extends ComponentMsgProcessor<RuleNod
57 } 57 }
58 58
59 @Override 59 @Override
60 - public void onUpdate(ActorContext context) throws Exception { 60 + public void onUpdate(TbActorCtx context) throws Exception {
61 RuleNode newRuleNode = systemContext.getRuleChainService().findRuleNodeById(tenantId, entityId); 61 RuleNode newRuleNode = systemContext.getRuleChainService().findRuleNodeById(tenantId, entityId);
62 boolean restartRequired = state != ComponentLifecycleState.ACTIVE || 62 boolean restartRequired = state != ComponentLifecycleState.ACTIVE ||
63 !(ruleNode.getType().equals(newRuleNode.getType()) && ruleNode.getConfiguration().equals(newRuleNode.getConfiguration())); 63 !(ruleNode.getType().equals(newRuleNode.getType()) && ruleNode.getConfiguration().equals(newRuleNode.getConfiguration()));
@@ -72,11 +72,11 @@ public class RuleNodeActorMessageProcessor extends ComponentMsgProcessor<RuleNod @@ -72,11 +72,11 @@ public class RuleNodeActorMessageProcessor extends ComponentMsgProcessor<RuleNod
72 } 72 }
73 73
74 @Override 74 @Override
75 - public void stop(ActorContext context) { 75 + public void stop(TbActorCtx context) {
76 if (tbNode != null) { 76 if (tbNode != null) {
77 tbNode.destroy(); 77 tbNode.destroy();
  78 + state = ComponentLifecycleState.SUSPENDED;
78 } 79 }
79 - context.stop(self);  
80 } 80 }
81 81
82 @Override 82 @Override
@@ -15,9 +15,9 @@ @@ -15,9 +15,9 @@
15 */ 15 */
16 package org.thingsboard.server.actors.ruleChain; 16 package org.thingsboard.server.actors.ruleChain;
17 17
18 -import akka.actor.ActorRef;  
19 import lombok.AllArgsConstructor; 18 import lombok.AllArgsConstructor;
20 import lombok.Data; 19 import lombok.Data;
  20 +import org.thingsboard.server.actors.TbActorRef;
21 import org.thingsboard.server.common.data.id.TenantId; 21 import org.thingsboard.server.common.data.id.TenantId;
22 import org.thingsboard.server.common.data.rule.RuleNode; 22 import org.thingsboard.server.common.data.rule.RuleNode;
23 23
@@ -28,7 +28,7 @@ import org.thingsboard.server.common.data.rule.RuleNode; @@ -28,7 +28,7 @@ import org.thingsboard.server.common.data.rule.RuleNode;
28 @AllArgsConstructor 28 @AllArgsConstructor
29 final class RuleNodeCtx { 29 final class RuleNodeCtx {
30 private final TenantId tenantId; 30 private final TenantId tenantId;
31 - private final ActorRef chainActor;  
32 - private final ActorRef selfActor; 31 + private final TbActorRef chainActor;
  32 + private final TbActorRef selfActor;
33 private RuleNode self; 33 private RuleNode self;
34 } 34 }
@@ -15,19 +15,21 @@ @@ -15,19 +15,21 @@
15 */ 15 */
16 package org.thingsboard.server.actors.service; 16 package org.thingsboard.server.actors.service;
17 17
18 -import akka.actor.ActorRef; 18 +import lombok.extern.slf4j.Slf4j;
19 import org.thingsboard.server.actors.ActorSystemContext; 19 import org.thingsboard.server.actors.ActorSystemContext;
  20 +import org.thingsboard.server.actors.TbActorCtx;
20 import org.thingsboard.server.actors.shared.ComponentMsgProcessor; 21 import org.thingsboard.server.actors.shared.ComponentMsgProcessor;
21 import org.thingsboard.server.actors.stats.StatsPersistMsg; 22 import org.thingsboard.server.actors.stats.StatsPersistMsg;
22 import org.thingsboard.server.common.data.id.EntityId; 23 import org.thingsboard.server.common.data.id.EntityId;
23 import org.thingsboard.server.common.data.id.TenantId; 24 import org.thingsboard.server.common.data.id.TenantId;
24 import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; 25 import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
25 -import org.thingsboard.server.common.msg.queue.PartitionChangeMsg;  
26 import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; 26 import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg;
  27 +import org.thingsboard.server.common.msg.queue.PartitionChangeMsg;
27 28
28 /** 29 /**
29 * @author Andrew Shvayka 30 * @author Andrew Shvayka
30 */ 31 */
  32 +@Slf4j
31 public abstract class ComponentActor<T extends EntityId, P extends ComponentMsgProcessor<T>> extends ContextAwareActor { 33 public abstract class ComponentActor<T extends EntityId, P extends ComponentMsgProcessor<T>> extends ContextAwareActor {
32 34
33 private long lastPersistedErrorTs = 0L; 35 private long lastPersistedErrorTs = 0L;
@@ -43,15 +45,19 @@ public abstract class ComponentActor<T extends EntityId, P extends ComponentMsgP @@ -43,15 +45,19 @@ public abstract class ComponentActor<T extends EntityId, P extends ComponentMsgP
43 this.id = id; 45 this.id = id;
44 } 46 }
45 47
46 - protected void setProcessor(P processor) {  
47 - this.processor = processor;  
48 - } 48 + abstract protected P createProcessor(TbActorCtx ctx);
49 49
50 @Override 50 @Override
51 - public void preStart() { 51 + public void init(TbActorCtx ctx) {
  52 + super.init(ctx);
  53 + this.processor = createProcessor(ctx);
  54 + initProcessor(ctx);
  55 + }
  56 +
  57 + protected void initProcessor(TbActorCtx ctx) {
52 try { 58 try {
53 log.debug("[{}][{}][{}] Starting processor.", tenantId, id, id.getEntityType()); 59 log.debug("[{}][{}][{}] Starting processor.", tenantId, id, id.getEntityType());
54 - processor.start(context()); 60 + processor.start(ctx);
55 logLifecycleEvent(ComponentLifecycleEvent.STARTED); 61 logLifecycleEvent(ComponentLifecycleEvent.STARTED);
56 if (systemContext.isStatisticsEnabled()) { 62 if (systemContext.isStatisticsEnabled()) {
57 scheduleStatsPersistTick(); 63 scheduleStatsPersistTick();
@@ -66,7 +72,7 @@ public abstract class ComponentActor<T extends EntityId, P extends ComponentMsgP @@ -66,7 +72,7 @@ public abstract class ComponentActor<T extends EntityId, P extends ComponentMsgP
66 72
67 private void scheduleStatsPersistTick() { 73 private void scheduleStatsPersistTick() {
68 try { 74 try {
69 - processor.scheduleStatsPersistTick(context(), systemContext.getStatisticsPersistFrequency()); 75 + processor.scheduleStatsPersistTick(ctx, systemContext.getStatisticsPersistFrequency());
70 } catch (Exception e) { 76 } catch (Exception e) {
71 log.error("[{}][{}] Failed to schedule statistics store message. No statistics is going to be stored: {}", tenantId, id, e.getMessage()); 77 log.error("[{}][{}] Failed to schedule statistics store message. No statistics is going to be stored: {}", tenantId, id, e.getMessage());
72 logAndPersist("onScheduleStatsPersistMsg", e); 78 logAndPersist("onScheduleStatsPersistMsg", e);
@@ -74,10 +80,10 @@ public abstract class ComponentActor<T extends EntityId, P extends ComponentMsgP @@ -74,10 +80,10 @@ public abstract class ComponentActor<T extends EntityId, P extends ComponentMsgP
74 } 80 }
75 81
76 @Override 82 @Override
77 - public void postStop() { 83 + public void destroy() {
78 try { 84 try {
79 - log.debug("[{}][{}] Stopping processor.", tenantId, id, id.getEntityType());  
80 - processor.stop(context()); 85 + log.debug("[{}][{}][{}] Stopping processor.", tenantId, id, id.getEntityType());
  86 + processor.stop(ctx);
81 logLifecycleEvent(ComponentLifecycleEvent.STOPPED); 87 logLifecycleEvent(ComponentLifecycleEvent.STOPPED);
82 } catch (Exception e) { 88 } catch (Exception e) {
83 log.warn("[{}][{}] Failed to stop {} processor: {}", tenantId, id, id.getEntityType(), e.getMessage()); 89 log.warn("[{}][{}] Failed to stop {} processor: {}", tenantId, id, id.getEntityType(), e.getMessage());
@@ -91,19 +97,20 @@ public abstract class ComponentActor<T extends EntityId, P extends ComponentMsgP @@ -91,19 +97,20 @@ public abstract class ComponentActor<T extends EntityId, P extends ComponentMsgP
91 try { 97 try {
92 switch (msg.getEvent()) { 98 switch (msg.getEvent()) {
93 case CREATED: 99 case CREATED:
94 - processor.onCreated(context()); 100 + processor.onCreated(ctx);
95 break; 101 break;
96 case UPDATED: 102 case UPDATED:
97 - processor.onUpdate(context()); 103 + processor.onUpdate(ctx);
98 break; 104 break;
99 case ACTIVATED: 105 case ACTIVATED:
100 - processor.onActivate(context()); 106 + processor.onActivate(ctx);
101 break; 107 break;
102 case SUSPENDED: 108 case SUSPENDED:
103 - processor.onSuspend(context()); 109 + processor.onSuspend(ctx);
104 break; 110 break;
105 case DELETED: 111 case DELETED:
106 - processor.onStop(context()); 112 + processor.onStop(ctx);
  113 + ctx.stop(ctx.getSelf());
107 break; 114 break;
108 default: 115 default:
109 break; 116 break;
@@ -125,7 +132,7 @@ public abstract class ComponentActor<T extends EntityId, P extends ComponentMsgP @@ -125,7 +132,7 @@ public abstract class ComponentActor<T extends EntityId, P extends ComponentMsgP
125 132
126 protected void onStatsPersistTick(EntityId entityId) { 133 protected void onStatsPersistTick(EntityId entityId) {
127 try { 134 try {
128 - systemContext.getStatsActor().tell(new StatsPersistMsg(messagesProcessed, errorsOccurred, tenantId, entityId), ActorRef.noSender()); 135 + systemContext.getStatsActor().tell(new StatsPersistMsg(messagesProcessed, errorsOccurred, tenantId, entityId));
129 resetStatsCounters(); 136 resetStatsCounters();
130 } catch (Exception e) { 137 } catch (Exception e) {
131 logAndPersist("onStatsPersistTick", e); 138 logAndPersist("onStatsPersistTick", e);
@@ -149,10 +156,10 @@ public abstract class ComponentActor<T extends EntityId, P extends ComponentMsgP @@ -149,10 +156,10 @@ public abstract class ComponentActor<T extends EntityId, P extends ComponentMsgP
149 errorsOccurred++; 156 errorsOccurred++;
150 String componentName = processor != null ? processor.getComponentName() : "Unknown"; 157 String componentName = processor != null ? processor.getComponentName() : "Unknown";
151 if (critical) { 158 if (critical) {
152 - log.warn("[{}][{}][{}] Failed to process {} msg: {}", id, tenantId, componentName, method); 159 + log.warn("[{}][{}][{}] Failed to process method: {}", id, tenantId, componentName, method);
153 log.warn("Critical Error: ", e); 160 log.warn("Critical Error: ", e);
154 } else { 161 } else {
155 - log.debug("[{}][{}][{}] Failed to process {} msg: {}", id, tenantId, componentName, method); 162 + log.debug("[{}][{}][{}] Failed to process method: {}", id, tenantId, componentName, method);
156 log.debug("Debug Error: ", e); 163 log.debug("Debug Error: ", e);
157 } 164 }
158 long ts = System.currentTimeMillis(); 165 long ts = System.currentTimeMillis();
@@ -15,17 +15,18 @@ @@ -15,17 +15,18 @@
15 */ 15 */
16 package org.thingsboard.server.actors.service; 16 package org.thingsboard.server.actors.service;
17 17
18 -import akka.actor.Terminated;  
19 -import akka.actor.UntypedAbstractActor; 18 +import lombok.extern.slf4j.Slf4j;
20 import org.slf4j.Logger; 19 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory; 20 import org.slf4j.LoggerFactory;
  21 +import org.thingsboard.server.actors.AbstractTbActor;
22 import org.thingsboard.server.actors.ActorSystemContext; 22 import org.thingsboard.server.actors.ActorSystemContext;
  23 +import org.thingsboard.server.actors.ProcessFailureStrategy;
  24 +import org.thingsboard.server.actors.TbActor;
  25 +import org.thingsboard.server.actors.TbActorCtx;
23 import org.thingsboard.server.common.msg.TbActorMsg; 26 import org.thingsboard.server.common.msg.TbActorMsg;
24 27
25 -  
26 -public abstract class ContextAwareActor extends UntypedAbstractActor {  
27 -  
28 - protected final Logger log = LoggerFactory.getLogger(getClass()); 28 +@Slf4j
  29 +public abstract class ContextAwareActor extends AbstractTbActor {
29 30
30 public static final int ENTITY_PACK_LIMIT = 1024; 31 public static final int ENTITY_PACK_LIMIT = 1024;
31 32
@@ -37,27 +38,29 @@ public abstract class ContextAwareActor extends UntypedAbstractActor { @@ -37,27 +38,29 @@ public abstract class ContextAwareActor extends UntypedAbstractActor {
37 } 38 }
38 39
39 @Override 40 @Override
40 - public void onReceive(Object msg) { 41 + public boolean process(TbActorMsg msg) {
41 if (log.isDebugEnabled()) { 42 if (log.isDebugEnabled()) {
42 log.debug("Processing msg: {}", msg); 43 log.debug("Processing msg: {}", msg);
43 } 44 }
44 - if (msg instanceof TbActorMsg) {  
45 - try {  
46 - if (!process((TbActorMsg) msg)) {  
47 - log.warn("Unknown message: {}!", msg);  
48 - }  
49 - } catch (Exception e) {  
50 - throw e;  
51 - }  
52 - } else if (msg instanceof Terminated) {  
53 - processTermination((Terminated) msg);  
54 - } else {  
55 - log.warn("Unknown message: {}!", msg); 45 + if (!doProcess(msg)) {
  46 + log.warn("Unprocessed message: {}!", msg);
56 } 47 }
  48 + return false;
57 } 49 }
58 50
59 - protected void processTermination(Terminated msg) { 51 + protected abstract boolean doProcess(TbActorMsg msg);
  52 +
  53 + @Override
  54 + public ProcessFailureStrategy onProcessFailure(Throwable t) {
  55 + log.debug("[{}] Processing failure: ", getActorRef().getActorId(), t);
  56 + return doProcessFailure(t);
60 } 57 }
61 58
62 - protected abstract boolean process(TbActorMsg msg); 59 + protected ProcessFailureStrategy doProcessFailure(Throwable t) {
  60 + if (t instanceof Error) {
  61 + return ProcessFailureStrategy.stop();
  62 + } else {
  63 + return ProcessFailureStrategy.resume();
  64 + }
  65 + }
63 } 66 }
@@ -15,12 +15,10 @@ @@ -15,12 +15,10 @@
15 */ 15 */
16 package org.thingsboard.server.actors.service; 16 package org.thingsboard.server.actors.service;
17 17
18 -import akka.japi.Creator;  
19 import org.thingsboard.server.actors.ActorSystemContext; 18 import org.thingsboard.server.actors.ActorSystemContext;
  19 +import org.thingsboard.server.actors.TbActorCreator;
20 20
21 -public abstract class ContextBasedCreator<T> implements Creator<T> {  
22 -  
23 - private static final long serialVersionUID = 1L; 21 +public abstract class ContextBasedCreator implements TbActorCreator {
24 22
25 protected final transient ActorSystemContext context; 23 protected final transient ActorSystemContext context;
26 24
@@ -15,85 +15,116 @@ @@ -15,85 +15,116 @@
15 */ 15 */
16 package org.thingsboard.server.actors.service; 16 package org.thingsboard.server.actors.service;
17 17
18 -import akka.actor.ActorRef;  
19 -import akka.actor.ActorSystem;  
20 -import akka.actor.Props;  
21 -import akka.actor.Terminated;  
22 import lombok.extern.slf4j.Slf4j; 18 import lombok.extern.slf4j.Slf4j;
23 import org.springframework.beans.factory.annotation.Autowired; 19 import org.springframework.beans.factory.annotation.Autowired;
24 import org.springframework.beans.factory.annotation.Value; 20 import org.springframework.beans.factory.annotation.Value;
25 import org.springframework.boot.context.event.ApplicationReadyEvent; 21 import org.springframework.boot.context.event.ApplicationReadyEvent;
26 import org.springframework.context.event.EventListener; 22 import org.springframework.context.event.EventListener;
27 -import org.springframework.scheduling.annotation.Scheduled;  
28 import org.springframework.stereotype.Service; 23 import org.springframework.stereotype.Service;
29 import org.thingsboard.server.actors.ActorSystemContext; 24 import org.thingsboard.server.actors.ActorSystemContext;
  25 +import org.thingsboard.server.actors.DefaultTbActorSystem;
  26 +import org.thingsboard.server.actors.TbActorId;
  27 +import org.thingsboard.server.actors.TbActorRef;
  28 +import org.thingsboard.server.actors.TbActorSystem;
  29 +import org.thingsboard.server.actors.TbActorSystemSettings;
30 import org.thingsboard.server.actors.app.AppActor; 30 import org.thingsboard.server.actors.app.AppActor;
31 import org.thingsboard.server.actors.app.AppInitMsg; 31 import org.thingsboard.server.actors.app.AppInitMsg;
32 import org.thingsboard.server.actors.stats.StatsActor; 32 import org.thingsboard.server.actors.stats.StatsActor;
33 import org.thingsboard.server.common.msg.queue.PartitionChangeMsg; 33 import org.thingsboard.server.common.msg.queue.PartitionChangeMsg;
34 import org.thingsboard.server.queue.discovery.PartitionChangeEvent; 34 import org.thingsboard.server.queue.discovery.PartitionChangeEvent;
35 -import scala.concurrent.Await;  
36 -import scala.concurrent.Future;  
37 -import scala.concurrent.duration.Duration;  
38 35
39 import javax.annotation.PostConstruct; 36 import javax.annotation.PostConstruct;
40 import javax.annotation.PreDestroy; 37 import javax.annotation.PreDestroy;
41 -import java.util.concurrent.atomic.AtomicInteger; 38 +import java.util.concurrent.ExecutorService;
  39 +import java.util.concurrent.Executors;
  40 +import java.util.concurrent.ScheduledExecutorService;
42 41
43 @Service 42 @Service
44 @Slf4j 43 @Slf4j
45 public class DefaultActorService implements ActorService { 44 public class DefaultActorService implements ActorService {
46 45
47 - private static final String ACTOR_SYSTEM_NAME = "Akka";  
48 -  
49 public static final String APP_DISPATCHER_NAME = "app-dispatcher"; 46 public static final String APP_DISPATCHER_NAME = "app-dispatcher";
50 - public static final String CORE_DISPATCHER_NAME = "core-dispatcher";  
51 - public static final String SYSTEM_RULE_DISPATCHER_NAME = "system-rule-dispatcher";  
52 - public static final String TENANT_RULE_DISPATCHER_NAME = "rule-dispatcher"; 47 + public static final String TENANT_DISPATCHER_NAME = "tenant-dispatcher";
  48 + public static final String DEVICE_DISPATCHER_NAME = "device-dispatcher";
  49 + public static final String RULE_DISPATCHER_NAME = "rule-dispatcher";
53 50
54 @Autowired 51 @Autowired
55 private ActorSystemContext actorContext; 52 private ActorSystemContext actorContext;
56 53
57 - private ActorSystem system; 54 + private TbActorSystem system;
  55 +
  56 + private TbActorRef appActor;
  57 +
  58 + @Value("${actors.system.throughput:5}")
  59 + private int actorThroughput;
  60 +
  61 + @Value("${actors.system.max_actor_init_attempts:10}")
  62 + private int maxActorInitAttempts;
  63 +
  64 + @Value("${actors.system.scheduler_pool_size:1}")
  65 + private int schedulerPoolSize;
  66 +
  67 + @Value("${actors.system.app_dispatcher_pool_size:1}")
  68 + private int appDispatcherSize;
  69 +
  70 + @Value("${actors.system.tenant_dispatcher_pool_size:2}")
  71 + private int tenantDispatcherSize;
58 72
59 - private ActorRef appActor; 73 + @Value("${actors.system.device_dispatcher_pool_size:4}")
  74 + private int deviceDispatcherSize;
  75 +
  76 + @Value("${actors.system.rule_dispatcher_pool_size:4}")
  77 + private int ruleDispatcherSize;
60 78
61 @PostConstruct 79 @PostConstruct
62 public void initActorSystem() { 80 public void initActorSystem() {
63 - log.info("Initializing Actor system."); 81 + log.info("Initializing actor system.");
64 actorContext.setActorService(this); 82 actorContext.setActorService(this);
65 - system = ActorSystem.create(ACTOR_SYSTEM_NAME, actorContext.getConfig()); 83 + TbActorSystemSettings settings = new TbActorSystemSettings(actorThroughput, schedulerPoolSize, maxActorInitAttempts);
  84 + system = new DefaultTbActorSystem(settings);
  85 +
  86 + system.createDispatcher(APP_DISPATCHER_NAME, initDispatcherExecutor(appDispatcherSize));
  87 + system.createDispatcher(TENANT_DISPATCHER_NAME, initDispatcherExecutor(tenantDispatcherSize));
  88 + system.createDispatcher(DEVICE_DISPATCHER_NAME, initDispatcherExecutor(deviceDispatcherSize));
  89 + system.createDispatcher(RULE_DISPATCHER_NAME, initDispatcherExecutor(ruleDispatcherSize));
  90 +
66 actorContext.setActorSystem(system); 91 actorContext.setActorSystem(system);
67 92
68 - appActor = system.actorOf(Props.create(new AppActor.ActorCreator(actorContext)).withDispatcher(APP_DISPATCHER_NAME), "appActor"); 93 + appActor = system.createRootActor(APP_DISPATCHER_NAME, new AppActor.ActorCreator(actorContext));
69 actorContext.setAppActor(appActor); 94 actorContext.setAppActor(appActor);
70 95
71 - ActorRef statsActor = system.actorOf(Props.create(new StatsActor.ActorCreator(actorContext)).withDispatcher(CORE_DISPATCHER_NAME), "statsActor"); 96 + TbActorRef statsActor = system.createRootActor(TENANT_DISPATCHER_NAME, new StatsActor.ActorCreator(actorContext, "StatsActor"));
72 actorContext.setStatsActor(statsActor); 97 actorContext.setStatsActor(statsActor);
73 98
74 log.info("Actor system initialized."); 99 log.info("Actor system initialized.");
75 } 100 }
76 101
  102 + private ExecutorService initDispatcherExecutor(int poolSize) {
  103 + if (poolSize == 0) {
  104 + int cores = Runtime.getRuntime().availableProcessors();
  105 + poolSize = Math.max(1, cores / 2);
  106 + }
  107 + return Executors.newWorkStealingPool(poolSize);
  108 + }
  109 +
77 @EventListener(ApplicationReadyEvent.class) 110 @EventListener(ApplicationReadyEvent.class)
78 public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) { 111 public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
79 log.info("Received application ready event. Sending application init message to actor system"); 112 log.info("Received application ready event. Sending application init message to actor system");
80 - appActor.tell(new AppInitMsg(), ActorRef.noSender()); 113 + appActor.tell(new AppInitMsg());
81 } 114 }
82 115
83 @EventListener(PartitionChangeEvent.class) 116 @EventListener(PartitionChangeEvent.class)
84 public void onApplicationEvent(PartitionChangeEvent partitionChangeEvent) { 117 public void onApplicationEvent(PartitionChangeEvent partitionChangeEvent) {
85 log.info("Received partition change event."); 118 log.info("Received partition change event.");
86 - this.appActor.tell(new PartitionChangeMsg(partitionChangeEvent.getServiceQueueKey(), partitionChangeEvent.getPartitions()), ActorRef.noSender()); 119 + this.appActor.tell(new PartitionChangeMsg(partitionChangeEvent.getServiceQueueKey(), partitionChangeEvent.getPartitions()));
87 } 120 }
88 121
89 @PreDestroy 122 @PreDestroy
90 public void stopActorSystem() { 123 public void stopActorSystem() {
91 - Future<Terminated> status = system.terminate();  
92 - try {  
93 - Terminated terminated = Await.result(status, Duration.Inf());  
94 - log.info("Actor system terminated: {}", terminated);  
95 - } catch (Exception e) {  
96 - log.error("Failed to terminate actor system.", e); 124 + if (system != null) {
  125 + log.info("Stopping actor system.");
  126 + system.stop();
  127 + log.info("Actor system stopped.");
97 } 128 }
98 } 129 }
99 130
@@ -15,18 +15,13 @@ @@ -15,18 +15,13 @@
15 */ 15 */
16 package org.thingsboard.server.actors.shared; 16 package org.thingsboard.server.actors.shared;
17 17
18 -import akka.actor.ActorContext;  
19 -import akka.actor.ActorRef;  
20 -import akka.actor.Scheduler;  
21 -import akka.event.LoggingAdapter;  
22 import com.fasterxml.jackson.databind.ObjectMapper; 18 import com.fasterxml.jackson.databind.ObjectMapper;
23 -import lombok.AllArgsConstructor;  
24 -import lombok.Data;  
25 import lombok.extern.slf4j.Slf4j; 19 import lombok.extern.slf4j.Slf4j;
26 import org.thingsboard.server.actors.ActorSystemContext; 20 import org.thingsboard.server.actors.ActorSystemContext;
27 -import scala.concurrent.ExecutionContextExecutor;  
28 -import scala.concurrent.duration.Duration; 21 +import org.thingsboard.server.actors.TbActorCtx;
  22 +import org.thingsboard.server.common.msg.TbActorMsg;
29 23
  24 +import java.util.concurrent.ScheduledExecutorService;
30 import java.util.concurrent.TimeUnit; 25 import java.util.concurrent.TimeUnit;
31 26
32 @Slf4j 27 @Slf4j
@@ -40,31 +35,16 @@ public abstract class AbstractContextAwareMsgProcessor { @@ -40,31 +35,16 @@ public abstract class AbstractContextAwareMsgProcessor {
40 this.systemContext = systemContext; 35 this.systemContext = systemContext;
41 } 36 }
42 37
43 - private Scheduler getScheduler() { 38 + private ScheduledExecutorService getScheduler() {
44 return systemContext.getScheduler(); 39 return systemContext.getScheduler();
45 } 40 }
46 41
47 - private ExecutionContextExecutor getSystemDispatcher() {  
48 - return systemContext.getActorSystem().dispatcher(); 42 + protected void schedulePeriodicMsgWithDelay(TbActorCtx ctx, TbActorMsg msg, long delayInMs, long periodInMs) {
  43 + systemContext.schedulePeriodicMsgWithDelay(ctx, msg, delayInMs, periodInMs);
49 } 44 }
50 45
51 - protected void schedulePeriodicMsgWithDelay(ActorContext ctx, Object msg, long delayInMs, long periodInMs) {  
52 - schedulePeriodicMsgWithDelay(msg, delayInMs, periodInMs, ctx.self()); 46 + protected void scheduleMsgWithDelay(TbActorCtx ctx, TbActorMsg msg, long delayInMs) {
  47 + systemContext.scheduleMsgWithDelay(ctx, msg, delayInMs);
53 } 48 }
54 49
55 - private void schedulePeriodicMsgWithDelay(Object msg, long delayInMs, long periodInMs, ActorRef target) {  
56 - log.debug("Scheduling periodic msg {} every {} ms with delay {} ms", msg, periodInMs, delayInMs);  
57 - getScheduler().schedule(Duration.create(delayInMs, TimeUnit.MILLISECONDS), Duration.create(periodInMs, TimeUnit.MILLISECONDS), target, msg, getSystemDispatcher(), null);  
58 - }  
59 -  
60 - protected void scheduleMsgWithDelay(ActorContext ctx, Object msg, long delayInMs) {  
61 - scheduleMsgWithDelay(msg, delayInMs, ctx.self());  
62 - }  
63 -  
64 - private void scheduleMsgWithDelay(Object msg, long delayInMs, ActorRef target) {  
65 - log.debug("Scheduling msg {} with delay {} ms", msg, delayInMs);  
66 - getScheduler().scheduleOnce(Duration.create(delayInMs, TimeUnit.MILLISECONDS), target, msg, getSystemDispatcher(), null);  
67 - }  
68 -  
69 -  
70 } 50 }
@@ -15,16 +15,15 @@ @@ -15,16 +15,15 @@
15 */ 15 */
16 package org.thingsboard.server.actors.shared; 16 package org.thingsboard.server.actors.shared;
17 17
18 -import akka.actor.ActorContext;  
19 import lombok.extern.slf4j.Slf4j; 18 import lombok.extern.slf4j.Slf4j;
20 import org.thingsboard.server.actors.ActorSystemContext; 19 import org.thingsboard.server.actors.ActorSystemContext;
  20 +import org.thingsboard.server.actors.TbActorCtx;
21 import org.thingsboard.server.actors.stats.StatsPersistTick; 21 import org.thingsboard.server.actors.stats.StatsPersistTick;
22 import org.thingsboard.server.common.data.id.EntityId; 22 import org.thingsboard.server.common.data.id.EntityId;
23 import org.thingsboard.server.common.data.id.TenantId; 23 import org.thingsboard.server.common.data.id.TenantId;
24 import org.thingsboard.server.common.data.plugin.ComponentLifecycleState; 24 import org.thingsboard.server.common.data.plugin.ComponentLifecycleState;
25 import org.thingsboard.server.common.msg.TbMsg; 25 import org.thingsboard.server.common.msg.TbMsg;
26 import org.thingsboard.server.common.msg.queue.PartitionChangeMsg; 26 import org.thingsboard.server.common.msg.queue.PartitionChangeMsg;
27 -import org.thingsboard.server.common.msg.queue.RuleEngineException;  
28 import org.thingsboard.server.common.msg.queue.RuleNodeException; 27 import org.thingsboard.server.common.msg.queue.RuleNodeException;
29 28
30 @Slf4j 29 @Slf4j
@@ -42,38 +41,38 @@ public abstract class ComponentMsgProcessor<T extends EntityId> extends Abstract @@ -42,38 +41,38 @@ public abstract class ComponentMsgProcessor<T extends EntityId> extends Abstract
42 41
43 public abstract String getComponentName(); 42 public abstract String getComponentName();
44 43
45 - public abstract void start(ActorContext context) throws Exception; 44 + public abstract void start(TbActorCtx context) throws Exception;
46 45
47 - public abstract void stop(ActorContext context) throws Exception; 46 + public abstract void stop(TbActorCtx context) throws Exception;
48 47
49 public abstract void onPartitionChangeMsg(PartitionChangeMsg msg) throws Exception; 48 public abstract void onPartitionChangeMsg(PartitionChangeMsg msg) throws Exception;
50 49
51 - public void onCreated(ActorContext context) throws Exception { 50 + public void onCreated(TbActorCtx context) throws Exception {
52 start(context); 51 start(context);
53 } 52 }
54 53
55 - public void onUpdate(ActorContext context) throws Exception { 54 + public void onUpdate(TbActorCtx context) throws Exception {
56 restart(context); 55 restart(context);
57 } 56 }
58 57
59 - public void onActivate(ActorContext context) throws Exception { 58 + public void onActivate(TbActorCtx context) throws Exception {
60 restart(context); 59 restart(context);
61 } 60 }
62 61
63 - public void onSuspend(ActorContext context) throws Exception { 62 + public void onSuspend(TbActorCtx context) throws Exception {
64 stop(context); 63 stop(context);
65 } 64 }
66 65
67 - public void onStop(ActorContext context) throws Exception { 66 + public void onStop(TbActorCtx context) throws Exception {
68 stop(context); 67 stop(context);
69 } 68 }
70 69
71 - private void restart(ActorContext context) throws Exception { 70 + private void restart(TbActorCtx context) throws Exception {
72 stop(context); 71 stop(context);
73 start(context); 72 start(context);
74 } 73 }
75 74
76 - public void scheduleStatsPersistTick(ActorContext context, long statsPersistFrequency) { 75 + public void scheduleStatsPersistTick(TbActorCtx context, long statsPersistFrequency) {
77 schedulePeriodicMsgWithDelay(context, new StatsPersistTick(), statsPersistFrequency, statsPersistFrequency); 76 schedulePeriodicMsgWithDelay(context, new StatsPersistTick(), statsPersistFrequency, statsPersistFrequency);
78 } 77 }
79 78
@@ -19,10 +19,15 @@ import com.fasterxml.jackson.databind.JsonNode; @@ -19,10 +19,15 @@ import com.fasterxml.jackson.databind.JsonNode;
19 import com.fasterxml.jackson.databind.ObjectMapper; 19 import com.fasterxml.jackson.databind.ObjectMapper;
20 import lombok.extern.slf4j.Slf4j; 20 import lombok.extern.slf4j.Slf4j;
21 import org.thingsboard.server.actors.ActorSystemContext; 21 import org.thingsboard.server.actors.ActorSystemContext;
  22 +import org.thingsboard.server.actors.TbActor;
  23 +import org.thingsboard.server.actors.TbActorCtx;
  24 +import org.thingsboard.server.actors.TbActorId;
  25 +import org.thingsboard.server.actors.TbStringActorId;
22 import org.thingsboard.server.actors.service.ContextAwareActor; 26 import org.thingsboard.server.actors.service.ContextAwareActor;
23 import org.thingsboard.server.actors.service.ContextBasedCreator; 27 import org.thingsboard.server.actors.service.ContextBasedCreator;
24 import org.thingsboard.server.common.data.DataConstants; 28 import org.thingsboard.server.common.data.DataConstants;
25 import org.thingsboard.server.common.data.Event; 29 import org.thingsboard.server.common.data.Event;
  30 +import org.thingsboard.server.common.msg.MsgType;
26 import org.thingsboard.server.common.msg.TbActorMsg; 31 import org.thingsboard.server.common.msg.TbActorMsg;
27 32
28 @Slf4j 33 @Slf4j
@@ -35,24 +40,17 @@ public class StatsActor extends ContextAwareActor { @@ -35,24 +40,17 @@ public class StatsActor extends ContextAwareActor {
35 } 40 }
36 41
37 @Override 42 @Override
38 - protected boolean process(TbActorMsg msg) {  
39 - //TODO Move everything here, to work with TbActorMsg\  
40 - return false;  
41 - }  
42 -  
43 - @Override  
44 - public void onReceive(Object msg) { 43 + protected boolean doProcess(TbActorMsg msg) {
45 log.debug("Received message: {}", msg); 44 log.debug("Received message: {}", msg);
46 - if (msg instanceof StatsPersistMsg) {  
47 - try {  
48 - onStatsPersistMsg((StatsPersistMsg) msg);  
49 - } catch (Exception e) {  
50 - log.warn("Failed to persist statistics: {}", msg, e);  
51 - } 45 + if (msg.getMsgType().equals(MsgType.STATS_PERSIST_MSG)) {
  46 + onStatsPersistMsg((StatsPersistMsg) msg);
  47 + return true;
  48 + } else {
  49 + return false;
52 } 50 }
53 } 51 }
54 52
55 - public void onStatsPersistMsg(StatsPersistMsg msg) throws Exception { 53 + public void onStatsPersistMsg(StatsPersistMsg msg) {
56 Event event = new Event(); 54 Event event = new Event();
57 event.setEntityId(msg.getEntityId()); 55 event.setEntityId(msg.getEntityId());
58 event.setTenantId(msg.getTenantId()); 56 event.setTenantId(msg.getTenantId());
@@ -65,15 +63,21 @@ public class StatsActor extends ContextAwareActor { @@ -65,15 +63,21 @@ public class StatsActor extends ContextAwareActor {
65 return mapper.createObjectNode().put("server", serviceId).put("messagesProcessed", messagesProcessed).put("errorsOccurred", errorsOccurred); 63 return mapper.createObjectNode().put("server", serviceId).put("messagesProcessed", messagesProcessed).put("errorsOccurred", errorsOccurred);
66 } 64 }
67 65
68 - public static class ActorCreator extends ContextBasedCreator<StatsActor> {  
69 - private static final long serialVersionUID = 1L; 66 + public static class ActorCreator extends ContextBasedCreator {
  67 + private final String actorId;
70 68
71 - public ActorCreator(ActorSystemContext context) { 69 + public ActorCreator(ActorSystemContext context, String actorId) {
72 super(context); 70 super(context);
  71 + this.actorId = actorId;
  72 + }
  73 +
  74 + @Override
  75 + public TbActorId createActorId() {
  76 + return new TbStringActorId(actorId);
73 } 77 }
74 78
75 @Override 79 @Override
76 - public StatsActor create() { 80 + public TbActor createActor() {
77 return new StatsActor(context); 81 return new StatsActor(context);
78 } 82 }
79 } 83 }
@@ -20,13 +20,21 @@ import lombok.Getter; @@ -20,13 +20,21 @@ import lombok.Getter;
20 import lombok.ToString; 20 import lombok.ToString;
21 import org.thingsboard.server.common.data.id.EntityId; 21 import org.thingsboard.server.common.data.id.EntityId;
22 import org.thingsboard.server.common.data.id.TenantId; 22 import org.thingsboard.server.common.data.id.TenantId;
  23 +import org.thingsboard.server.common.msg.MsgType;
  24 +import org.thingsboard.server.common.msg.TbActorMsg;
23 25
24 @AllArgsConstructor 26 @AllArgsConstructor
25 @Getter 27 @Getter
26 @ToString 28 @ToString
27 -public final class StatsPersistMsg { 29 +public final class StatsPersistMsg implements TbActorMsg {
  30 +
28 private long messagesProcessed; 31 private long messagesProcessed;
29 private long errorsOccurred; 32 private long errorsOccurred;
30 private TenantId tenantId; 33 private TenantId tenantId;
31 private EntityId entityId; 34 private EntityId entityId;
  35 +
  36 + @Override
  37 + public MsgType getMsgType() {
  38 + return MsgType.STATS_PERSIST_MSG;
  39 + }
32 } 40 }
@@ -15,16 +15,15 @@ @@ -15,16 +15,15 @@
15 */ 15 */
16 package org.thingsboard.server.actors.tenant; 16 package org.thingsboard.server.actors.tenant;
17 17
18 -import akka.actor.ActorInitializationException;  
19 -import akka.actor.ActorRef;  
20 -import akka.actor.LocalActorRef;  
21 -import akka.actor.OneForOneStrategy;  
22 -import akka.actor.Props;  
23 -import akka.actor.SupervisorStrategy;  
24 -import akka.actor.Terminated;  
25 -import com.google.common.collect.BiMap;  
26 -import com.google.common.collect.HashBiMap; 18 +import lombok.extern.slf4j.Slf4j;
27 import org.thingsboard.server.actors.ActorSystemContext; 19 import org.thingsboard.server.actors.ActorSystemContext;
  20 +import org.thingsboard.server.actors.TbActor;
  21 +import org.thingsboard.server.actors.TbActorCtx;
  22 +import org.thingsboard.server.actors.TbActorId;
  23 +import org.thingsboard.server.actors.TbActorNotRegisteredException;
  24 +import org.thingsboard.server.actors.TbActorRef;
  25 +import org.thingsboard.server.actors.TbEntityActorId;
  26 +import org.thingsboard.server.actors.TbEntityTypeActorIdPredicate;
28 import org.thingsboard.server.actors.device.DeviceActorCreator; 27 import org.thingsboard.server.actors.device.DeviceActorCreator;
29 import org.thingsboard.server.actors.ruleChain.RuleChainManagerActor; 28 import org.thingsboard.server.actors.ruleChain.RuleChainManagerActor;
30 import org.thingsboard.server.actors.service.ContextBasedCreator; 29 import org.thingsboard.server.actors.service.ContextBasedCreator;
@@ -32,6 +31,7 @@ import org.thingsboard.server.actors.service.DefaultActorService; @@ -32,6 +31,7 @@ import org.thingsboard.server.actors.service.DefaultActorService;
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;
34 import org.thingsboard.server.common.data.id.DeviceId; 33 import org.thingsboard.server.common.data.id.DeviceId;
  34 +import org.thingsboard.server.common.data.id.EntityId;
35 import org.thingsboard.server.common.data.id.RuleChainId; 35 import org.thingsboard.server.common.data.id.RuleChainId;
36 import org.thingsboard.server.common.data.id.TenantId; 36 import org.thingsboard.server.common.data.id.TenantId;
37 import org.thingsboard.server.common.data.rule.RuleChain; 37 import org.thingsboard.server.common.data.rule.RuleChain;
@@ -45,32 +45,25 @@ import org.thingsboard.server.common.msg.queue.PartitionChangeMsg; @@ -45,32 +45,25 @@ import org.thingsboard.server.common.msg.queue.PartitionChangeMsg;
45 import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg; 45 import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg;
46 import org.thingsboard.server.common.msg.queue.RuleEngineException; 46 import org.thingsboard.server.common.msg.queue.RuleEngineException;
47 import org.thingsboard.server.common.msg.queue.ServiceType; 47 import org.thingsboard.server.common.msg.queue.ServiceType;
48 -import scala.concurrent.duration.Duration;  
49 48
50 import java.util.List; 49 import java.util.List;
51 import java.util.Optional; 50 import java.util.Optional;
52 -import java.util.stream.Collectors;  
53 51
  52 +@Slf4j
54 public class TenantActor extends RuleChainManagerActor { 53 public class TenantActor extends RuleChainManagerActor {
55 54
56 - private final BiMap<DeviceId, ActorRef> deviceActors;  
57 private boolean isRuleEngineForCurrentTenant; 55 private boolean isRuleEngineForCurrentTenant;
58 private boolean isCore; 56 private boolean isCore;
59 57
60 private TenantActor(ActorSystemContext systemContext, TenantId tenantId) { 58 private TenantActor(ActorSystemContext systemContext, TenantId tenantId) {
61 super(systemContext, tenantId); 59 super(systemContext, tenantId);
62 - this.deviceActors = HashBiMap.create();  
63 - }  
64 -  
65 - @Override  
66 - public SupervisorStrategy supervisorStrategy() {  
67 - return strategy;  
68 } 60 }
69 61
70 boolean cantFindTenant = false; 62 boolean cantFindTenant = false;
71 63
72 @Override 64 @Override
73 - public void preStart() { 65 + public void init(TbActorCtx ctx) {
  66 + super.init(ctx);
74 log.info("[{}] Starting tenant actor.", tenantId); 67 log.info("[{}] Starting tenant actor.", tenantId);
75 try { 68 try {
76 Tenant tenant = systemContext.getTenantService().findTenantById(tenantId); 69 Tenant tenant = systemContext.getTenantService().findTenantById(tenantId);
@@ -104,12 +97,12 @@ public class TenantActor extends RuleChainManagerActor { @@ -104,12 +97,12 @@ public class TenantActor extends RuleChainManagerActor {
104 } 97 }
105 98
106 @Override 99 @Override
107 - public void postStop() { 100 + public void destroy() {
108 log.info("[{}] Stopping tenant actor.", tenantId); 101 log.info("[{}] Stopping tenant actor.", tenantId);
109 } 102 }
110 103
111 @Override 104 @Override
112 - protected boolean process(TbActorMsg msg) { 105 + protected boolean doProcess(TbActorMsg msg) {
113 if (cantFindTenant) { 106 if (cantFindTenant) {
114 log.info("[{}] Processing missing Tenant msg: {}", tenantId, msg); 107 log.info("[{}] Processing missing Tenant msg: {}", tenantId, msg);
115 if (msg.getMsgType().equals(MsgType.QUEUE_TO_RULE_ENGINE_MSG)) { 108 if (msg.getMsgType().equals(MsgType.QUEUE_TO_RULE_ENGINE_MSG)) {
@@ -126,13 +119,13 @@ public class TenantActor extends RuleChainManagerActor { @@ -126,13 +119,13 @@ public class TenantActor extends RuleChainManagerActor {
126 //To Rule Chain Actors 119 //To Rule Chain Actors
127 broadcast(msg); 120 broadcast(msg);
128 } else if (ServiceType.TB_CORE.equals(serviceType)) { 121 } else if (ServiceType.TB_CORE.equals(serviceType)) {
129 - //To Device Actors  
130 - List<DeviceId> repartitionedDevices =  
131 - deviceActors.keySet().stream().filter(deviceId -> !isMyPartition(deviceId)).collect(Collectors.toList());  
132 - for (DeviceId deviceId : repartitionedDevices) {  
133 - ActorRef deviceActor = deviceActors.remove(deviceId);  
134 - context().stop(deviceActor);  
135 - } 122 + List<TbActorId> deviceActorIds = ctx.filterChildren(new TbEntityTypeActorIdPredicate(EntityType.DEVICE) {
  123 + @Override
  124 + protected boolean testEntityId(EntityId entityId) {
  125 + return super.testEntityId(entityId) && !isMyPartition(entityId);
  126 + }
  127 + });
  128 + deviceActorIds.forEach(id -> ctx.stop(id));
136 } 129 }
137 break; 130 break;
138 case COMPONENT_LIFE_CYCLE_MSG: 131 case COMPONENT_LIFE_CYCLE_MSG:
@@ -158,8 +151,8 @@ public class TenantActor extends RuleChainManagerActor { @@ -158,8 +151,8 @@ public class TenantActor extends RuleChainManagerActor {
158 return true; 151 return true;
159 } 152 }
160 153
161 - private boolean isMyPartition(DeviceId deviceId) {  
162 - return systemContext.resolve(ServiceType.TB_CORE, tenantId, deviceId).isMyPartition(); 154 + private boolean isMyPartition(EntityId entityId) {
  155 + return systemContext.resolve(ServiceType.TB_CORE, tenantId, entityId).isMyPartition();
163 } 156 }
164 157
165 private void onQueueToRuleEngineMsg(QueueToRuleEngineMsg msg) { 158 private void onQueueToRuleEngineMsg(QueueToRuleEngineMsg msg) {
@@ -170,16 +163,15 @@ public class TenantActor extends RuleChainManagerActor { @@ -170,16 +163,15 @@ public class TenantActor extends RuleChainManagerActor {
170 TbMsg tbMsg = msg.getTbMsg(); 163 TbMsg tbMsg = msg.getTbMsg();
171 if (tbMsg.getRuleChainId() == null) { 164 if (tbMsg.getRuleChainId() == null) {
172 if (getRootChainActor() != null) { 165 if (getRootChainActor() != null) {
173 - getRootChainActor().tell(msg, self()); 166 + getRootChainActor().tell(msg);
174 } else { 167 } else {
175 tbMsg.getCallback().onFailure(new RuleEngineException("No Root Rule Chain available!")); 168 tbMsg.getCallback().onFailure(new RuleEngineException("No Root Rule Chain available!"));
176 log.info("[{}] No Root Chain: {}", tenantId, msg); 169 log.info("[{}] No Root Chain: {}", tenantId, msg);
177 } 170 }
178 } else { 171 } else {
179 - ActorRef ruleChainActor = get(tbMsg.getRuleChainId());  
180 - if (ruleChainActor != null) {  
181 - ruleChainActor.tell(msg, self());  
182 - } else { 172 + try {
  173 + ctx.tell(new TbEntityActorId(tbMsg.getRuleChainId()), msg);
  174 + } catch (TbActorNotRegisteredException ex) {
183 log.trace("Received message for non-existing rule chain: [{}]", tbMsg.getRuleChainId()); 175 log.trace("Received message for non-existing rule chain: [{}]", tbMsg.getRuleChainId());
184 //TODO: 3.1 Log it to dead letters queue; 176 //TODO: 3.1 Log it to dead letters queue;
185 tbMsg.getCallback().onSuccess(); 177 tbMsg.getCallback().onSuccess();
@@ -188,61 +180,39 @@ public class TenantActor extends RuleChainManagerActor { @@ -188,61 +180,39 @@ public class TenantActor extends RuleChainManagerActor {
188 } 180 }
189 181
190 private void onRuleChainMsg(RuleChainAwareMsg msg) { 182 private void onRuleChainMsg(RuleChainAwareMsg msg) {
191 - getOrCreateActor(context(), msg.getRuleChainId()).tell(msg, self()); 183 + getOrCreateActor(msg.getRuleChainId()).tell(msg);
192 } 184 }
193 185
194 private void onToDeviceActorMsg(DeviceAwareMsg msg) { 186 private void onToDeviceActorMsg(DeviceAwareMsg msg) {
195 if (!isCore) { 187 if (!isCore) {
196 log.warn("RECEIVED INVALID MESSAGE: {}", msg); 188 log.warn("RECEIVED INVALID MESSAGE: {}", msg);
197 } 189 }
198 - getOrCreateDeviceActor(msg.getDeviceId()).tell(msg, ActorRef.noSender()); 190 + getOrCreateDeviceActor(msg.getDeviceId()).tell(msg);
199 } 191 }
200 192
201 private void onComponentLifecycleMsg(ComponentLifecycleMsg msg) { 193 private void onComponentLifecycleMsg(ComponentLifecycleMsg msg) {
202 if (isRuleEngineForCurrentTenant) { 194 if (isRuleEngineForCurrentTenant) {
203 - ActorRef target = getEntityActorRef(msg.getEntityId()); 195 + TbActorRef target = getEntityActorRef(msg.getEntityId());
204 if (target != null) { 196 if (target != null) {
205 if (msg.getEntityId().getEntityType() == EntityType.RULE_CHAIN) { 197 if (msg.getEntityId().getEntityType() == EntityType.RULE_CHAIN) {
206 RuleChain ruleChain = systemContext.getRuleChainService(). 198 RuleChain ruleChain = systemContext.getRuleChainService().
207 findRuleChainById(tenantId, new RuleChainId(msg.getEntityId().getId())); 199 findRuleChainById(tenantId, new RuleChainId(msg.getEntityId().getId()));
208 visit(ruleChain, target); 200 visit(ruleChain, target);
209 } 201 }
210 - target.tell(msg, ActorRef.noSender()); 202 + target.tell(msg);
211 } else { 203 } else {
212 log.debug("[{}] Invalid component lifecycle msg: {}", tenantId, msg); 204 log.debug("[{}] Invalid component lifecycle msg: {}", tenantId, msg);
213 } 205 }
214 } 206 }
215 } 207 }
216 208
217 - private ActorRef getOrCreateDeviceActor(DeviceId deviceId) {  
218 - return deviceActors.computeIfAbsent(deviceId, k -> {  
219 - log.debug("[{}][{}] Creating device actor.", tenantId, deviceId);  
220 - ActorRef deviceActor = context().actorOf(Props.create(new DeviceActorCreator(systemContext, tenantId, deviceId))  
221 - .withDispatcher(DefaultActorService.CORE_DISPATCHER_NAME)  
222 - , deviceId.toString());  
223 - context().watch(deviceActor);  
224 - log.debug("[{}][{}] Created device actor: {}.", tenantId, deviceId, deviceActor);  
225 - return deviceActor;  
226 - }); 209 + private TbActorRef getOrCreateDeviceActor(DeviceId deviceId) {
  210 + return ctx.getOrCreateChildActor(new TbEntityActorId(deviceId),
  211 + () -> DefaultActorService.DEVICE_DISPATCHER_NAME,
  212 + () -> new DeviceActorCreator(systemContext, tenantId, deviceId));
227 } 213 }
228 214
229 - @Override  
230 - protected void processTermination(Terminated message) {  
231 - ActorRef terminated = message.actor();  
232 - if (terminated instanceof LocalActorRef) {  
233 - boolean removed = deviceActors.inverse().remove(terminated) != null;  
234 - if (removed) {  
235 - log.debug("[{}] Removed actor:", terminated);  
236 - } else {  
237 - log.debug("Removed actor was not found in the device map!");  
238 - }  
239 - } else {  
240 - throw new IllegalStateException("Remote actors are not supported!");  
241 - }  
242 - }  
243 -  
244 - public static class ActorCreator extends ContextBasedCreator<TenantActor> {  
245 - private static final long serialVersionUID = 1L; 215 + public static class ActorCreator extends ContextBasedCreator {
246 216
247 private final TenantId tenantId; 217 private final TenantId tenantId;
248 218
@@ -252,18 +222,14 @@ public class TenantActor extends RuleChainManagerActor { @@ -252,18 +222,14 @@ public class TenantActor extends RuleChainManagerActor {
252 } 222 }
253 223
254 @Override 224 @Override
255 - public TenantActor create() {  
256 - return new TenantActor(context, tenantId); 225 + public TbActorId createActorId() {
  226 + return new TbEntityActorId(tenantId);
257 } 227 }
258 - }  
259 228
260 - private final SupervisorStrategy strategy = new OneForOneStrategy(3, Duration.create("1 minute"), t -> {  
261 - log.warn("[{}] Unknown failure", tenantId, t);  
262 - if (t instanceof ActorInitializationException) {  
263 - return SupervisorStrategy.stop();  
264 - } else {  
265 - return SupervisorStrategy.resume(); 229 + @Override
  230 + public TbActor createActor() {
  231 + return new TenantActor(context, tenantId);
266 } 232 }
267 - }); 233 + }
268 234
269 } 235 }
@@ -15,7 +15,6 @@ @@ -15,7 +15,6 @@
15 */ 15 */
16 package org.thingsboard.server.service.queue; 16 package org.thingsboard.server.service.queue;
17 17
18 -import akka.actor.ActorRef;  
19 import lombok.extern.slf4j.Slf4j; 18 import lombok.extern.slf4j.Slf4j;
20 import org.springframework.beans.factory.annotation.Value; 19 import org.springframework.beans.factory.annotation.Value;
21 import org.springframework.scheduling.annotation.Scheduled; 20 import org.springframework.scheduling.annotation.Scheduled;
@@ -150,7 +149,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore @@ -150,7 +149,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore
150 tbCoreDeviceRpcService.forwardRpcRequestToDeviceActor((ToDeviceRpcRequestActorMsg) tbActorMsg); 149 tbCoreDeviceRpcService.forwardRpcRequestToDeviceActor((ToDeviceRpcRequestActorMsg) tbActorMsg);
151 } else { 150 } else {
152 log.trace("[{}] Forwarding message to App Actor {}", id, actorMsg.get()); 151 log.trace("[{}] Forwarding message to App Actor {}", id, actorMsg.get());
153 - actorContext.tell(actorMsg.get(), ActorRef.noSender()); 152 + actorContext.tell(actorMsg.get());
154 } 153 }
155 } 154 }
156 callback.onSuccess(); 155 callback.onSuccess();
@@ -208,7 +207,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore @@ -208,7 +207,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore
208 Optional<TbActorMsg> actorMsg = encodingService.decode(toCoreNotification.getComponentLifecycleMsg().toByteArray()); 207 Optional<TbActorMsg> actorMsg = encodingService.decode(toCoreNotification.getComponentLifecycleMsg().toByteArray());
209 if (actorMsg.isPresent()) { 208 if (actorMsg.isPresent()) {
210 log.trace("[{}] Forwarding message to App Actor {}", id, actorMsg.get()); 209 log.trace("[{}] Forwarding message to App Actor {}", id, actorMsg.get());
211 - actorContext.tell(actorMsg.get(), ActorRef.noSender()); 210 + actorContext.tell(actorMsg.get());
212 } 211 }
213 callback.onSuccess(); 212 callback.onSuccess();
214 } 213 }
@@ -279,7 +278,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore @@ -279,7 +278,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore
279 if (statsEnabled) { 278 if (statsEnabled) {
280 stats.log(toDeviceActorMsg); 279 stats.log(toDeviceActorMsg);
281 } 280 }
282 - actorContext.tell(new TransportToDeviceActorMsgWrapper(toDeviceActorMsg, callback), ActorRef.noSender()); 281 + actorContext.tell(new TransportToDeviceActorMsgWrapper(toDeviceActorMsg, callback));
283 } 282 }
284 283
285 private void throwNotHandled(Object msg, TbCallback callback) { 284 private void throwNotHandled(Object msg, TbCallback callback) {
@@ -15,7 +15,6 @@ @@ -15,7 +15,6 @@
15 */ 15 */
16 package org.thingsboard.server.service.queue; 16 package org.thingsboard.server.service.queue;
17 17
18 -import akka.actor.ActorRef;  
19 import com.google.protobuf.ProtocolStringList; 18 import com.google.protobuf.ProtocolStringList;
20 import lombok.extern.slf4j.Slf4j; 19 import lombok.extern.slf4j.Slf4j;
21 import org.springframework.beans.factory.annotation.Value; 20 import org.springframework.beans.factory.annotation.Value;
@@ -51,7 +50,6 @@ import org.thingsboard.server.service.queue.processing.TbRuleEngineProcessingStr @@ -51,7 +50,6 @@ import org.thingsboard.server.service.queue.processing.TbRuleEngineProcessingStr
51 import org.thingsboard.server.service.queue.processing.TbRuleEngineSubmitStrategy; 50 import org.thingsboard.server.service.queue.processing.TbRuleEngineSubmitStrategy;
52 import org.thingsboard.server.service.queue.processing.TbRuleEngineSubmitStrategyFactory; 51 import org.thingsboard.server.service.queue.processing.TbRuleEngineSubmitStrategyFactory;
53 import org.thingsboard.server.service.rpc.FromDeviceRpcResponse; 52 import org.thingsboard.server.service.rpc.FromDeviceRpcResponse;
54 -import org.thingsboard.server.service.rpc.TbCoreDeviceRpcService;  
55 import org.thingsboard.server.service.rpc.TbRuleEngineDeviceRpcService; 53 import org.thingsboard.server.service.rpc.TbRuleEngineDeviceRpcService;
56 import org.thingsboard.server.service.stats.RuleEngineStatisticsService; 54 import org.thingsboard.server.service.stats.RuleEngineStatisticsService;
57 55
@@ -232,7 +230,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< @@ -232,7 +230,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService<
232 Optional<TbActorMsg> actorMsg = encodingService.decode(nfMsg.getComponentLifecycleMsg().toByteArray()); 230 Optional<TbActorMsg> actorMsg = encodingService.decode(nfMsg.getComponentLifecycleMsg().toByteArray());
233 if (actorMsg.isPresent()) { 231 if (actorMsg.isPresent()) {
234 log.trace("[{}] Forwarding message to App Actor {}", id, actorMsg.get()); 232 log.trace("[{}] Forwarding message to App Actor {}", id, actorMsg.get());
235 - actorContext.tell(actorMsg.get(), ActorRef.noSender()); 233 + actorContext.tell(actorMsg.get());
236 } 234 }
237 callback.onSuccess(); 235 callback.onSuccess();
238 } else if (nfMsg.hasFromDeviceRpcResponse()) { 236 } else if (nfMsg.hasFromDeviceRpcResponse()) {
@@ -261,7 +259,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< @@ -261,7 +259,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService<
261 } 259 }
262 } 260 }
263 msg = new QueueToRuleEngineMsg(tenantId, tbMsg, relationTypes, toRuleEngineMsg.getFailureMessage()); 261 msg = new QueueToRuleEngineMsg(tenantId, tbMsg, relationTypes, toRuleEngineMsg.getFailureMessage());
264 - actorContext.tell(msg, ActorRef.noSender()); 262 + actorContext.tell(msg);
265 } 263 }
266 264
267 @Scheduled(fixedDelayString = "${queue.rule-engine.stats.print-interval-ms}") 265 @Scheduled(fixedDelayString = "${queue.rule-engine.stats.print-interval-ms}")
@@ -15,7 +15,6 @@ @@ -15,7 +15,6 @@
15 */ 15 */
16 package org.thingsboard.server.service.rpc; 16 package org.thingsboard.server.service.rpc;
17 17
18 -import akka.actor.ActorRef;  
19 import com.fasterxml.jackson.core.JsonProcessingException; 18 import com.fasterxml.jackson.core.JsonProcessingException;
20 import com.fasterxml.jackson.databind.ObjectMapper; 19 import com.fasterxml.jackson.databind.ObjectMapper;
21 import com.fasterxml.jackson.databind.node.ObjectNode; 20 import com.fasterxml.jackson.databind.node.ObjectNode;
@@ -122,7 +121,7 @@ public class DefaultTbCoreDeviceRpcService implements TbCoreDeviceRpcService { @@ -122,7 +121,7 @@ public class DefaultTbCoreDeviceRpcService implements TbCoreDeviceRpcService {
122 log.trace("[{}][{}] Processing local rpc call to device actor [{}]", request.getTenantId(), request.getId(), request.getDeviceId()); 121 log.trace("[{}][{}] Processing local rpc call to device actor [{}]", request.getTenantId(), request.getId(), request.getDeviceId());
123 UUID requestId = request.getId(); 122 UUID requestId = request.getId();
124 localToDeviceRpcRequests.put(requestId, rpcMsg); 123 localToDeviceRpcRequests.put(requestId, rpcMsg);
125 - actorContext.tell(rpcMsg, ActorRef.noSender()); 124 + actorContext.tell(rpcMsg);
126 scheduleToDeviceTimeout(request, requestId); 125 scheduleToDeviceTimeout(request, requestId);
127 } 126 }
128 127
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 -  
17 -  
18 -akka {  
19 - # JVM shutdown, System.exit(-1), in case of a fatal error,  
20 - # such as OutOfMemoryError  
21 - jvm-exit-on-fatal-error = off  
22 - loglevel = "INFO"  
23 - loggers = ["akka.event.slf4j.Slf4jLogger"]  
24 -}  
25 -  
26 -# This dispatcher is used for app  
27 -app-dispatcher {  
28 - type = Dispatcher  
29 - executor = "fork-join-executor"  
30 - fork-join-executor {  
31 - # Min number of threads to cap factor-based parallelism number to  
32 - parallelism-min = 1  
33 - # Max number of threads to cap factor-based parallelism number to  
34 - parallelism-max = 1  
35 -  
36 - # The parallelism factor is used to determine thread pool size using the  
37 - # following formula: ceil(available processors * factor). Resulting size  
38 - # is then bounded by the parallelism-min and parallelism-max values.  
39 - parallelism-factor = 1.0  
40 - }  
41 - # How long time the dispatcher will wait for new actors until it shuts down  
42 - shutdown-timeout = 1s  
43 -  
44 - # Throughput defines the number of messages that are processed in a batch  
45 - # before the thread is returned to the pool. Set to 1 for as fair as possible.  
46 - throughput = 5  
47 -}  
48 -  
49 -# This dispatcher is used for rpc actors  
50 -rpc-dispatcher {  
51 - type = Dispatcher  
52 - executor = "fork-join-executor"  
53 - fork-join-executor {  
54 - # Min number of threads to cap factor-based parallelism number to  
55 - parallelism-min = 2  
56 - # Max number of threads to cap factor-based parallelism number to  
57 - parallelism-max = 8  
58 -  
59 - # The parallelism factor is used to determine thread pool size using the  
60 - # following formula: ceil(available processors * factor). Resulting size  
61 - # is then bounded by the parallelism-min and parallelism-max values.  
62 - parallelism-factor = 0.5  
63 - }  
64 - # How long time the dispatcher will wait for new actors until it shuts down  
65 - shutdown-timeout = 1s  
66 -  
67 - # Throughput defines the number of messages that are processed in a batch  
68 - # before the thread is returned to the pool. Set to 1 for as fair as possible.  
69 - throughput = 5  
70 -}  
71 -  
72 -# This dispatcher is used for auth  
73 -core-dispatcher {  
74 - type = Dispatcher  
75 - executor = "fork-join-executor"  
76 - fork-join-executor {  
77 - # Min number of threads to cap factor-based parallelism number to  
78 - parallelism-min = 2  
79 - # Max number of threads to cap factor-based parallelism number to  
80 - parallelism-max = 12  
81 -  
82 - # The parallelism factor is used to determine thread pool size using the  
83 - # following formula: ceil(available processors * factor). Resulting size  
84 - # is then bounded by the parallelism-min and parallelism-max values.  
85 - parallelism-factor = 0.25  
86 - }  
87 - # How long time the dispatcher will wait for new actors until it shuts down  
88 - shutdown-timeout = 1s  
89 -  
90 - # Throughput defines the number of messages that are processed in a batch  
91 - # before the thread is returned to the pool. Set to 1 for as fair as possible.  
92 - throughput = 5  
93 -}  
94 -  
95 -# This dispatcher is used for system rule chains and rule node actors  
96 -system-rule-dispatcher {  
97 - type = Dispatcher  
98 - executor = "fork-join-executor"  
99 - fork-join-executor {  
100 - # Min number of threads to cap factor-based parallelism number to  
101 - parallelism-min = 2  
102 - # Max number of threads to cap factor-based parallelism number to  
103 - parallelism-max = 12  
104 -  
105 - # The parallelism factor is used to determine thread pool size using the  
106 - # following formula: ceil(available processors * factor). Resulting size  
107 - # is then bounded by the parallelism-min and parallelism-max values.  
108 - parallelism-factor = 0.25  
109 - }  
110 - # How long time the dispatcher will wait for new actors until it shuts down  
111 - shutdown-timeout = 1s  
112 -  
113 - # Throughput defines the number of messages that are processed in a batch  
114 - # before the thread is returned to the pool. Set to 1 for as fair as possible.  
115 - throughput = 5  
116 -}  
117 -  
118 -# This dispatcher is used for tenant rule chains and rule node actors  
119 -rule-dispatcher {  
120 - type = Dispatcher  
121 - executor = "fork-join-executor"  
122 - fork-join-executor {  
123 - # Min number of threads to cap factor-based parallelism number to  
124 - parallelism-min = 2  
125 - # Max number of threads to cap factor-based parallelism number to  
126 - parallelism-max = 12  
127 -  
128 - # The parallelism factor is used to determine thread pool size using the  
129 - # following formula: ceil(available processors * factor). Resulting size  
130 - # is then bounded by the parallelism-min and parallelism-max values.  
131 - parallelism-factor = 0.25  
132 - }  
133 - # How long time the dispatcher will wait for new actors until it shuts down  
134 - shutdown-timeout = 1s  
135 -  
136 - # Throughput defines the number of messages that are processed in a batch  
137 - # before the thread is returned to the pool. Set to 1 for as fair as possible.  
138 - throughput = 5  
139 -}  
@@ -281,6 +281,14 @@ sql: @@ -281,6 +281,14 @@ sql:
281 281
282 # Actor system parameters 282 # Actor system parameters
283 actors: 283 actors:
  284 + system:
  285 + throughput: "${ACTORS_SYSTEM_THROUGHPUT:5}"
  286 + scheduler_pool_size: "${ACTORS_SYSTEM_SCHEDULER_POOL_SIZE:1}"
  287 + max_actor_init_attempts: "${ACTORS_SYSTEM_MAX_ACTOR_INIT_ATTEMPTS:10}"
  288 + app_dispatcher_pool_size: "${ACTORS_SYSTEM_APP_DISPATCHER_POOL_SIZE:1}"
  289 + tenant_dispatcher_pool_size: "${ACTORS_SYSTEM_TENANT_DISPATCHER_POOL_SIZE:2}"
  290 + device_dispatcher_pool_size: "${ACTORS_SYSTEM_DEVICE_DISPATCHER_POOL_SIZE:4}"
  291 + rule_dispatcher_pool_size: "${ACTORS_SYSTEM_RULE_DISPATCHER_POOL_SIZE:4}"
284 tenant: 292 tenant:
285 create_components_on_init: "${ACTORS_TENANT_CREATE_COMPONENTS_ON_INIT:true}" 293 create_components_on_init: "${ACTORS_TENANT_CREATE_COMPONENTS_ON_INIT:true}"
286 session: 294 session:
@@ -318,11 +326,6 @@ actors: @@ -318,11 +326,6 @@ actors:
318 enabled: "${ACTORS_STATISTICS_ENABLED:true}" 326 enabled: "${ACTORS_STATISTICS_ENABLED:true}"
319 js_print_interval_ms: "${ACTORS_JS_STATISTICS_PRINT_INTERVAL_MS:10000}" 327 js_print_interval_ms: "${ACTORS_JS_STATISTICS_PRINT_INTERVAL_MS:10000}"
320 persist_frequency: "${ACTORS_STATISTICS_PERSIST_FREQUENCY:3600000}" 328 persist_frequency: "${ACTORS_STATISTICS_PERSIST_FREQUENCY:3600000}"
321 - queue:  
322 - # Enable/disable persistence of un-processed messages to the queue  
323 - enabled: "${ACTORS_QUEUE_ENABLED:true}"  
324 - # Maximum allowed timeout for persistence into the queue  
325 - timeout: "${ACTORS_QUEUE_PERSISTENCE_TIMEOUT:30000}"  
326 329
327 cache: 330 cache:
328 # caffeine or redis 331 # caffeine or redis
@@ -15,8 +15,6 @@ @@ -15,8 +15,6 @@
15 */ 15 */
16 package org.thingsboard.server.rules.flow; 16 package org.thingsboard.server.rules.flow;
17 17
18 -import akka.actor.ActorRef;  
19 -import com.datastax.driver.core.utils.UUIDs;  
20 import lombok.extern.slf4j.Slf4j; 18 import lombok.extern.slf4j.Slf4j;
21 import org.junit.After; 19 import org.junit.After;
22 import org.junit.Assert; 20 import org.junit.Assert;
@@ -26,7 +24,6 @@ import org.mockito.Mockito; @@ -26,7 +24,6 @@ import org.mockito.Mockito;
26 import org.springframework.beans.factory.annotation.Autowired; 24 import org.springframework.beans.factory.annotation.Autowired;
27 import org.thingsboard.rule.engine.metadata.TbGetAttributesNodeConfiguration; 25 import org.thingsboard.rule.engine.metadata.TbGetAttributesNodeConfiguration;
28 import org.thingsboard.server.actors.ActorSystemContext; 26 import org.thingsboard.server.actors.ActorSystemContext;
29 -import org.thingsboard.server.actors.service.ActorService;  
30 import org.thingsboard.server.common.data.*; 27 import org.thingsboard.server.common.data.*;
31 import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; 28 import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry;
32 import org.thingsboard.server.common.data.kv.StringDataEntry; 29 import org.thingsboard.server.common.data.kv.StringDataEntry;
@@ -36,7 +33,6 @@ import org.thingsboard.server.common.data.rule.RuleChainMetaData; @@ -36,7 +33,6 @@ import org.thingsboard.server.common.data.rule.RuleChainMetaData;
36 import org.thingsboard.server.common.data.rule.RuleNode; 33 import org.thingsboard.server.common.data.rule.RuleNode;
37 import org.thingsboard.server.common.data.security.Authority; 34 import org.thingsboard.server.common.data.security.Authority;
38 import org.thingsboard.server.common.msg.TbMsg; 35 import org.thingsboard.server.common.msg.TbMsg;
39 -import org.thingsboard.server.common.msg.TbMsgDataType;  
40 import org.thingsboard.server.common.msg.TbMsgMetaData; 36 import org.thingsboard.server.common.msg.TbMsgMetaData;
41 import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg; 37 import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg;
42 import org.thingsboard.server.common.msg.queue.TbMsgCallback; 38 import org.thingsboard.server.common.msg.queue.TbMsgCallback;
@@ -151,7 +147,7 @@ public abstract class AbstractRuleEngineFlowIntegrationTest extends AbstractRule @@ -151,7 +147,7 @@ public abstract class AbstractRuleEngineFlowIntegrationTest extends AbstractRule
151 TbMsg tbMsg = TbMsg.newMsg("CUSTOM", device.getId(), new TbMsgMetaData(), "{}", tbMsgCallback); 147 TbMsg tbMsg = TbMsg.newMsg("CUSTOM", device.getId(), new TbMsgMetaData(), "{}", tbMsgCallback);
152 QueueToRuleEngineMsg qMsg = new QueueToRuleEngineMsg(savedTenant.getId(), tbMsg, null, null); 148 QueueToRuleEngineMsg qMsg = new QueueToRuleEngineMsg(savedTenant.getId(), tbMsg, null, null);
153 // Pushing Message to the system 149 // Pushing Message to the system
154 - actorSystem.tell(qMsg, ActorRef.noSender()); 150 + actorSystem.tell(qMsg);
155 Mockito.verify(tbMsgCallback, Mockito.timeout(10000)).onSuccess(); 151 Mockito.verify(tbMsgCallback, Mockito.timeout(10000)).onSuccess();
156 152
157 TimePageData<Event> eventsPage = getDebugEvents(savedTenant.getId(), ruleChain.getFirstRuleNodeId(), 1000); 153 TimePageData<Event> eventsPage = getDebugEvents(savedTenant.getId(), ruleChain.getFirstRuleNodeId(), 1000);
@@ -263,7 +259,7 @@ public abstract class AbstractRuleEngineFlowIntegrationTest extends AbstractRule @@ -263,7 +259,7 @@ public abstract class AbstractRuleEngineFlowIntegrationTest extends AbstractRule
263 TbMsg tbMsg = TbMsg.newMsg("CUSTOM", device.getId(), new TbMsgMetaData(), "{}", tbMsgCallback); 259 TbMsg tbMsg = TbMsg.newMsg("CUSTOM", device.getId(), new TbMsgMetaData(), "{}", tbMsgCallback);
264 QueueToRuleEngineMsg qMsg = new QueueToRuleEngineMsg(savedTenant.getId(), tbMsg, null, null); 260 QueueToRuleEngineMsg qMsg = new QueueToRuleEngineMsg(savedTenant.getId(), tbMsg, null, null);
265 // Pushing Message to the system 261 // Pushing Message to the system
266 - actorSystem.tell(qMsg, ActorRef.noSender()); 262 + actorSystem.tell(qMsg);
267 263
268 Mockito.verify(tbMsgCallback, Mockito.timeout(10000)).onSuccess(); 264 Mockito.verify(tbMsgCallback, Mockito.timeout(10000)).onSuccess();
269 265
@@ -15,8 +15,6 @@ @@ -15,8 +15,6 @@
15 */ 15 */
16 package org.thingsboard.server.rules.lifecycle; 16 package org.thingsboard.server.rules.lifecycle;
17 17
18 -import akka.actor.ActorRef;  
19 -import com.datastax.driver.core.utils.UUIDs;  
20 import lombok.extern.slf4j.Slf4j; 18 import lombok.extern.slf4j.Slf4j;
21 import org.junit.After; 19 import org.junit.After;
22 import org.junit.Assert; 20 import org.junit.Assert;
@@ -26,7 +24,6 @@ import org.mockito.Mockito; @@ -26,7 +24,6 @@ import org.mockito.Mockito;
26 import org.springframework.beans.factory.annotation.Autowired; 24 import org.springframework.beans.factory.annotation.Autowired;
27 import org.thingsboard.rule.engine.metadata.TbGetAttributesNodeConfiguration; 25 import org.thingsboard.rule.engine.metadata.TbGetAttributesNodeConfiguration;
28 import org.thingsboard.server.actors.ActorSystemContext; 26 import org.thingsboard.server.actors.ActorSystemContext;
29 -import org.thingsboard.server.actors.service.ActorService;  
30 import org.thingsboard.server.common.data.DataConstants; 27 import org.thingsboard.server.common.data.DataConstants;
31 import org.thingsboard.server.common.data.Device; 28 import org.thingsboard.server.common.data.Device;
32 import org.thingsboard.server.common.data.Event; 29 import org.thingsboard.server.common.data.Event;
@@ -40,7 +37,6 @@ import org.thingsboard.server.common.data.rule.RuleChainMetaData; @@ -40,7 +37,6 @@ import org.thingsboard.server.common.data.rule.RuleChainMetaData;
40 import org.thingsboard.server.common.data.rule.RuleNode; 37 import org.thingsboard.server.common.data.rule.RuleNode;
41 import org.thingsboard.server.common.data.security.Authority; 38 import org.thingsboard.server.common.data.security.Authority;
42 import org.thingsboard.server.common.msg.TbMsg; 39 import org.thingsboard.server.common.msg.TbMsg;
43 -import org.thingsboard.server.common.msg.TbMsgDataType;  
44 import org.thingsboard.server.common.msg.TbMsgMetaData; 40 import org.thingsboard.server.common.msg.TbMsgMetaData;
45 import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg; 41 import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg;
46 import org.thingsboard.server.common.msg.queue.TbMsgCallback; 42 import org.thingsboard.server.common.msg.queue.TbMsgCallback;
@@ -142,7 +138,7 @@ public abstract class AbstractRuleEngineLifecycleIntegrationTest extends Abstrac @@ -142,7 +138,7 @@ public abstract class AbstractRuleEngineLifecycleIntegrationTest extends Abstrac
142 TbMsg tbMsg = TbMsg.newMsg("CUSTOM", device.getId(), new TbMsgMetaData(), "{}", tbMsgCallback); 138 TbMsg tbMsg = TbMsg.newMsg("CUSTOM", device.getId(), new TbMsgMetaData(), "{}", tbMsgCallback);
143 QueueToRuleEngineMsg qMsg = new QueueToRuleEngineMsg(savedTenant.getId(), tbMsg, null, null); 139 QueueToRuleEngineMsg qMsg = new QueueToRuleEngineMsg(savedTenant.getId(), tbMsg, null, null);
144 // Pushing Message to the system 140 // Pushing Message to the system
145 - actorSystem.tell(qMsg, ActorRef.noSender()); 141 + actorSystem.tell(qMsg);
146 Mockito.verify(tbMsgCallback, Mockito.timeout(3000)).onSuccess(); 142 Mockito.verify(tbMsgCallback, Mockito.timeout(3000)).onSuccess();
147 143
148 144
  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;
  17 +
  18 +import lombok.Getter;
  19 +
  20 +public abstract class AbstractTbActor implements TbActor {
  21 +
  22 + @Getter
  23 + protected TbActorCtx ctx;
  24 +
  25 + @Override
  26 + public void init(TbActorCtx ctx) {
  27 + this.ctx = ctx;
  28 + }
  29 +
  30 + @Override
  31 + public TbActorRef getActorRef() {
  32 + return ctx;
  33 + }
  34 +}
@@ -21,13 +21,19 @@ import lombok.extern.slf4j.Slf4j; @@ -21,13 +21,19 @@ import lombok.extern.slf4j.Slf4j;
21 import org.thingsboard.common.util.ThingsBoardThreadFactory; 21 import org.thingsboard.common.util.ThingsBoardThreadFactory;
22 import org.thingsboard.server.common.msg.TbActorMsg; 22 import org.thingsboard.server.common.msg.TbActorMsg;
23 23
  24 +import java.util.Collections;
  25 +import java.util.List;
  26 +import java.util.Set;
24 import java.util.concurrent.ConcurrentHashMap; 27 import java.util.concurrent.ConcurrentHashMap;
25 import java.util.concurrent.ConcurrentMap; 28 import java.util.concurrent.ConcurrentMap;
26 import java.util.concurrent.ExecutorService; 29 import java.util.concurrent.ExecutorService;
27 import java.util.concurrent.Executors; 30 import java.util.concurrent.Executors;
28 import java.util.concurrent.ScheduledExecutorService; 31 import java.util.concurrent.ScheduledExecutorService;
  32 +import java.util.concurrent.TimeUnit;
29 import java.util.concurrent.locks.Lock; 33 import java.util.concurrent.locks.Lock;
30 import java.util.concurrent.locks.ReentrantLock; 34 import java.util.concurrent.locks.ReentrantLock;
  35 +import java.util.function.Predicate;
  36 +import java.util.stream.Collectors;
31 37
32 @Slf4j 38 @Slf4j
33 @Data 39 @Data
@@ -36,6 +42,8 @@ public class DefaultTbActorSystem implements TbActorSystem { @@ -36,6 +42,8 @@ public class DefaultTbActorSystem implements TbActorSystem {
36 private final ConcurrentMap<String, Dispatcher> dispatchers = new ConcurrentHashMap<>(); 42 private final ConcurrentMap<String, Dispatcher> dispatchers = new ConcurrentHashMap<>();
37 private final ConcurrentMap<TbActorId, TbActorMailbox> actors = new ConcurrentHashMap<>(); 43 private final ConcurrentMap<TbActorId, TbActorMailbox> actors = new ConcurrentHashMap<>();
38 private final ConcurrentMap<TbActorId, ReentrantLock> actorCreationLocks = new ConcurrentHashMap<>(); 44 private final ConcurrentMap<TbActorId, ReentrantLock> actorCreationLocks = new ConcurrentHashMap<>();
  45 + private final ConcurrentMap<TbActorId, Set<TbActorId>> parentChildMap = new ConcurrentHashMap<>();
  46 +
39 @Getter 47 @Getter
40 private final TbActorSystemSettings settings; 48 private final TbActorSystemSettings settings;
41 @Getter 49 @Getter
@@ -65,16 +73,21 @@ public class DefaultTbActorSystem implements TbActorSystem { @@ -65,16 +73,21 @@ public class DefaultTbActorSystem implements TbActorSystem {
65 } 73 }
66 74
67 @Override 75 @Override
68 - public TbActorId createRootActor(String dispatcherId, TbActorCreator creator) { 76 + public TbActorRef getActor(TbActorId actorId) {
  77 + return actors.get(actorId);
  78 + }
  79 +
  80 + @Override
  81 + public TbActorRef createRootActor(String dispatcherId, TbActorCreator creator) {
69 return createActor(dispatcherId, creator, null); 82 return createActor(dispatcherId, creator, null);
70 } 83 }
71 84
72 @Override 85 @Override
73 - public TbActorId createChildActor(String dispatcherId, TbActorCreator creator, TbActorId parent) { 86 + public TbActorRef createChildActor(String dispatcherId, TbActorCreator creator, TbActorId parent) {
74 return createActor(dispatcherId, creator, parent); 87 return createActor(dispatcherId, creator, parent);
75 } 88 }
76 89
77 - private TbActorId createActor(String dispatcherId, TbActorCreator creator, TbActorId parent) { 90 + private TbActorRef createActor(String dispatcherId, TbActorCreator creator, TbActorId parent) {
78 Dispatcher dispatcher = dispatchers.get(dispatcherId); 91 Dispatcher dispatcher = dispatchers.get(dispatcherId);
79 if (dispatcher == null) { 92 if (dispatcher == null) {
80 log.warn("Dispatcher with id [{}] is not registered!", dispatcherId); 93 log.warn("Dispatcher with id [{}] is not registered!", dispatcherId);
@@ -93,9 +106,20 @@ public class DefaultTbActorSystem implements TbActorSystem { @@ -93,9 +106,20 @@ public class DefaultTbActorSystem implements TbActorSystem {
93 if (actorMailbox == null) { 106 if (actorMailbox == null) {
94 log.debug("Creating actor with id [{}]!", actorId); 107 log.debug("Creating actor with id [{}]!", actorId);
95 TbActor actor = creator.createActor(); 108 TbActor actor = creator.createActor();
96 - TbActorMailbox mailbox = new TbActorMailbox(this, settings, actorId, parent, actor, dispatcher); 109 + TbActorRef parentRef = null;
  110 + if (parent != null) {
  111 + parentRef = getActor(parent);
  112 + if (parentRef == null) {
  113 + throw new TbActorNotRegisteredException(parent, "Parent Actor with id [" + parent + "] is not registered!");
  114 + }
  115 + }
  116 + TbActorMailbox mailbox = new TbActorMailbox(this, settings, actorId, parentRef, actor, dispatcher);
97 actors.put(actorId, mailbox); 117 actors.put(actorId, mailbox);
98 mailbox.initActor(); 118 mailbox.initActor();
  119 + actorMailbox = mailbox;
  120 + if (parent != null) {
  121 + parentChildMap.computeIfAbsent(parent, id -> ConcurrentHashMap.newKeySet()).add(actorId);
  122 + }
99 } else { 123 } else {
100 log.debug("Actor with id [{}] is already registered!", actorId); 124 log.debug("Actor with id [{}] is already registered!", actorId);
101 } 125 }
@@ -104,7 +128,12 @@ public class DefaultTbActorSystem implements TbActorSystem { @@ -104,7 +128,12 @@ public class DefaultTbActorSystem implements TbActorSystem {
104 actorCreationLocks.remove(actorId); 128 actorCreationLocks.remove(actorId);
105 } 129 }
106 } 130 }
107 - return actorId; 131 + return actorMailbox;
  132 + }
  133 +
  134 + @Override
  135 + public void tell(TbActorRef target, TbActorMsg actorMsg) {
  136 + target.tell(actorMsg);
108 } 137 }
109 138
110 @Override 139 @Override
@@ -117,7 +146,41 @@ public class DefaultTbActorSystem implements TbActorSystem { @@ -117,7 +146,41 @@ public class DefaultTbActorSystem implements TbActorSystem {
117 } 146 }
118 147
119 @Override 148 @Override
  149 + public void broadcastToChildren(TbActorId parent, TbActorMsg msg) {
  150 + broadcastToChildren(parent, id -> true, msg);
  151 + }
  152 +
  153 + @Override
  154 + public void broadcastToChildren(TbActorId parent, Predicate<TbActorId> childFilter, TbActorMsg msg) {
  155 + Set<TbActorId> children = parentChildMap.get(parent);
  156 + if (children != null) {
  157 + children.stream().filter(childFilter).forEach(id -> tell(id, msg));
  158 + }
  159 + }
  160 +
  161 + @Override
  162 + public List<TbActorId> filterChildren(TbActorId parent, Predicate<TbActorId> childFilter) {
  163 + Set<TbActorId> children = parentChildMap.get(parent);
  164 + if (children != null) {
  165 + return children.stream().filter(childFilter).collect(Collectors.toList());
  166 + } else {
  167 + return Collections.emptyList();
  168 + }
  169 + }
  170 +
  171 + @Override
  172 + public void stop(TbActorRef actorRef) {
  173 + stop(actorRef.getActorId());
  174 + }
  175 +
  176 + @Override
120 public void stop(TbActorId actorId) { 177 public void stop(TbActorId actorId) {
  178 + Set<TbActorId> children = parentChildMap.remove(actorId);
  179 + if (children != null) {
  180 + for (TbActorId child : children) {
  181 + stop(child);
  182 + }
  183 + }
121 TbActorMailbox mailbox = actors.remove(actorId); 184 TbActorMailbox mailbox = actors.remove(actorId);
122 if (mailbox != null) { 185 if (mailbox != null) {
123 mailbox.destroy(); 186 mailbox.destroy();
@@ -126,7 +189,17 @@ public class DefaultTbActorSystem implements TbActorSystem { @@ -126,7 +189,17 @@ public class DefaultTbActorSystem implements TbActorSystem {
126 189
127 @Override 190 @Override
128 public void stop() { 191 public void stop() {
129 - dispatchers.values().forEach(dispatcher -> dispatcher.getExecutor().shutdownNow()); 192 + dispatchers.values().forEach(dispatcher -> {
  193 + dispatcher.getExecutor().shutdown();
  194 + try {
  195 + dispatcher.getExecutor().awaitTermination(3, TimeUnit.SECONDS);
  196 + } catch (InterruptedException e) {
  197 + log.warn("[{}] Failed to stop dispatcher", dispatcher.getDispatcherId(), e);
  198 + }
  199 + });
  200 + if (scheduler != null) {
  201 + scheduler.shutdownNow();
  202 + }
130 actors.clear(); 203 actors.clear();
131 } 204 }
132 205
@@ -19,11 +19,15 @@ import org.thingsboard.server.common.msg.TbActorMsg; @@ -19,11 +19,15 @@ import org.thingsboard.server.common.msg.TbActorMsg;
19 19
20 public interface TbActor { 20 public interface TbActor {
21 21
22 - void init(); 22 + boolean process(TbActorMsg msg);
23 23
24 - boolean process(TbActorCtx ctx, TbActorMsg msg); 24 + TbActorRef getActorRef();
25 25
26 - void destroy(); 26 + default void init(TbActorCtx ctx) {
  27 + }
  28 +
  29 + default void destroy() {
  30 + }
27 31
28 default InitFailureStrategy onInitFailure(int attempt, Throwable t) { 32 default InitFailureStrategy onInitFailure(int attempt, Throwable t) {
29 return InitFailureStrategy.retryWithDelay(5000); 33 return InitFailureStrategy.retryWithDelay(5000);
@@ -17,12 +17,25 @@ package org.thingsboard.server.actors; @@ -17,12 +17,25 @@ package org.thingsboard.server.actors;
17 17
18 import org.thingsboard.server.common.msg.TbActorMsg; 18 import org.thingsboard.server.common.msg.TbActorMsg;
19 19
20 -public interface TbActorCtx { 20 +import java.util.List;
  21 +import java.util.function.Predicate;
  22 +import java.util.function.Supplier;
  23 +
  24 +public interface TbActorCtx extends TbActorRef {
21 25
22 TbActorId getSelf(); 26 TbActorId getSelf();
23 27
24 - TbActorId getParent(); 28 + TbActorRef getParentRef();
  29 +
  30 + void tell(TbActorId target, TbActorMsg msg);
  31 +
  32 + void stop(TbActorId target);
  33 +
  34 + TbActorRef getOrCreateChildActor(TbActorId actorId, Supplier<String> dispatcher, Supplier<TbActorCreator> creator);
  35 +
  36 + void broadcastToChildren(TbActorMsg msg);
25 37
26 - void tell(TbActorId target, TbActorMsg actorMsg); 38 + void broadcastToChildren(TbActorMsg msg, Predicate<TbActorId> childFilter);
27 39
  40 + List<TbActorId> filterChildren(Predicate<TbActorId> childFilter);
28 } 41 }
@@ -15,33 +15,6 @@ @@ -15,33 +15,6 @@
15 */ 15 */
16 package org.thingsboard.server.actors; 16 package org.thingsboard.server.actors;
17 17
18 -import org.thingsboard.server.common.data.id.EntityId; 18 +public interface TbActorId {
19 19
20 -import java.util.Objects;  
21 -  
22 -public class TbActorId {  
23 -  
24 - private final EntityId entityId;  
25 -  
26 - public TbActorId(EntityId entityId) {  
27 - this.entityId = entityId;  
28 - }  
29 -  
30 - @Override  
31 - public String toString() {  
32 - return entityId.toString();  
33 - }  
34 -  
35 - @Override  
36 - public boolean equals(Object o) {  
37 - if (this == o) return true;  
38 - if (o == null || getClass() != o.getClass()) return false;  
39 - TbActorId actorId = (TbActorId) o;  
40 - return entityId.equals(actorId.entityId);  
41 - }  
42 -  
43 - @Override  
44 - public int hashCode() {  
45 - return Objects.hash(entityId);  
46 - }  
47 } 20 }
@@ -19,9 +19,12 @@ import lombok.Data; @@ -19,9 +19,12 @@ import lombok.Data;
19 import lombok.extern.slf4j.Slf4j; 19 import lombok.extern.slf4j.Slf4j;
20 import org.thingsboard.server.common.msg.TbActorMsg; 20 import org.thingsboard.server.common.msg.TbActorMsg;
21 21
  22 +import java.util.List;
22 import java.util.concurrent.ConcurrentLinkedQueue; 23 import java.util.concurrent.ConcurrentLinkedQueue;
23 import java.util.concurrent.TimeUnit; 24 import java.util.concurrent.TimeUnit;
24 import java.util.concurrent.atomic.AtomicBoolean; 25 import java.util.concurrent.atomic.AtomicBoolean;
  26 +import java.util.function.Predicate;
  27 +import java.util.function.Supplier;
25 28
26 @Slf4j 29 @Slf4j
27 @Data 30 @Data
@@ -35,7 +38,7 @@ public final class TbActorMailbox implements TbActorCtx { @@ -35,7 +38,7 @@ public final class TbActorMailbox implements TbActorCtx {
35 private final TbActorSystem system; 38 private final TbActorSystem system;
36 private final TbActorSystemSettings settings; 39 private final TbActorSystemSettings settings;
37 private final TbActorId selfId; 40 private final TbActorId selfId;
38 - private final TbActorId parentId; 41 + private final TbActorRef parentRef;
39 private final TbActor actor; 42 private final TbActor actor;
40 private final Dispatcher dispatcher; 43 private final Dispatcher dispatcher;
41 private final ConcurrentLinkedQueue<TbActorMsg> msgs = new ConcurrentLinkedQueue<>(); 44 private final ConcurrentLinkedQueue<TbActorMsg> msgs = new ConcurrentLinkedQueue<>();
@@ -47,11 +50,12 @@ public final class TbActorMailbox implements TbActorCtx { @@ -47,11 +50,12 @@ public final class TbActorMailbox implements TbActorCtx {
47 dispatcher.getExecutor().execute(() -> tryInit(1)); 50 dispatcher.getExecutor().execute(() -> tryInit(1));
48 } 51 }
49 52
  53 +
50 private void tryInit(int attempt) { 54 private void tryInit(int attempt) {
51 try { 55 try {
52 log.debug("[{}] Trying to init actor, attempt: {}", selfId, attempt); 56 log.debug("[{}] Trying to init actor, attempt: {}", selfId, attempt);
53 if (!destroyInProgress.get()) { 57 if (!destroyInProgress.get()) {
54 - actor.init(); 58 + actor.init(this);
55 if (!destroyInProgress.get()) { 59 if (!destroyInProgress.get()) {
56 ready.set(READY); 60 ready.set(READY);
57 tryProcessQueue(false); 61 tryProcessQueue(false);
@@ -94,7 +98,7 @@ public final class TbActorMailbox implements TbActorCtx { @@ -94,7 +98,7 @@ public final class TbActorMailbox implements TbActorCtx {
94 if (msg != null) { 98 if (msg != null) {
95 try { 99 try {
96 log.debug("[{}] Going to process message: {}", selfId, msg); 100 log.debug("[{}] Going to process message: {}", selfId, msg);
97 - actor.process(this, msg); 101 + actor.process(msg);
98 } catch (Throwable t) { 102 } catch (Throwable t) {
99 log.debug("[{}] Failed to process message: {}", selfId, msg, t); 103 log.debug("[{}] Failed to process message: {}", selfId, msg, t);
100 ProcessFailureStrategy strategy = actor.onProcessFailure(t); 104 ProcessFailureStrategy strategy = actor.onProcessFailure(t);
@@ -121,13 +125,38 @@ public final class TbActorMailbox implements TbActorCtx { @@ -121,13 +125,38 @@ public final class TbActorMailbox implements TbActorCtx {
121 } 125 }
122 126
123 @Override 127 @Override
124 - public TbActorId getParent() {  
125 - return parentId; 128 + public void tell(TbActorId target, TbActorMsg actorMsg) {
  129 + system.tell(target, actorMsg);
126 } 130 }
127 131
128 @Override 132 @Override
129 - public void tell(TbActorId target, TbActorMsg actorMsg) {  
130 - system.tell(target, actorMsg); 133 + public void broadcastToChildren(TbActorMsg msg) {
  134 + system.broadcastToChildren(selfId, msg);
  135 + }
  136 +
  137 + @Override
  138 + public void broadcastToChildren(TbActorMsg msg, Predicate<TbActorId> childFilter) {
  139 + system.broadcastToChildren(selfId, childFilter, msg);
  140 + }
  141 +
  142 + @Override
  143 + public List<TbActorId> filterChildren(Predicate<TbActorId> childFilter) {
  144 + return system.filterChildren(selfId, childFilter);
  145 + }
  146 +
  147 + @Override
  148 + public void stop(TbActorId target) {
  149 + system.stop(target);
  150 + }
  151 +
  152 + @Override
  153 + public TbActorRef getOrCreateChildActor(TbActorId actorId, Supplier<String> dispatcher, Supplier<TbActorCreator> creator) {
  154 + TbActorRef actorRef = system.getActor(actorId);
  155 + if (actorRef == null) {
  156 + return system.createChildActor(dispatcher.get(), creator.get(), selfId);
  157 + } else {
  158 + return actorRef;
  159 + }
131 } 160 }
132 161
133 public void destroy() { 162 public void destroy() {
@@ -141,4 +170,14 @@ public final class TbActorMailbox implements TbActorCtx { @@ -141,4 +170,14 @@ public final class TbActorMailbox implements TbActorCtx {
141 } 170 }
142 }); 171 });
143 } 172 }
  173 +
  174 + @Override
  175 + public TbActorId getActorId() {
  176 + return selfId;
  177 + }
  178 +
  179 + @Override
  180 + public void tell(TbActorMsg actorMsg) {
  181 + enqueue(actorMsg);
  182 + }
144 } 183 }
  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;
  17 +
  18 +import org.thingsboard.server.common.msg.TbActorMsg;
  19 +
  20 +public interface TbActorRef {
  21 +
  22 + TbActorId getActorId();
  23 +
  24 + void tell(TbActorMsg actorMsg);
  25 +
  26 +}
@@ -17,8 +17,10 @@ package org.thingsboard.server.actors; @@ -17,8 +17,10 @@ package org.thingsboard.server.actors;
17 17
18 import org.thingsboard.server.common.msg.TbActorMsg; 18 import org.thingsboard.server.common.msg.TbActorMsg;
19 19
  20 +import java.util.List;
20 import java.util.concurrent.ExecutorService; 21 import java.util.concurrent.ExecutorService;
21 import java.util.concurrent.ScheduledExecutorService; 22 import java.util.concurrent.ScheduledExecutorService;
  23 +import java.util.function.Predicate;
22 24
23 public interface TbActorSystem { 25 public interface TbActorSystem {
24 26
@@ -28,14 +30,25 @@ public interface TbActorSystem { @@ -28,14 +30,25 @@ public interface TbActorSystem {
28 30
29 void destroyDispatcher(String dispatcherId); 31 void destroyDispatcher(String dispatcherId);
30 32
31 - TbActorId createRootActor(String dispatcherId, TbActorCreator creator); 33 + TbActorRef getActor(TbActorId actorId);
32 34
33 - TbActorId createChildActor(String dispatcherId, TbActorCreator creator, TbActorId parent); 35 + TbActorRef createRootActor(String dispatcherId, TbActorCreator creator);
  36 +
  37 + TbActorRef createChildActor(String dispatcherId, TbActorCreator creator, TbActorId parent);
  38 +
  39 + void tell(TbActorRef target, TbActorMsg actorMsg);
34 40
35 void tell(TbActorId target, TbActorMsg actorMsg); 41 void tell(TbActorId target, TbActorMsg actorMsg);
36 42
  43 + void stop(TbActorRef actorRef);
  44 +
37 void stop(TbActorId actorId); 45 void stop(TbActorId actorId);
38 46
39 void stop(); 47 void stop();
40 48
  49 + void broadcastToChildren(TbActorId parent, TbActorMsg msg);
  50 +
  51 + void broadcastToChildren(TbActorId parent, Predicate<TbActorId> childFilter, TbActorMsg msg);
  52 +
  53 + List<TbActorId> filterChildren(TbActorId parent, Predicate<TbActorId> childFilter);
41 } 54 }
  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;
  17 +
  18 +import lombok.Getter;
  19 +import org.thingsboard.server.common.data.id.EntityId;
  20 +
  21 +import java.util.Objects;
  22 +
  23 +public class TbEntityActorId implements TbActorId {
  24 +
  25 + @Getter
  26 + private final EntityId entityId;
  27 +
  28 + public TbEntityActorId(EntityId entityId) {
  29 + this.entityId = entityId;
  30 + }
  31 +
  32 + @Override
  33 + public String toString() {
  34 + return entityId.toString();
  35 + }
  36 +
  37 + @Override
  38 + public boolean equals(Object o) {
  39 + if (this == o) return true;
  40 + if (o == null || getClass() != o.getClass()) return false;
  41 + TbEntityActorId that = (TbEntityActorId) o;
  42 + return entityId.equals(that.entityId);
  43 + }
  44 +
  45 + @Override
  46 + public int hashCode() {
  47 + return Objects.hash(entityId);
  48 + }
  49 +}
  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;
  17 +
  18 +import java.util.Objects;
  19 +
  20 +public class TbStringActorId implements TbActorId {
  21 +
  22 + private final String id;
  23 +
  24 + public TbStringActorId(String id) {
  25 + this.id = id;
  26 + }
  27 +
  28 + @Override
  29 + public String toString() {
  30 + return id;
  31 + }
  32 +
  33 + @Override
  34 + public boolean equals(Object o) {
  35 + if (this == o) return true;
  36 + if (o == null || getClass() != o.getClass()) return false;
  37 + TbStringActorId that = (TbStringActorId) o;
  38 + return id.equals(that.id);
  39 + }
  40 +
  41 + @Override
  42 + public int hashCode() {
  43 + return Objects.hash(id);
  44 + }
  45 +}
@@ -81,10 +81,10 @@ public class ActorSystemTest { @@ -81,10 +81,10 @@ public class ActorSystemTest {
81 ActorTestCtx testCtx1 = getActorTestCtx(1); 81 ActorTestCtx testCtx1 = getActorTestCtx(1);
82 ActorTestCtx testCtx2 = getActorTestCtx(1); 82 ActorTestCtx testCtx2 = getActorTestCtx(1);
83 83
84 - TbActorId actorId1 = actorSystem.createRootActor(ROOT_DISPATCHER, new SlowInitActor.SlowInitActorCreator(  
85 - new TbActorId(new DeviceId(UUID.randomUUID())), testCtx1));  
86 - TbActorId actorId2 = actorSystem.createRootActor(ROOT_DISPATCHER, new SlowInitActor.SlowInitActorCreator(  
87 - new TbActorId(new DeviceId(UUID.randomUUID())), testCtx2)); 84 + TbActorRef actorId1 = actorSystem.createRootActor(ROOT_DISPATCHER, new SlowInitActor.SlowInitActorCreator(
  85 + new TbEntityActorId(new DeviceId(UUID.randomUUID())), testCtx1));
  86 + TbActorRef actorId2 = actorSystem.createRootActor(ROOT_DISPATCHER, new SlowInitActor.SlowInitActorCreator(
  87 + new TbEntityActorId(new DeviceId(UUID.randomUUID())), testCtx2));
88 88
89 actorSystem.tell(actorId1, new IntTbActorMsg(42)); 89 actorSystem.tell(actorId1, new IntTbActorMsg(42));
90 actorSystem.tell(actorId2, new IntTbActorMsg(42)); 90 actorSystem.tell(actorId2, new IntTbActorMsg(42));
@@ -98,7 +98,7 @@ public class ActorSystemTest { @@ -98,7 +98,7 @@ public class ActorSystemTest {
98 public void testOneActorCreated() throws InterruptedException { 98 public void testOneActorCreated() throws InterruptedException {
99 ActorTestCtx testCtx1 = getActorTestCtx(1); 99 ActorTestCtx testCtx1 = getActorTestCtx(1);
100 ActorTestCtx testCtx2 = getActorTestCtx(1); 100 ActorTestCtx testCtx2 = getActorTestCtx(1);
101 - TbActorId actorId = new TbActorId(new DeviceId(UUID.randomUUID())); 101 + TbActorId actorId = new TbEntityActorId(new DeviceId(UUID.randomUUID()));
102 submitPool.submit(() -> actorSystem.createRootActor(ROOT_DISPATCHER, new SlowCreateActor.SlowCreateActorCreator(actorId, testCtx1))); 102 submitPool.submit(() -> actorSystem.createRootActor(ROOT_DISPATCHER, new SlowCreateActor.SlowCreateActorCreator(actorId, testCtx1)));
103 submitPool.submit(() -> actorSystem.createRootActor(ROOT_DISPATCHER, new SlowCreateActor.SlowCreateActorCreator(actorId, testCtx2))); 103 submitPool.submit(() -> actorSystem.createRootActor(ROOT_DISPATCHER, new SlowCreateActor.SlowCreateActorCreator(actorId, testCtx2)));
104 104
@@ -112,7 +112,7 @@ public class ActorSystemTest { @@ -112,7 +112,7 @@ public class ActorSystemTest {
112 @Test 112 @Test
113 public void testActorCreatorCalledOnce() throws InterruptedException { 113 public void testActorCreatorCalledOnce() throws InterruptedException {
114 ActorTestCtx testCtx = getActorTestCtx(1); 114 ActorTestCtx testCtx = getActorTestCtx(1);
115 - TbActorId actorId = new TbActorId(new DeviceId(UUID.randomUUID())); 115 + TbActorId actorId = new TbEntityActorId(new DeviceId(UUID.randomUUID()));
116 for(int i =0; i < 1000; i++) { 116 for(int i =0; i < 1000; i++) {
117 submitPool.submit(() -> actorSystem.createRootActor(ROOT_DISPATCHER, new SlowCreateActor.SlowCreateActorCreator(actorId, testCtx))); 117 submitPool.submit(() -> actorSystem.createRootActor(ROOT_DISPATCHER, new SlowCreateActor.SlowCreateActorCreator(actorId, testCtx)));
118 } 118 }
@@ -138,12 +138,12 @@ public class ActorSystemTest { @@ -138,12 +138,12 @@ public class ActorSystemTest {
138 138
139 List<ActorTestCtx> testCtxes = new ArrayList<>(); 139 List<ActorTestCtx> testCtxes = new ArrayList<>();
140 140
141 - List<TbActorId> actorIds = new ArrayList<>(); 141 + List<TbActorRef> actorRefs = new ArrayList<>();
142 for (int actorIdx = 0; actorIdx < actorsCount; actorIdx++) { 142 for (int actorIdx = 0; actorIdx < actorsCount; actorIdx++) {
143 ActorTestCtx testCtx = getActorTestCtx(msgNumber); 143 ActorTestCtx testCtx = getActorTestCtx(msgNumber);
144 144
145 - actorIds.add(actorSystem.createRootActor(ROOT_DISPATCHER, new TestRootActor.TestRootActorCreator(  
146 - new TbActorId(new DeviceId(UUID.randomUUID())), testCtx))); 145 + actorRefs.add(actorSystem.createRootActor(ROOT_DISPATCHER, new TestRootActor.TestRootActorCreator(
  146 + new TbEntityActorId(new DeviceId(UUID.randomUUID())), testCtx)));
147 testCtxes.add(testCtx); 147 testCtxes.add(testCtx);
148 } 148 }
149 149
@@ -151,7 +151,7 @@ public class ActorSystemTest { @@ -151,7 +151,7 @@ public class ActorSystemTest {
151 151
152 for (int i = 0; i < msgNumber; i++) { 152 for (int i = 0; i < msgNumber; i++) {
153 int tmp = randomIntegers[i]; 153 int tmp = randomIntegers[i];
154 - submitPool.execute(() -> actorIds.forEach(actorId -> actorSystem.tell(actorId, new IntTbActorMsg(tmp)))); 154 + submitPool.execute(() -> actorRefs.forEach(actorId -> actorSystem.tell(actorId, new IntTbActorMsg(tmp))));
155 } 155 }
156 log.info("Submitted all messages"); 156 log.info("Submitted all messages");
157 157
@@ -25,13 +25,13 @@ public class SlowInitActor extends TestRootActor { @@ -25,13 +25,13 @@ public class SlowInitActor extends TestRootActor {
25 } 25 }
26 26
27 @Override 27 @Override
28 - public void init() { 28 + public void init(TbActorCtx ctx) {
29 try { 29 try {
30 Thread.sleep(500); 30 Thread.sleep(500);
31 } catch (InterruptedException e) { 31 } catch (InterruptedException e) {
32 e.printStackTrace(); 32 e.printStackTrace();
33 } 33 }
34 - super.init(); 34 + super.init(ctx);
35 } 35 }
36 36
37 public static class SlowInitActorCreator implements TbActorCreator { 37 public static class SlowInitActorCreator implements TbActorCreator {
@@ -20,7 +20,7 @@ import lombok.extern.slf4j.Slf4j; @@ -20,7 +20,7 @@ import lombok.extern.slf4j.Slf4j;
20 import org.thingsboard.server.common.msg.TbActorMsg; 20 import org.thingsboard.server.common.msg.TbActorMsg;
21 21
22 @Slf4j 22 @Slf4j
23 -public class TestRootActor implements TbActor { 23 +public class TestRootActor extends AbstractTbActor {
24 24
25 @Getter 25 @Getter
26 private final TbActorId actorId; 26 private final TbActorId actorId;
@@ -37,12 +37,13 @@ public class TestRootActor implements TbActor { @@ -37,12 +37,13 @@ public class TestRootActor implements TbActor {
37 } 37 }
38 38
39 @Override 39 @Override
40 - public void init() { 40 + public void init(TbActorCtx ctx) {
  41 + super.init(ctx);
41 initialized = true; 42 initialized = true;
42 } 43 }
43 44
44 @Override 45 @Override
45 - public boolean process(TbActorCtx ctx, TbActorMsg msg) { 46 + public boolean process(TbActorMsg msg) {
46 if (initialized) { 47 if (initialized) {
47 int value = ((IntTbActorMsg) msg).getValue(); 48 int value = ((IntTbActorMsg) msg).getValue();
48 sum += value; 49 sum += value;
@@ -21,7 +21,6 @@ import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg; @@ -21,7 +21,6 @@ import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg;
21 /** 21 /**
22 * Created by ashvayka on 15.03.18. 22 * Created by ashvayka on 15.03.18.
23 */ 23 */
24 -//TODO: add all "See" references  
25 public enum MsgType { 24 public enum MsgType {
26 25
27 /** 26 /**
@@ -97,6 +96,7 @@ public enum MsgType { @@ -97,6 +96,7 @@ public enum MsgType {
97 96
98 STATS_PERSIST_TICK_MSG, 97 STATS_PERSIST_TICK_MSG,
99 98
  99 + STATS_PERSIST_MSG,
100 100
101 /** 101 /**
102 * Message that is sent by TransportRuleEngineService to Device Actor. Represents messages from the device itself. 102 * Message that is sent by TransportRuleEngineService to Device Actor. Represents messages from the device itself.
@@ -16,8 +16,9 @@ @@ -16,8 +16,9 @@
16 package org.thingsboard.server.common.msg.aware; 16 package org.thingsboard.server.common.msg.aware;
17 17
18 import org.thingsboard.server.common.data.id.DeviceId; 18 import org.thingsboard.server.common.data.id.DeviceId;
  19 +import org.thingsboard.server.common.msg.TbActorMsg;
19 20
20 -public interface DeviceAwareMsg { 21 +public interface DeviceAwareMsg extends TbActorMsg {
21 22
22 DeviceId getDeviceId(); 23 DeviceId getDeviceId();
23 } 24 }
@@ -16,8 +16,9 @@ @@ -16,8 +16,9 @@
16 package org.thingsboard.server.common.msg.aware; 16 package org.thingsboard.server.common.msg.aware;
17 17
18 import org.thingsboard.server.common.data.id.RuleChainId; 18 import org.thingsboard.server.common.data.id.RuleChainId;
  19 +import org.thingsboard.server.common.msg.TbActorMsg;
19 20
20 -public interface RuleChainAwareMsg { 21 +public interface RuleChainAwareMsg extends TbActorMsg {
21 22
22 RuleChainId getRuleChainId(); 23 RuleChainId getRuleChainId();
23 24
@@ -16,8 +16,9 @@ @@ -16,8 +16,9 @@
16 package org.thingsboard.server.common.msg.aware; 16 package org.thingsboard.server.common.msg.aware;
17 17
18 import org.thingsboard.server.common.data.id.TenantId; 18 import org.thingsboard.server.common.data.id.TenantId;
  19 +import org.thingsboard.server.common.msg.TbActorMsg;
19 20
20 -public interface TenantAwareMsg { 21 +public interface TenantAwareMsg extends TbActorMsg {
21 22
22 TenantId getTenantId(); 23 TenantId getTenantId();
23 24
@@ -62,8 +62,6 @@ @@ -62,8 +62,6 @@
62 <jackson-annotations.version>2.10.2</jackson-annotations.version> 62 <jackson-annotations.version>2.10.2</jackson-annotations.version>
63 <jackson-core.version>2.10.2</jackson-core.version> 63 <jackson-core.version>2.10.2</jackson-core.version>
64 <json-schema-validator.version>2.2.6</json-schema-validator.version> 64 <json-schema-validator.version>2.2.6</json-schema-validator.version>
65 - <scala.version>2.13</scala.version>  
66 - <akka.version>2.6.3</akka.version>  
67 <californium.version>1.0.2</californium.version> 65 <californium.version>1.0.2</californium.version>
68 <gson.version>2.6.2</gson.version> 66 <gson.version>2.6.2</gson.version>
69 <velocity.version>1.7</velocity.version> 67 <velocity.version>1.7</velocity.version>
@@ -782,6 +780,11 @@ @@ -782,6 +780,11 @@
782 </dependency> 780 </dependency>
783 <dependency> 781 <dependency>
784 <groupId>org.thingsboard.common</groupId> 782 <groupId>org.thingsboard.common</groupId>
  783 + <artifactId>actor</artifactId>
  784 + <version>${project.version}</version>
  785 + </dependency>
  786 + <dependency>
  787 + <groupId>org.thingsboard.common</groupId>
785 <artifactId>dao-api</artifactId> 788 <artifactId>dao-api</artifactId>
786 <version>${project.version}</version> 789 <version>${project.version}</version>
787 </dependency> 790 </dependency>
@@ -1114,16 +1117,6 @@ @@ -1114,16 +1117,6 @@
1114 </exclusions> 1117 </exclusions>
1115 </dependency> 1118 </dependency>
1116 <dependency> 1119 <dependency>
1117 - <groupId>com.typesafe.akka</groupId>  
1118 - <artifactId>akka-actor_${scala.version}</artifactId>  
1119 - <version>${akka.version}</version>  
1120 - </dependency>  
1121 - <dependency>  
1122 - <groupId>com.typesafe.akka</groupId>  
1123 - <artifactId>akka-slf4j_${scala.version}</artifactId>  
1124 - <version>${akka.version}</version>  
1125 - </dependency>  
1126 - <dependency>  
1127 <groupId>org.eclipse.californium</groupId> 1120 <groupId>org.eclipse.californium</groupId>
1128 <artifactId>californium-core</artifactId> 1121 <artifactId>californium-core</artifactId>
1129 <version>${californium.version}</version> 1122 <version>${californium.version}</version>