Commit bd98ce8deb0794ca4edbd64cac4ad3cd2396ef51

Authored by Igor Kulikov
2 parents 78a91b8c f572f473

Merge with develop/2.5.2

Showing 58 changed files with 1209 additions and 55 deletions
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>2.5.2-SNAPSHOT</version> 23 + <version>3.0.1-SNAPSHOT</version>
24 <artifactId>thingsboard</artifactId> 24 <artifactId>thingsboard</artifactId>
25 </parent> 25 </parent>
26 <artifactId>application</artifactId> 26 <artifactId>application</artifactId>
@@ -48,8 +48,6 @@ public class CassandraTsDatabaseUpgradeService extends AbstractCassandraDatabase @@ -48,8 +48,6 @@ public class CassandraTsDatabaseUpgradeService extends AbstractCassandraDatabase
48 } 48 }
49 log.info("Schema updated."); 49 log.info("Schema updated.");
50 break; 50 break;
51 - case "2.5.0":  
52 - break;  
53 default: 51 default:
54 throw new RuntimeException("Unable to upgrade Cassandra database, unsupported fromVersion: " + fromVersion); 52 throw new RuntimeException("Unable to upgrade Cassandra database, unsupported fromVersion: " + fromVersion);
55 } 53 }
  1 +<!--
  2 +
  3 + Copyright © 2016-2020 The Thingsboard Authors
  4 +
  5 + Licensed under the Apache License, Version 2.0 (the "License");
  6 + you may not use this file except in compliance with the License.
  7 + You may obtain a copy of the License at
  8 +
  9 + http://www.apache.org/licenses/LICENSE-2.0
  10 +
  11 + Unless required by applicable law or agreed to in writing, software
  12 + distributed under the License is distributed on an "AS IS" BASIS,
  13 + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14 + See the License for the specific language governing permissions and
  15 + limitations under the License.
  16 +
  17 +-->
  18 +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  19 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  20 + <modelVersion>4.0.0</modelVersion>
  21 + <parent>
  22 + <groupId>org.thingsboard</groupId>
  23 + <version>3.0.1-SNAPSHOT</version>
  24 + <artifactId>common</artifactId>
  25 + </parent>
  26 + <groupId>org.thingsboard.common</groupId>
  27 + <artifactId>actor</artifactId>
  28 + <packaging>jar</packaging>
  29 +
  30 + <name>Thingsboard Actor system</name>
  31 + <url>https://thingsboard.io</url>
  32 +
  33 + <properties>
  34 + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  35 + <main.dir>${basedir}/../..</main.dir>
  36 + </properties>
  37 +
  38 + <dependencies>
  39 + <dependency>
  40 + <groupId>org.thingsboard.common</groupId>
  41 + <artifactId>util</artifactId>
  42 + </dependency>
  43 + <dependency>
  44 + <groupId>org.thingsboard.common</groupId>
  45 + <artifactId>message</artifactId>
  46 + </dependency>
  47 + <dependency>
  48 + <groupId>org.slf4j</groupId>
  49 + <artifactId>slf4j-api</artifactId>
  50 + </dependency>
  51 + <dependency>
  52 + <groupId>org.slf4j</groupId>
  53 + <artifactId>log4j-over-slf4j</artifactId>
  54 + </dependency>
  55 + <dependency>
  56 + <groupId>ch.qos.logback</groupId>
  57 + <artifactId>logback-core</artifactId>
  58 + </dependency>
  59 + <dependency>
  60 + <groupId>ch.qos.logback</groupId>
  61 + <artifactId>logback-classic</artifactId>
  62 + </dependency>
  63 + <dependency>
  64 + <groupId>junit</groupId>
  65 + <artifactId>junit</artifactId>
  66 + <scope>test</scope>
  67 + </dependency>
  68 + <dependency>
  69 + <groupId>org.mockito</groupId>
  70 + <artifactId>mockito-all</artifactId>
  71 + <scope>test</scope>
  72 + </dependency>
  73 + </dependencies>
  74 +
  75 +</project>
  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.Data;
  19 +import lombok.Getter;
  20 +import lombok.extern.slf4j.Slf4j;
  21 +import org.thingsboard.common.util.ThingsBoardThreadFactory;
  22 +import org.thingsboard.server.common.msg.TbActorMsg;
  23 +
  24 +import java.util.concurrent.ConcurrentHashMap;
  25 +import java.util.concurrent.ConcurrentMap;
  26 +import java.util.concurrent.ExecutorService;
  27 +import java.util.concurrent.Executors;
  28 +import java.util.concurrent.ScheduledExecutorService;
  29 +import java.util.concurrent.locks.Lock;
  30 +import java.util.concurrent.locks.ReentrantLock;
  31 +
  32 +@Slf4j
  33 +@Data
  34 +public class DefaultTbActorSystem implements TbActorSystem {
  35 +
  36 + private final ConcurrentMap<String, Dispatcher> dispatchers = new ConcurrentHashMap<>();
  37 + private final ConcurrentMap<TbActorId, TbActorMailbox> actors = new ConcurrentHashMap<>();
  38 + private final ConcurrentMap<TbActorId, ReentrantLock> actorCreationLocks = new ConcurrentHashMap<>();
  39 + @Getter
  40 + private final TbActorSystemSettings settings;
  41 + @Getter
  42 + private final ScheduledExecutorService scheduler;
  43 +
  44 + public DefaultTbActorSystem(TbActorSystemSettings settings) {
  45 + this.settings = settings;
  46 + this.scheduler = Executors.newScheduledThreadPool(settings.getSchedulerPoolSize(), ThingsBoardThreadFactory.forName("actor-system-scheduler"));
  47 + }
  48 +
  49 + @Override
  50 + public void createDispatcher(String dispatcherId, ExecutorService executor) {
  51 + Dispatcher current = dispatchers.putIfAbsent(dispatcherId, new Dispatcher(dispatcherId, executor));
  52 + if (current != null) {
  53 + throw new RuntimeException("Dispatcher with id [" + dispatcherId + "] is already registered!");
  54 + }
  55 + }
  56 +
  57 + @Override
  58 + public void destroyDispatcher(String dispatcherId) {
  59 + Dispatcher dispatcher = dispatchers.remove(dispatcherId);
  60 + if (dispatcher != null) {
  61 + dispatcher.getExecutor().shutdownNow();
  62 + } else {
  63 + throw new RuntimeException("Dispatcher with id [" + dispatcherId + "] is not registered!");
  64 + }
  65 + }
  66 +
  67 + @Override
  68 + public TbActorId createRootActor(String dispatcherId, TbActorCreator creator) {
  69 + return createActor(dispatcherId, creator, null);
  70 + }
  71 +
  72 + @Override
  73 + public TbActorId createChildActor(String dispatcherId, TbActorCreator creator, TbActorId parent) {
  74 + return createActor(dispatcherId, creator, parent);
  75 + }
  76 +
  77 + private TbActorId createActor(String dispatcherId, TbActorCreator creator, TbActorId parent) {
  78 + Dispatcher dispatcher = dispatchers.get(dispatcherId);
  79 + if (dispatcher == null) {
  80 + log.warn("Dispatcher with id [{}] is not registered!", dispatcherId);
  81 + throw new RuntimeException("Dispatcher with id [" + dispatcherId + "] is not registered!");
  82 + }
  83 +
  84 + TbActorId actorId = creator.createActorId();
  85 + TbActorMailbox actorMailbox = actors.get(actorId);
  86 + if (actorMailbox != null) {
  87 + log.debug("Actor with id [{}] is already registered!", actorId);
  88 + } else {
  89 + Lock actorCreationLock = actorCreationLocks.computeIfAbsent(actorId, id -> new ReentrantLock());
  90 + actorCreationLock.lock();
  91 + try {
  92 + actorMailbox = actors.get(actorId);
  93 + if (actorMailbox == null) {
  94 + log.debug("Creating actor with id [{}]!", actorId);
  95 + TbActor actor = creator.createActor();
  96 + TbActorMailbox mailbox = new TbActorMailbox(this, settings, actorId, parent, actor, dispatcher);
  97 + actors.put(actorId, mailbox);
  98 + mailbox.initActor();
  99 + } else {
  100 + log.debug("Actor with id [{}] is already registered!", actorId);
  101 + }
  102 + } finally {
  103 + actorCreationLock.unlock();
  104 + actorCreationLocks.remove(actorId);
  105 + }
  106 + }
  107 + return actorId;
  108 + }
  109 +
  110 + @Override
  111 + public void tell(TbActorId target, TbActorMsg actorMsg) {
  112 + TbActorMailbox mailbox = actors.get(target);
  113 + if (mailbox == null) {
  114 + throw new TbActorNotRegisteredException(target, "Actor with id [" + target + "] is not registered!");
  115 + }
  116 + mailbox.enqueue(actorMsg);
  117 + }
  118 +
  119 + @Override
  120 + public void stop(TbActorId actorId) {
  121 + TbActorMailbox mailbox = actors.remove(actorId);
  122 + if (mailbox != null) {
  123 + mailbox.destroy();
  124 + }
  125 + }
  126 +
  127 + @Override
  128 + public void stop() {
  129 + dispatchers.values().forEach(dispatcher -> dispatcher.getExecutor().shutdownNow());
  130 + actors.clear();
  131 + }
  132 +
  133 +}
  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.Data;
  19 +
  20 +import java.util.concurrent.ExecutorService;
  21 +
  22 +@Data
  23 +class Dispatcher {
  24 +
  25 + private final String dispatcherId;
  26 + private final ExecutorService executor;
  27 +
  28 +}
  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 lombok.ToString;
  20 +
  21 +@ToString
  22 +public class InitFailureStrategy {
  23 +
  24 + @Getter
  25 + private boolean stop;
  26 + @Getter
  27 + private long retryDelay;
  28 +
  29 + private InitFailureStrategy(boolean stop, long retryDelay) {
  30 + this.stop = stop;
  31 + this.retryDelay = retryDelay;
  32 + }
  33 +
  34 + public static InitFailureStrategy retryImmediately() {
  35 + return new InitFailureStrategy(false, 0);
  36 + }
  37 +
  38 + public static InitFailureStrategy retryWithDelay(long ms) {
  39 + return new InitFailureStrategy(false, ms);
  40 + }
  41 +
  42 + public static InitFailureStrategy stop() {
  43 + return new InitFailureStrategy(true, 0);
  44 + }
  45 +}
  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 lombok.ToString;
  20 +
  21 +@ToString
  22 +public class ProcessFailureStrategy {
  23 +
  24 + @Getter
  25 + private boolean stop;
  26 +
  27 + private ProcessFailureStrategy(boolean stop) {
  28 + this.stop = stop;
  29 + }
  30 +
  31 + public static ProcessFailureStrategy stop() {
  32 + return new ProcessFailureStrategy(true);
  33 + }
  34 +
  35 + public static ProcessFailureStrategy resume() {
  36 + return new ProcessFailureStrategy(false);
  37 + }
  38 +}
  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 TbActor {
  21 +
  22 + void init();
  23 +
  24 + boolean process(TbActorCtx ctx, TbActorMsg msg);
  25 +
  26 + void destroy();
  27 +
  28 + default InitFailureStrategy onInitFailure(int attempt, Throwable t) {
  29 + return InitFailureStrategy.retryWithDelay(5000);
  30 + }
  31 +
  32 + default ProcessFailureStrategy onProcessFailure(Throwable t) {
  33 + if (t instanceof Error) {
  34 + return ProcessFailureStrategy.stop();
  35 + } else {
  36 + return ProcessFailureStrategy.resume();
  37 + }
  38 + }
  39 +}
  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 +public interface TbActorCreator {
  19 +
  20 + TbActorId createActorId();
  21 +
  22 + TbActor createActor();
  23 +
  24 +}
  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 TbActorCtx {
  21 +
  22 + TbActorId getSelf();
  23 +
  24 + TbActorId getParent();
  25 +
  26 + void tell(TbActorId target, TbActorMsg actorMsg);
  27 +
  28 +}
  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.data.id.EntityId;
  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 +}
  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.Data;
  19 +import lombok.extern.slf4j.Slf4j;
  20 +import org.thingsboard.server.common.msg.TbActorMsg;
  21 +
  22 +import java.util.concurrent.ConcurrentLinkedQueue;
  23 +import java.util.concurrent.TimeUnit;
  24 +import java.util.concurrent.atomic.AtomicBoolean;
  25 +
  26 +@Slf4j
  27 +@Data
  28 +public final class TbActorMailbox implements TbActorCtx {
  29 + private static final boolean FREE = false;
  30 + private static final boolean BUSY = true;
  31 +
  32 + private static final boolean NOT_READY = false;
  33 + private static final boolean READY = true;
  34 +
  35 + private final TbActorSystem system;
  36 + private final TbActorSystemSettings settings;
  37 + private final TbActorId selfId;
  38 + private final TbActorId parentId;
  39 + private final TbActor actor;
  40 + private final Dispatcher dispatcher;
  41 + private final ConcurrentLinkedQueue<TbActorMsg> msgs = new ConcurrentLinkedQueue<>();
  42 + private final AtomicBoolean busy = new AtomicBoolean(FREE);
  43 + private final AtomicBoolean ready = new AtomicBoolean(NOT_READY);
  44 + private final AtomicBoolean destroyInProgress = new AtomicBoolean();
  45 +
  46 + public void initActor() {
  47 + dispatcher.getExecutor().execute(() -> tryInit(1));
  48 + }
  49 +
  50 + private void tryInit(int attempt) {
  51 + try {
  52 + log.debug("[{}] Trying to init actor, attempt: {}", selfId, attempt);
  53 + if (!destroyInProgress.get()) {
  54 + actor.init();
  55 + if (!destroyInProgress.get()) {
  56 + ready.set(READY);
  57 + tryProcessQueue(false);
  58 + }
  59 + }
  60 + } catch (Throwable t) {
  61 + log.debug("[{}] Failed to init actor, attempt: {}", selfId, attempt, t);
  62 + int attemptIdx = attempt + 1;
  63 + InitFailureStrategy strategy = actor.onInitFailure(attempt, t);
  64 + if (strategy.isStop() || (settings.getMaxActorInitAttempts() > 0 && attemptIdx > settings.getMaxActorInitAttempts())) {
  65 + log.info("[{}] Failed to init actor, attempt {}, going to stop attempts.", selfId, attempt, t);
  66 + system.stop(selfId);
  67 + } else if (strategy.getRetryDelay() > 0) {
  68 + log.info("[{}] Failed to init actor, attempt {}, going to retry in attempts in {}ms", selfId, attempt, strategy.getRetryDelay(), t);
  69 + system.getScheduler().schedule(() -> dispatcher.getExecutor().execute(() -> tryInit(attemptIdx)), strategy.getRetryDelay(), TimeUnit.MILLISECONDS);
  70 + } else {
  71 + log.info("[{}] Failed to init actor, attempt {}, going to retry immediately", selfId, attempt, t);
  72 + dispatcher.getExecutor().execute(() -> tryInit(attemptIdx));
  73 + }
  74 + }
  75 + }
  76 +
  77 + public void enqueue(TbActorMsg msg) {
  78 + msgs.add(msg);
  79 + tryProcessQueue(true);
  80 + }
  81 +
  82 + private void tryProcessQueue(boolean newMsg) {
  83 + if (ready.get() == READY && (newMsg || !msgs.isEmpty()) && busy.compareAndSet(FREE, BUSY)) {
  84 + dispatcher.getExecutor().execute(this::processMailbox);
  85 + } else {
  86 + log.trace("[{}] MessageBox is busy, new msg: {}", selfId, newMsg);
  87 + }
  88 + }
  89 +
  90 + private void processMailbox() {
  91 + boolean noMoreElements = false;
  92 + for (int i = 0; i < settings.getActorThroughput(); i++) {
  93 + TbActorMsg msg = msgs.poll();
  94 + if (msg != null) {
  95 + try {
  96 + log.debug("[{}] Going to process message: {}", selfId, msg);
  97 + actor.process(this, msg);
  98 + } catch (Throwable t) {
  99 + log.debug("[{}] Failed to process message: {}", selfId, msg, t);
  100 + ProcessFailureStrategy strategy = actor.onProcessFailure(t);
  101 + if (strategy.isStop()) {
  102 + system.stop(selfId);
  103 + }
  104 + }
  105 + } else {
  106 + noMoreElements = true;
  107 + break;
  108 + }
  109 + }
  110 + if (noMoreElements) {
  111 + busy.set(FREE);
  112 + dispatcher.getExecutor().execute(() -> tryProcessQueue(false));
  113 + } else {
  114 + dispatcher.getExecutor().execute(this::processMailbox);
  115 + }
  116 + }
  117 +
  118 + @Override
  119 + public TbActorId getSelf() {
  120 + return selfId;
  121 + }
  122 +
  123 + @Override
  124 + public TbActorId getParent() {
  125 + return parentId;
  126 + }
  127 +
  128 + @Override
  129 + public void tell(TbActorId target, TbActorMsg actorMsg) {
  130 + system.tell(target, actorMsg);
  131 + }
  132 +
  133 + public void destroy() {
  134 + destroyInProgress.set(true);
  135 + dispatcher.getExecutor().execute(() -> {
  136 + try {
  137 + ready.set(NOT_READY);
  138 + actor.destroy();
  139 + } catch (Throwable t) {
  140 + log.warn("[{}] Failed to destroy actor: {}", selfId, t);
  141 + }
  142 + });
  143 + }
  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 class TbActorNotRegisteredException extends RuntimeException {
  21 +
  22 + @Getter
  23 + private TbActorId target;
  24 +
  25 + public TbActorNotRegisteredException(TbActorId target, String message) {
  26 + super(message);
  27 + this.target = target;
  28 + }
  29 +}
  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 +import java.util.concurrent.ExecutorService;
  21 +import java.util.concurrent.ScheduledExecutorService;
  22 +
  23 +public interface TbActorSystem {
  24 +
  25 + ScheduledExecutorService getScheduler();
  26 +
  27 + void createDispatcher(String dispatcherId, ExecutorService executor);
  28 +
  29 + void destroyDispatcher(String dispatcherId);
  30 +
  31 + TbActorId createRootActor(String dispatcherId, TbActorCreator creator);
  32 +
  33 + TbActorId createChildActor(String dispatcherId, TbActorCreator creator, TbActorId parent);
  34 +
  35 + void tell(TbActorId target, TbActorMsg actorMsg);
  36 +
  37 + void stop(TbActorId actorId);
  38 +
  39 + void stop();
  40 +
  41 +}
  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.Data;
  19 +
  20 +@Data
  21 +public class TbActorSystemSettings {
  22 +
  23 + private final int actorThroughput;
  24 + private final int schedulerPoolSize;
  25 + private final int maxActorInitAttempts;
  26 +
  27 +}
  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.extern.slf4j.Slf4j;
  19 +import org.junit.After;
  20 +import org.junit.Assert;
  21 +import org.junit.Before;
  22 +import org.junit.Test;
  23 +import org.junit.runner.RunWith;
  24 +import org.mockito.runners.MockitoJUnitRunner;
  25 +import org.thingsboard.server.common.data.id.DeviceId;
  26 +
  27 +import java.util.ArrayList;
  28 +import java.util.List;
  29 +import java.util.Random;
  30 +import java.util.UUID;
  31 +import java.util.concurrent.CountDownLatch;
  32 +import java.util.concurrent.ExecutorService;
  33 +import java.util.concurrent.Executors;
  34 +import java.util.concurrent.TimeUnit;
  35 +import java.util.concurrent.atomic.AtomicInteger;
  36 +import java.util.concurrent.atomic.AtomicLong;
  37 +
  38 +@Slf4j
  39 +@RunWith(MockitoJUnitRunner.class)
  40 +public class ActorSystemTest {
  41 +
  42 + public static final String ROOT_DISPATCHER = "root-dispatcher";
  43 + private static final int _1M = 1024 * 1024;
  44 +
  45 + private TbActorSystem actorSystem;
  46 + private ExecutorService submitPool;
  47 +
  48 + @Before
  49 + public void initActorSystem() {
  50 + int cores = Runtime.getRuntime().availableProcessors();
  51 + int parallelism = Math.max(1, cores / 2);
  52 + TbActorSystemSettings settings = new TbActorSystemSettings(5, parallelism, 42);
  53 + actorSystem = new DefaultTbActorSystem(settings);
  54 + submitPool = Executors.newWorkStealingPool(parallelism);
  55 + actorSystem.createDispatcher(ROOT_DISPATCHER, Executors.newWorkStealingPool(parallelism));
  56 + }
  57 +
  58 + @After
  59 + public void shutdownActorSystem() {
  60 + actorSystem.stop();
  61 + submitPool.shutdownNow();
  62 + }
  63 +
  64 + @Test
  65 + public void test10actorsAnd1MMessages() throws InterruptedException {
  66 + testActorsAndMessages(10, _1M);
  67 + }
  68 +
  69 + @Test
  70 + public void test1MActorsAnd10Messages() throws InterruptedException {
  71 + testActorsAndMessages(_1M, 10);
  72 + }
  73 +
  74 + @Test
  75 + public void test1KActorsAnd1KMessages() throws InterruptedException {
  76 + testActorsAndMessages(1000, 1000);
  77 + }
  78 +
  79 + @Test
  80 + public void testNoMessagesAfterDestroy() throws InterruptedException {
  81 + ActorTestCtx testCtx1 = getActorTestCtx(1);
  82 + ActorTestCtx testCtx2 = getActorTestCtx(1);
  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));
  88 +
  89 + actorSystem.tell(actorId1, new IntTbActorMsg(42));
  90 + actorSystem.tell(actorId2, new IntTbActorMsg(42));
  91 + actorSystem.stop(actorId1);
  92 +
  93 + Assert.assertTrue(testCtx2.getLatch().await(1, TimeUnit.SECONDS));
  94 + Assert.assertFalse(testCtx1.getLatch().await(2, TimeUnit.SECONDS));
  95 + }
  96 +
  97 + @Test
  98 + public void testOneActorCreated() throws InterruptedException {
  99 + ActorTestCtx testCtx1 = getActorTestCtx(1);
  100 + ActorTestCtx testCtx2 = getActorTestCtx(1);
  101 + TbActorId actorId = new TbActorId(new DeviceId(UUID.randomUUID()));
  102 + submitPool.submit(() -> actorSystem.createRootActor(ROOT_DISPATCHER, new SlowCreateActor.SlowCreateActorCreator(actorId, testCtx1)));
  103 + submitPool.submit(() -> actorSystem.createRootActor(ROOT_DISPATCHER, new SlowCreateActor.SlowCreateActorCreator(actorId, testCtx2)));
  104 +
  105 + Thread.sleep(1000);
  106 + actorSystem.tell(actorId, new IntTbActorMsg(42));
  107 +
  108 + Assert.assertTrue(testCtx1.getLatch().await(3, TimeUnit.SECONDS));
  109 + Assert.assertFalse(testCtx2.getLatch().await(3, TimeUnit.SECONDS));
  110 + }
  111 +
  112 + @Test
  113 + public void testActorCreatorCalledOnce() throws InterruptedException {
  114 + ActorTestCtx testCtx = getActorTestCtx(1);
  115 + TbActorId actorId = new TbActorId(new DeviceId(UUID.randomUUID()));
  116 + for(int i =0; i < 1000; i++) {
  117 + submitPool.submit(() -> actorSystem.createRootActor(ROOT_DISPATCHER, new SlowCreateActor.SlowCreateActorCreator(actorId, testCtx)));
  118 + }
  119 + Thread.sleep(1000);
  120 + actorSystem.tell(actorId, new IntTbActorMsg(42));
  121 +
  122 + Assert.assertTrue(testCtx.getLatch().await(1, TimeUnit.SECONDS));
  123 + //One for creation and one for message
  124 + Assert.assertEquals(2, testCtx.getInvocationCount().get());
  125 + }
  126 +
  127 +
  128 + public void testActorsAndMessages(int actorsCount, int msgNumber) throws InterruptedException {
  129 + Random random = new Random();
  130 + int[] randomIntegers = new int[msgNumber];
  131 + long sumTmp = 0;
  132 + for (int i = 0; i < msgNumber; i++) {
  133 + int tmp = random.nextInt();
  134 + randomIntegers[i] = tmp;
  135 + sumTmp += tmp;
  136 + }
  137 + long expected = sumTmp;
  138 +
  139 + List<ActorTestCtx> testCtxes = new ArrayList<>();
  140 +
  141 + List<TbActorId> actorIds = new ArrayList<>();
  142 + for (int actorIdx = 0; actorIdx < actorsCount; actorIdx++) {
  143 + ActorTestCtx testCtx = getActorTestCtx(msgNumber);
  144 +
  145 + actorIds.add(actorSystem.createRootActor(ROOT_DISPATCHER, new TestRootActor.TestRootActorCreator(
  146 + new TbActorId(new DeviceId(UUID.randomUUID())), testCtx)));
  147 + testCtxes.add(testCtx);
  148 + }
  149 +
  150 + long start = System.nanoTime();
  151 +
  152 + for (int i = 0; i < msgNumber; i++) {
  153 + int tmp = randomIntegers[i];
  154 + submitPool.execute(() -> actorIds.forEach(actorId -> actorSystem.tell(actorId, new IntTbActorMsg(tmp))));
  155 + }
  156 + log.info("Submitted all messages");
  157 +
  158 + testCtxes.forEach(ctx -> {
  159 + try {
  160 + Assert.assertTrue(ctx.getLatch().await(1, TimeUnit.MINUTES));
  161 + Assert.assertEquals(expected, ctx.getActual().get());
  162 + Assert.assertEquals(msgNumber, ctx.getInvocationCount().get());
  163 + } catch (InterruptedException e) {
  164 + e.printStackTrace();
  165 + }
  166 + });
  167 +
  168 + long duration = System.nanoTime() - start;
  169 + log.info("Time spend: {}ns ({} ms)", duration, TimeUnit.NANOSECONDS.toMillis(duration));
  170 + }
  171 +
  172 + private ActorTestCtx getActorTestCtx(int i) {
  173 + CountDownLatch countDownLatch = new CountDownLatch(1);
  174 + AtomicLong actual = new AtomicLong();
  175 + AtomicInteger invocations = new AtomicInteger();
  176 + return new ActorTestCtx(countDownLatch, invocations, i, actual);
  177 + }
  178 +}
  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.Data;
  19 +
  20 +import java.util.concurrent.CountDownLatch;
  21 +import java.util.concurrent.atomic.AtomicInteger;
  22 +import java.util.concurrent.atomic.AtomicLong;
  23 +
  24 +@Data
  25 +public class ActorTestCtx {
  26 +
  27 + private final CountDownLatch latch;
  28 + private final AtomicInteger invocationCount;
  29 + private final int expectedInvocationCount;
  30 + private final AtomicLong actual;
  31 +}
  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.msg.MsgType;
  20 +import org.thingsboard.server.common.msg.TbActorMsg;
  21 +
  22 +public class IntTbActorMsg implements TbActorMsg {
  23 +
  24 + @Getter
  25 + private final int value;
  26 +
  27 + public IntTbActorMsg(int value) {
  28 + this.value = value;
  29 + }
  30 +
  31 + @Override
  32 + public MsgType getMsgType() {
  33 + return MsgType.QUEUE_TO_RULE_ENGINE_MSG;
  34 + }
  35 +}
  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.extern.slf4j.Slf4j;
  19 +
  20 +@Slf4j
  21 +public class SlowCreateActor extends TestRootActor {
  22 +
  23 + public SlowCreateActor(TbActorId actorId, ActorTestCtx testCtx) {
  24 + super(actorId, testCtx);
  25 + try {
  26 + Thread.sleep(500);
  27 + } catch (InterruptedException e) {
  28 + e.printStackTrace();
  29 + }
  30 + testCtx.getInvocationCount().incrementAndGet();
  31 + }
  32 +
  33 + public static class SlowCreateActorCreator implements TbActorCreator {
  34 +
  35 + private final TbActorId actorId;
  36 + private final ActorTestCtx testCtx;
  37 +
  38 + public SlowCreateActorCreator(TbActorId actorId, ActorTestCtx testCtx) {
  39 + this.actorId = actorId;
  40 + this.testCtx = testCtx;
  41 + }
  42 +
  43 + @Override
  44 + public TbActorId createActorId() {
  45 + return actorId;
  46 + }
  47 +
  48 + @Override
  49 + public TbActor createActor() {
  50 + return new SlowCreateActor(actorId, testCtx);
  51 + }
  52 + }
  53 +}
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.actors;
  17 +
  18 +import lombok.extern.slf4j.Slf4j;
  19 +
  20 +@Slf4j
  21 +public class SlowInitActor extends TestRootActor {
  22 +
  23 + public SlowInitActor(TbActorId actorId, ActorTestCtx testCtx) {
  24 + super(actorId, testCtx);
  25 + }
  26 +
  27 + @Override
  28 + public void init() {
  29 + try {
  30 + Thread.sleep(500);
  31 + } catch (InterruptedException e) {
  32 + e.printStackTrace();
  33 + }
  34 + super.init();
  35 + }
  36 +
  37 + public static class SlowInitActorCreator implements TbActorCreator {
  38 +
  39 + private final TbActorId actorId;
  40 + private final ActorTestCtx testCtx;
  41 +
  42 + public SlowInitActorCreator(TbActorId actorId, ActorTestCtx testCtx) {
  43 + this.actorId = actorId;
  44 + this.testCtx = testCtx;
  45 + }
  46 +
  47 + @Override
  48 + public TbActorId createActorId() {
  49 + return actorId;
  50 + }
  51 +
  52 + @Override
  53 + public TbActor createActor() {
  54 + return new SlowInitActor(actorId, testCtx);
  55 + }
  56 + }
  57 +}
  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 lombok.extern.slf4j.Slf4j;
  20 +import org.thingsboard.server.common.msg.TbActorMsg;
  21 +
  22 +@Slf4j
  23 +public class TestRootActor implements TbActor {
  24 +
  25 + @Getter
  26 + private final TbActorId actorId;
  27 + @Getter
  28 + private final ActorTestCtx testCtx;
  29 +
  30 + private boolean initialized;
  31 + private long sum;
  32 + private int count;
  33 +
  34 + public TestRootActor(TbActorId actorId, ActorTestCtx testCtx) {
  35 + this.actorId = actorId;
  36 + this.testCtx = testCtx;
  37 + }
  38 +
  39 + @Override
  40 + public void init() {
  41 + initialized = true;
  42 + }
  43 +
  44 + @Override
  45 + public boolean process(TbActorCtx ctx, TbActorMsg msg) {
  46 + if (initialized) {
  47 + int value = ((IntTbActorMsg) msg).getValue();
  48 + sum += value;
  49 + count += 1;
  50 + if (count == testCtx.getExpectedInvocationCount()) {
  51 + testCtx.getActual().set(sum);
  52 + testCtx.getInvocationCount().addAndGet(count);
  53 + testCtx.getLatch().countDown();
  54 + }
  55 + }
  56 + return true;
  57 + }
  58 +
  59 + @Override
  60 + public void destroy() {
  61 +
  62 + }
  63 +
  64 + public static class TestRootActorCreator implements TbActorCreator {
  65 +
  66 + private final TbActorId actorId;
  67 + private final ActorTestCtx testCtx;
  68 +
  69 + public TestRootActorCreator(TbActorId actorId, ActorTestCtx testCtx) {
  70 + this.actorId = actorId;
  71 + this.testCtx = testCtx;
  72 + }
  73 +
  74 + @Override
  75 + public TbActorId createActorId() {
  76 + return actorId;
  77 + }
  78 +
  79 + @Override
  80 + public TbActor createActor() {
  81 + return new TestRootActor(actorId, testCtx);
  82 + }
  83 + }
  84 +}
  1 +<?xml version="1.0" encoding="UTF-8" ?>
  2 +
  3 +<configuration>
  4 + <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
  5 + <encoder>
  6 + <pattern>%d{ISO8601} [%thread] %-5level %logger{36} - %msg%n</pattern>
  7 + </encoder>
  8 + </appender>
  9 +
  10 + <root level="INFO">
  11 + <appender-ref ref="console"/>
  12 + </root>
  13 +
  14 +</configuration>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>2.5.2-SNAPSHOT</version> 23 + <version>3.0.1-SNAPSHOT</version>
24 <artifactId>common</artifactId> 24 <artifactId>common</artifactId>
25 </parent> 25 </parent>
26 <groupId>org.thingsboard.common</groupId> 26 <groupId>org.thingsboard.common</groupId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>2.5.2-SNAPSHOT</version> 23 + <version>3.0.1-SNAPSHOT</version>
24 <artifactId>common</artifactId> 24 <artifactId>common</artifactId>
25 </parent> 25 </parent>
26 <groupId>org.thingsboard.common</groupId> 26 <groupId>org.thingsboard.common</groupId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>2.5.2-SNAPSHOT</version> 23 + <version>3.0.1-SNAPSHOT</version>
24 <artifactId>common</artifactId> 24 <artifactId>common</artifactId>
25 </parent> 25 </parent>
26 <groupId>org.thingsboard.common</groupId> 26 <groupId>org.thingsboard.common</groupId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>2.5.2-SNAPSHOT</version> 23 + <version>3.0.1-SNAPSHOT</version>
24 <artifactId>thingsboard</artifactId> 24 <artifactId>thingsboard</artifactId>
25 </parent> 25 </parent>
26 <artifactId>common</artifactId> 26 <artifactId>common</artifactId>
@@ -37,6 +37,7 @@ @@ -37,6 +37,7 @@
37 <module>data</module> 37 <module>data</module>
38 <module>util</module> 38 <module>util</module>
39 <module>message</module> 39 <module>message</module>
  40 + <module>actor</module>
40 <module>queue</module> 41 <module>queue</module>
41 <module>transport</module> 42 <module>transport</module>
42 <module>dao-api</module> 43 <module>dao-api</module>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>2.5.2-SNAPSHOT</version> 23 + <version>3.0.1-SNAPSHOT</version>
24 <artifactId>common</artifactId> 24 <artifactId>common</artifactId>
25 </parent> 25 </parent>
26 <groupId>org.thingsboard.common</groupId> 26 <groupId>org.thingsboard.common</groupId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard.common</groupId> 22 <groupId>org.thingsboard.common</groupId>
23 - <version>2.5.2-SNAPSHOT</version> 23 + <version>3.0.1-SNAPSHOT</version>
24 <artifactId>transport</artifactId> 24 <artifactId>transport</artifactId>
25 </parent> 25 </parent>
26 <groupId>org.thingsboard.common.transport</groupId> 26 <groupId>org.thingsboard.common.transport</groupId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard.common</groupId> 22 <groupId>org.thingsboard.common</groupId>
23 - <version>2.5.2-SNAPSHOT</version> 23 + <version>3.0.1-SNAPSHOT</version>
24 <artifactId>transport</artifactId> 24 <artifactId>transport</artifactId>
25 </parent> 25 </parent>
26 <groupId>org.thingsboard.common.transport</groupId> 26 <groupId>org.thingsboard.common.transport</groupId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard.common</groupId> 22 <groupId>org.thingsboard.common</groupId>
23 - <version>2.5.2-SNAPSHOT</version> 23 + <version>3.0.1-SNAPSHOT</version>
24 <artifactId>transport</artifactId> 24 <artifactId>transport</artifactId>
25 </parent> 25 </parent>
26 <groupId>org.thingsboard.common.transport</groupId> 26 <groupId>org.thingsboard.common.transport</groupId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>2.5.2-SNAPSHOT</version> 23 + <version>3.0.1-SNAPSHOT</version>
24 <artifactId>common</artifactId> 24 <artifactId>common</artifactId>
25 </parent> 25 </parent>
26 <groupId>org.thingsboard.common</groupId> 26 <groupId>org.thingsboard.common</groupId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard.common</groupId> 22 <groupId>org.thingsboard.common</groupId>
23 - <version>2.5.2-SNAPSHOT</version> 23 + <version>3.0.1-SNAPSHOT</version>
24 <artifactId>transport</artifactId> 24 <artifactId>transport</artifactId>
25 </parent> 25 </parent>
26 <groupId>org.thingsboard.common.transport</groupId> 26 <groupId>org.thingsboard.common.transport</groupId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>2.5.2-SNAPSHOT</version> 23 + <version>3.0.1-SNAPSHOT</version>
24 <artifactId>common</artifactId> 24 <artifactId>common</artifactId>
25 </parent> 25 </parent>
26 <groupId>org.thingsboard.common</groupId> 26 <groupId>org.thingsboard.common</groupId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>2.5.2-SNAPSHOT</version> 23 + <version>3.0.1-SNAPSHOT</version>
24 <artifactId>thingsboard</artifactId> 24 <artifactId>thingsboard</artifactId>
25 </parent> 25 </parent>
26 <artifactId>dao</artifactId> 26 <artifactId>dao</artifactId>
@@ -4,15 +4,15 @@ This folder containing scripts and Kubernetes resources configurations to run Th @@ -4,15 +4,15 @@ This folder containing scripts and Kubernetes resources configurations to run Th
4 4
5 ## Prerequisites 5 ## Prerequisites
6 6
7 -ThingsBoard Microservices are running on Kubernetes cluster. 7 +ThingsBoard Microservices run on the Kubernetes cluster.
8 You need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. 8 You need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster.
9 -If you do not already have a cluster, you can create one by using [Minikube](https://kubernetes.io/docs/setup/minikube), 9 +If you do not have a cluster already, you can create one by using [Minikube](https://kubernetes.io/docs/setup/minikube),
10 or you can choose any other available [Kubernetes cluster deployment solutions](https://kubernetes.io/docs/setup/pick-right-solution/). 10 or you can choose any other available [Kubernetes cluster deployment solutions](https://kubernetes.io/docs/setup/pick-right-solution/).
11 11
12 ### Enable ingress addon 12 ### Enable ingress addon
13 13
14 -By default ingress addon is disable in the Minikube, and available only in cluster providers.  
15 -To enable ingress, please execute next command: 14 +By default ingress addon is disabled in the Minikube, and available only in cluster providers.
  15 +To enable ingress, please execute the following command:
16 16
17 ` 17 `
18 $ minikube addons enable ingress 18 $ minikube addons enable ingress
@@ -21,21 +21,21 @@ $ minikube addons enable ingress @@ -21,21 +21,21 @@ $ minikube addons enable ingress
21 ## Installation 21 ## Installation
22 22
23 Before performing initial installation you can configure the type of database to be used with ThingsBoard and the type of deployment. 23 Before performing initial installation you can configure the type of database to be used with ThingsBoard and the type of deployment.
24 -In order to set database type change the value of `DATABASE` variable in `.env` file to one of the following: 24 +To set database type change the value of `DATABASE` variable in `.env` file to one of the following:
25 25
26 - `postgres` - use PostgreSQL database; 26 - `postgres` - use PostgreSQL database;
27 - `hybrid` - use PostgreSQL for entities database and Cassandra for timeseries database; 27 - `hybrid` - use PostgreSQL for entities database and Cassandra for timeseries database;
28 28
29 **NOTE**: According to the database type corresponding kubernetes resources will be deployed (see `postgres.yml`, `cassandra.yml` for details). 29 **NOTE**: According to the database type corresponding kubernetes resources will be deployed (see `postgres.yml`, `cassandra.yml` for details).
30 30
31 -In order to set deployment type change the value of `DEPLOYMENT_TYPE` variable in `.env` file to one of the following: 31 +To set deployment type change the value of `DEPLOYMENT_TYPE` variable in `.env` file to one of the following:
32 32
33 -- `basic` - start up with single instance of Zookeeper, Kafka and Redis;  
34 -- `high-availability` - start up with Zookeeper, Kafka and Redis in cluster modes; 33 +- `basic` - startup with a single instance of Zookeeper, Kafka and Redis;
  34 +- `high-availability` - startup with Zookeeper, Kafka, and Redis in cluster modes;
35 35
36 -**NOTE**: According to the deployment type corresponding kubernetes resources will be deployed (see content of the directories `./basic` and `./high-availability` for details). 36 +**NOTE**: According to the deployment type corresponding kubernetes resources will be deployed (see the content of the directories `./basic` and `./high-availability` for details).
37 37
38 -Execute the following command to run installation: 38 +Execute the following command to run the installation:
39 39
40 ` 40 `
41 $ ./k8s-install-tb.sh --loadDemo 41 $ ./k8s-install-tb.sh --loadDemo
@@ -47,7 +47,7 @@ Where: @@ -47,7 +47,7 @@ Where:
47 47
48 ## Running 48 ## Running
49 49
50 -Execute the following command to deploy thirdparty resources: 50 +Execute the following command to deploy third-party resources:
51 51
52 ` 52 `
53 $ ./k8s-deploy-thirdparty.sh 53 $ ./k8s-deploy-thirdparty.sh
@@ -61,8 +61,8 @@ Execute the following command to deploy resources: @@ -61,8 +61,8 @@ Execute the following command to deploy resources:
61 $ ./k8s-deploy-resources.sh 61 $ ./k8s-deploy-resources.sh
62 ` 62 `
63 63
64 -After a while when all resources will be successfully started you can open `http://{your-cluster-ip}` in you browser (for ex. `http://192.168.99.101`).  
65 -You should see ThingsBoard login page. 64 +After a while when all resources will be successfully started you can open `http://{your-cluster-ip}` in your browser (for ex. `http://192.168.99.101`).
  65 +You should see the ThingsBoard login page.
66 66
67 Use the following default credentials: 67 Use the following default credentials:
68 68
@@ -73,16 +73,16 @@ If you installed DataBase with demo data (using `--loadDemo` flag) you can also @@ -73,16 +73,16 @@ If you installed DataBase with demo data (using `--loadDemo` flag) you can also
73 - **Tenant Administrator**: tenant@thingsboard.org / tenant 73 - **Tenant Administrator**: tenant@thingsboard.org / tenant
74 - **Customer User**: customer@thingsboard.org / customer 74 - **Customer User**: customer@thingsboard.org / customer
75 75
76 -In case of any issues you can examine service logs for errors. 76 +In case of any issues, you can examine service logs for errors.
77 For example to see ThingsBoard node logs execute the following commands: 77 For example to see ThingsBoard node logs execute the following commands:
78 78
79 -1) Get list of the running tb-node pods: 79 +1) Get the list of the running tb-node pods:
80 80
81 ` 81 `
82 $ kubectl get pods -l app=tb-node 82 $ kubectl get pods -l app=tb-node
83 ` 83 `
84 84
85 -2) Fetch logs of tb-node pod: 85 +2) Fetch logs of the tb-node pod:
86 86
87 ` 87 `
88 $ kubectl logs -f [tb-node-pod-name] 88 $ kubectl logs -f [tb-node-pod-name]
@@ -103,7 +103,7 @@ Execute the following command to delete all ThingsBoard microservices: @@ -103,7 +103,7 @@ Execute the following command to delete all ThingsBoard microservices:
103 $ ./k8s-delete-resources.sh 103 $ ./k8s-delete-resources.sh
104 ` 104 `
105 105
106 -Execute the following command to delete all thirdparty microservices: 106 +Execute the following command to delete all third-party microservices:
107 107
108 ` 108 `
109 $ ./k8s-delete-thirdparty.sh 109 $ ./k8s-delete-thirdparty.sh
@@ -21,7 +21,7 @@ @@ -21,7 +21,7 @@
21 21
22 <parent> 22 <parent>
23 <groupId>org.thingsboard</groupId> 23 <groupId>org.thingsboard</groupId>
24 - <version>2.5.2-SNAPSHOT</version> 24 + <version>3.0.1-SNAPSHOT</version>
25 <artifactId>msa</artifactId> 25 <artifactId>msa</artifactId>
26 </parent> 26 </parent>
27 <groupId>org.thingsboard.msa</groupId> 27 <groupId>org.thingsboard.msa</groupId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>2.5.2-SNAPSHOT</version> 23 + <version>3.0.1-SNAPSHOT</version>
24 <artifactId>msa</artifactId> 24 <artifactId>msa</artifactId>
25 </parent> 25 </parent>
26 <groupId>org.thingsboard.msa</groupId> 26 <groupId>org.thingsboard.msa</groupId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>2.5.2-SNAPSHOT</version> 23 + <version>3.0.1-SNAPSHOT</version>
24 <artifactId>thingsboard</artifactId> 24 <artifactId>thingsboard</artifactId>
25 </parent> 25 </parent>
26 <artifactId>msa</artifactId> 26 <artifactId>msa</artifactId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>2.5.2-SNAPSHOT</version> 23 + <version>3.0.1-SNAPSHOT</version>
24 <artifactId>msa</artifactId> 24 <artifactId>msa</artifactId>
25 </parent> 25 </parent>
26 <groupId>org.thingsboard.msa</groupId> 26 <groupId>org.thingsboard.msa</groupId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>2.5.2-SNAPSHOT</version> 23 + <version>3.0.1-SNAPSHOT</version>
24 <artifactId>msa</artifactId> 24 <artifactId>msa</artifactId>
25 </parent> 25 </parent>
26 <groupId>org.thingsboard.msa</groupId> 26 <groupId>org.thingsboard.msa</groupId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard.msa</groupId> 22 <groupId>org.thingsboard.msa</groupId>
23 - <version>2.5.2-SNAPSHOT</version> 23 + <version>3.0.1-SNAPSHOT</version>
24 <artifactId>transport</artifactId> 24 <artifactId>transport</artifactId>
25 </parent> 25 </parent>
26 <groupId>org.thingsboard.msa.transport</groupId> 26 <groupId>org.thingsboard.msa.transport</groupId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard.msa</groupId> 22 <groupId>org.thingsboard.msa</groupId>
23 - <version>2.5.2-SNAPSHOT</version> 23 + <version>3.0.1-SNAPSHOT</version>
24 <artifactId>transport</artifactId> 24 <artifactId>transport</artifactId>
25 </parent> 25 </parent>
26 <groupId>org.thingsboard.msa.transport</groupId> 26 <groupId>org.thingsboard.msa.transport</groupId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard.msa</groupId> 22 <groupId>org.thingsboard.msa</groupId>
23 - <version>2.5.2-SNAPSHOT</version> 23 + <version>3.0.1-SNAPSHOT</version>
24 <artifactId>transport</artifactId> 24 <artifactId>transport</artifactId>
25 </parent> 25 </parent>
26 <groupId>org.thingsboard.msa.transport</groupId> 26 <groupId>org.thingsboard.msa.transport</groupId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>2.5.2-SNAPSHOT</version> 23 + <version>3.0.1-SNAPSHOT</version>
24 <artifactId>msa</artifactId> 24 <artifactId>msa</artifactId>
25 </parent> 25 </parent>
26 <groupId>org.thingsboard.msa</groupId> 26 <groupId>org.thingsboard.msa</groupId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>2.5.2-SNAPSHOT</version> 23 + <version>3.0.1-SNAPSHOT</version>
24 <artifactId>msa</artifactId> 24 <artifactId>msa</artifactId>
25 </parent> 25 </parent>
26 <groupId>org.thingsboard.msa</groupId> 26 <groupId>org.thingsboard.msa</groupId>
@@ -19,11 +19,11 @@ @@ -19,11 +19,11 @@
19 <modelVersion>4.0.0</modelVersion> 19 <modelVersion>4.0.0</modelVersion>
20 <parent> 20 <parent>
21 <groupId>org.thingsboard</groupId> 21 <groupId>org.thingsboard</groupId>
22 - <version>2.5.2-SNAPSHOT</version> 22 + <version>3.0.1-SNAPSHOT</version>
23 <artifactId>thingsboard</artifactId> 23 <artifactId>thingsboard</artifactId>
24 </parent> 24 </parent>
25 <artifactId>netty-mqtt</artifactId> 25 <artifactId>netty-mqtt</artifactId>
26 - <version>2.5.2-SNAPSHOT</version> 26 + <version>3.0.1-SNAPSHOT</version>
27 <packaging>jar</packaging> 27 <packaging>jar</packaging>
28 28
29 <name>Netty MQTT Client</name> 29 <name>Netty MQTT Client</name>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <groupId>org.thingsboard</groupId> 21 <groupId>org.thingsboard</groupId>
22 <artifactId>thingsboard</artifactId> 22 <artifactId>thingsboard</artifactId>
23 - <version>2.5.2-SNAPSHOT</version> 23 + <version>3.0.1-SNAPSHOT</version>
24 <packaging>pom</packaging> 24 <packaging>pom</packaging>
25 25
26 <name>Thingsboard</name> 26 <name>Thingsboard</name>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>2.5.2-SNAPSHOT</version> 23 + <version>3.0.1-SNAPSHOT</version>
24 <artifactId>thingsboard</artifactId> 24 <artifactId>thingsboard</artifactId>
25 </parent> 25 </parent>
26 <artifactId>rest-client</artifactId> 26 <artifactId>rest-client</artifactId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>2.5.2-SNAPSHOT</version> 23 + <version>3.0.1-SNAPSHOT</version>
24 <artifactId>thingsboard</artifactId> 24 <artifactId>thingsboard</artifactId>
25 </parent> 25 </parent>
26 <artifactId>rule-engine</artifactId> 26 <artifactId>rule-engine</artifactId>
@@ -22,7 +22,7 @@ @@ -22,7 +22,7 @@
22 <modelVersion>4.0.0</modelVersion> 22 <modelVersion>4.0.0</modelVersion>
23 <parent> 23 <parent>
24 <groupId>org.thingsboard</groupId> 24 <groupId>org.thingsboard</groupId>
25 - <version>2.5.2-SNAPSHOT</version> 25 + <version>3.0.1-SNAPSHOT</version>
26 <artifactId>rule-engine</artifactId> 26 <artifactId>rule-engine</artifactId>
27 </parent> 27 </parent>
28 <groupId>org.thingsboard.rule-engine</groupId> 28 <groupId>org.thingsboard.rule-engine</groupId>
@@ -22,7 +22,7 @@ @@ -22,7 +22,7 @@
22 <modelVersion>4.0.0</modelVersion> 22 <modelVersion>4.0.0</modelVersion>
23 <parent> 23 <parent>
24 <groupId>org.thingsboard</groupId> 24 <groupId>org.thingsboard</groupId>
25 - <version>2.5.2-SNAPSHOT</version> 25 + <version>3.0.1-SNAPSHOT</version>
26 <artifactId>rule-engine</artifactId> 26 <artifactId>rule-engine</artifactId>
27 </parent> 27 </parent>
28 <groupId>org.thingsboard.rule-engine</groupId> 28 <groupId>org.thingsboard.rule-engine</groupId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>2.5.2-SNAPSHOT</version> 23 + <version>3.0.1-SNAPSHOT</version>
24 <artifactId>thingsboard</artifactId> 24 <artifactId>thingsboard</artifactId>
25 </parent> 25 </parent>
26 <artifactId>tools</artifactId> 26 <artifactId>tools</artifactId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>2.5.2-SNAPSHOT</version> 23 + <version>3.0.1-SNAPSHOT</version>
24 <artifactId>transport</artifactId> 24 <artifactId>transport</artifactId>
25 </parent> 25 </parent>
26 <groupId>org.thingsboard.transport</groupId> 26 <groupId>org.thingsboard.transport</groupId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>2.5.2-SNAPSHOT</version> 23 + <version>3.0.1-SNAPSHOT</version>
24 <artifactId>transport</artifactId> 24 <artifactId>transport</artifactId>
25 </parent> 25 </parent>
26 <groupId>org.thingsboard.transport</groupId> 26 <groupId>org.thingsboard.transport</groupId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>2.5.2-SNAPSHOT</version> 23 + <version>3.0.1-SNAPSHOT</version>
24 <artifactId>transport</artifactId> 24 <artifactId>transport</artifactId>
25 </parent> 25 </parent>
26 <groupId>org.thingsboard.transport</groupId> 26 <groupId>org.thingsboard.transport</groupId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>2.5.2-SNAPSHOT</version> 23 + <version>3.0.1-SNAPSHOT</version>
24 <artifactId>thingsboard</artifactId> 24 <artifactId>thingsboard</artifactId>
25 </parent> 25 </parent>
26 <artifactId>transport</artifactId> 26 <artifactId>transport</artifactId>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <modelVersion>4.0.0</modelVersion> 20 <modelVersion>4.0.0</modelVersion>
21 <parent> 21 <parent>
22 <groupId>org.thingsboard</groupId> 22 <groupId>org.thingsboard</groupId>
23 - <version>2.5.2-SNAPSHOT</version> 23 + <version>3.0.1-SNAPSHOT</version>
24 <artifactId>thingsboard</artifactId> 24 <artifactId>thingsboard</artifactId>
25 </parent> 25 </parent>
26 <groupId>org.thingsboard</groupId> 26 <groupId>org.thingsboard</groupId>
@@ -86,6 +86,11 @@ tb-widget-editor { @@ -86,6 +86,11 @@ tb-widget-editor {
86 height: 100%; 86 height: 100%;
87 } 87 }
88 } 88 }
  89 +
  90 + .container{
  91 + width: 100%;
  92 + height: 100%;
  93 + }
89 } 94 }
90 95
91 .tb-split-vertical { 96 .tb-split-vertical {