Showing
58 changed files
with
1209 additions
and
55 deletions
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>2.5.2-SNAPSHOT</version> | |
23 | + <version>3.0.1-SNAPSHOT</version> | |
24 | 24 | <artifactId>thingsboard</artifactId> |
25 | 25 | </parent> |
26 | 26 | <artifactId>application</artifactId> | ... | ... |
... | ... | @@ -48,8 +48,6 @@ public class CassandraTsDatabaseUpgradeService extends AbstractCassandraDatabase |
48 | 48 | } |
49 | 49 | log.info("Schema updated."); |
50 | 50 | break; |
51 | - case "2.5.0": | |
52 | - break; | |
53 | 51 | default: |
54 | 52 | throw new RuntimeException("Unable to upgrade Cassandra database, unsupported fromVersion: " + fromVersion); |
55 | 53 | } | ... | ... |
common/actor/pom.xml
0 → 100644
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 | +} | ... | ... |
common/actor/src/main/java/org/thingsboard/server/actors/TbActorNotRegisteredException.java
0 → 100644
1 | +/** | |
2 | + * Copyright © 2016-2020 The Thingsboard Authors | |
3 | + * | |
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | + * you may not use this file except in compliance with the License. | |
6 | + * You may obtain a copy of the License at | |
7 | + * | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | + * | |
10 | + * Unless required by applicable law or agreed to in writing, software | |
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | + * See the License for the specific language governing permissions and | |
14 | + * limitations under the License. | |
15 | + */ | |
16 | +package org.thingsboard.server.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 | +} | ... | ... |
common/actor/src/test/resources/logback.xml
0 → 100644
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 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>2.5.2-SNAPSHOT</version> | |
23 | + <version>3.0.1-SNAPSHOT</version> | |
24 | 24 | <artifactId>common</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.common</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>2.5.2-SNAPSHOT</version> | |
23 | + <version>3.0.1-SNAPSHOT</version> | |
24 | 24 | <artifactId>common</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.common</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>2.5.2-SNAPSHOT</version> | |
23 | + <version>3.0.1-SNAPSHOT</version> | |
24 | 24 | <artifactId>common</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.common</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>2.5.2-SNAPSHOT</version> | |
23 | + <version>3.0.1-SNAPSHOT</version> | |
24 | 24 | <artifactId>thingsboard</artifactId> |
25 | 25 | </parent> |
26 | 26 | <artifactId>common</artifactId> |
... | ... | @@ -37,6 +37,7 @@ |
37 | 37 | <module>data</module> |
38 | 38 | <module>util</module> |
39 | 39 | <module>message</module> |
40 | + <module>actor</module> | |
40 | 41 | <module>queue</module> |
41 | 42 | <module>transport</module> |
42 | 43 | <module>dao-api</module> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>2.5.2-SNAPSHOT</version> | |
23 | + <version>3.0.1-SNAPSHOT</version> | |
24 | 24 | <artifactId>common</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.common</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard.common</groupId> |
23 | - <version>2.5.2-SNAPSHOT</version> | |
23 | + <version>3.0.1-SNAPSHOT</version> | |
24 | 24 | <artifactId>transport</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.common.transport</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard.common</groupId> |
23 | - <version>2.5.2-SNAPSHOT</version> | |
23 | + <version>3.0.1-SNAPSHOT</version> | |
24 | 24 | <artifactId>transport</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.common.transport</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard.common</groupId> |
23 | - <version>2.5.2-SNAPSHOT</version> | |
23 | + <version>3.0.1-SNAPSHOT</version> | |
24 | 24 | <artifactId>transport</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.common.transport</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>2.5.2-SNAPSHOT</version> | |
23 | + <version>3.0.1-SNAPSHOT</version> | |
24 | 24 | <artifactId>common</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.common</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard.common</groupId> |
23 | - <version>2.5.2-SNAPSHOT</version> | |
23 | + <version>3.0.1-SNAPSHOT</version> | |
24 | 24 | <artifactId>transport</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.common.transport</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>2.5.2-SNAPSHOT</version> | |
23 | + <version>3.0.1-SNAPSHOT</version> | |
24 | 24 | <artifactId>common</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.common</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>2.5.2-SNAPSHOT</version> | |
23 | + <version>3.0.1-SNAPSHOT</version> | |
24 | 24 | <artifactId>thingsboard</artifactId> |
25 | 25 | </parent> |
26 | 26 | <artifactId>dao</artifactId> | ... | ... |
... | ... | @@ -4,15 +4,15 @@ This folder containing scripts and Kubernetes resources configurations to run Th |
4 | 4 | |
5 | 5 | ## Prerequisites |
6 | 6 | |
7 | -ThingsBoard Microservices are running on Kubernetes cluster. | |
7 | +ThingsBoard Microservices run on the Kubernetes cluster. | |
8 | 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 | 10 | or you can choose any other available [Kubernetes cluster deployment solutions](https://kubernetes.io/docs/setup/pick-right-solution/). |
11 | 11 | |
12 | 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 | 18 | $ minikube addons enable ingress |
... | ... | @@ -21,21 +21,21 @@ $ minikube addons enable ingress |
21 | 21 | ## Installation |
22 | 22 | |
23 | 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 | 26 | - `postgres` - use PostgreSQL database; |
27 | 27 | - `hybrid` - use PostgreSQL for entities database and Cassandra for timeseries database; |
28 | 28 | |
29 | 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 | 41 | $ ./k8s-install-tb.sh --loadDemo |
... | ... | @@ -47,7 +47,7 @@ Where: |
47 | 47 | |
48 | 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 | 53 | $ ./k8s-deploy-thirdparty.sh |
... | ... | @@ -61,8 +61,8 @@ Execute the following command to deploy resources: |
61 | 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 | 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 | 73 | - **Tenant Administrator**: tenant@thingsboard.org / tenant |
74 | 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 | 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 | 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 | 88 | $ kubectl logs -f [tb-node-pod-name] |
... | ... | @@ -103,7 +103,7 @@ Execute the following command to delete all ThingsBoard microservices: |
103 | 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 | 109 | $ ./k8s-delete-thirdparty.sh | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>2.5.2-SNAPSHOT</version> | |
23 | + <version>3.0.1-SNAPSHOT</version> | |
24 | 24 | <artifactId>msa</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.msa</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>2.5.2-SNAPSHOT</version> | |
23 | + <version>3.0.1-SNAPSHOT</version> | |
24 | 24 | <artifactId>thingsboard</artifactId> |
25 | 25 | </parent> |
26 | 26 | <artifactId>msa</artifactId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>2.5.2-SNAPSHOT</version> | |
23 | + <version>3.0.1-SNAPSHOT</version> | |
24 | 24 | <artifactId>msa</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.msa</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>2.5.2-SNAPSHOT</version> | |
23 | + <version>3.0.1-SNAPSHOT</version> | |
24 | 24 | <artifactId>msa</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.msa</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard.msa</groupId> |
23 | - <version>2.5.2-SNAPSHOT</version> | |
23 | + <version>3.0.1-SNAPSHOT</version> | |
24 | 24 | <artifactId>transport</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.msa.transport</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard.msa</groupId> |
23 | - <version>2.5.2-SNAPSHOT</version> | |
23 | + <version>3.0.1-SNAPSHOT</version> | |
24 | 24 | <artifactId>transport</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.msa.transport</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard.msa</groupId> |
23 | - <version>2.5.2-SNAPSHOT</version> | |
23 | + <version>3.0.1-SNAPSHOT</version> | |
24 | 24 | <artifactId>transport</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.msa.transport</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>2.5.2-SNAPSHOT</version> | |
23 | + <version>3.0.1-SNAPSHOT</version> | |
24 | 24 | <artifactId>msa</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.msa</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>2.5.2-SNAPSHOT</version> | |
23 | + <version>3.0.1-SNAPSHOT</version> | |
24 | 24 | <artifactId>msa</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.msa</groupId> | ... | ... |
... | ... | @@ -19,11 +19,11 @@ |
19 | 19 | <modelVersion>4.0.0</modelVersion> |
20 | 20 | <parent> |
21 | 21 | <groupId>org.thingsboard</groupId> |
22 | - <version>2.5.2-SNAPSHOT</version> | |
22 | + <version>3.0.1-SNAPSHOT</version> | |
23 | 23 | <artifactId>thingsboard</artifactId> |
24 | 24 | </parent> |
25 | 25 | <artifactId>netty-mqtt</artifactId> |
26 | - <version>2.5.2-SNAPSHOT</version> | |
26 | + <version>3.0.1-SNAPSHOT</version> | |
27 | 27 | <packaging>jar</packaging> |
28 | 28 | |
29 | 29 | <name>Netty MQTT Client</name> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <groupId>org.thingsboard</groupId> |
22 | 22 | <artifactId>thingsboard</artifactId> |
23 | - <version>2.5.2-SNAPSHOT</version> | |
23 | + <version>3.0.1-SNAPSHOT</version> | |
24 | 24 | <packaging>pom</packaging> |
25 | 25 | |
26 | 26 | <name>Thingsboard</name> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>2.5.2-SNAPSHOT</version> | |
23 | + <version>3.0.1-SNAPSHOT</version> | |
24 | 24 | <artifactId>thingsboard</artifactId> |
25 | 25 | </parent> |
26 | 26 | <artifactId>rest-client</artifactId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>2.5.2-SNAPSHOT</version> | |
23 | + <version>3.0.1-SNAPSHOT</version> | |
24 | 24 | <artifactId>thingsboard</artifactId> |
25 | 25 | </parent> |
26 | 26 | <artifactId>rule-engine</artifactId> | ... | ... |
... | ... | @@ -22,7 +22,7 @@ |
22 | 22 | <modelVersion>4.0.0</modelVersion> |
23 | 23 | <parent> |
24 | 24 | <groupId>org.thingsboard</groupId> |
25 | - <version>2.5.2-SNAPSHOT</version> | |
25 | + <version>3.0.1-SNAPSHOT</version> | |
26 | 26 | <artifactId>rule-engine</artifactId> |
27 | 27 | </parent> |
28 | 28 | <groupId>org.thingsboard.rule-engine</groupId> | ... | ... |
... | ... | @@ -22,7 +22,7 @@ |
22 | 22 | <modelVersion>4.0.0</modelVersion> |
23 | 23 | <parent> |
24 | 24 | <groupId>org.thingsboard</groupId> |
25 | - <version>2.5.2-SNAPSHOT</version> | |
25 | + <version>3.0.1-SNAPSHOT</version> | |
26 | 26 | <artifactId>rule-engine</artifactId> |
27 | 27 | </parent> |
28 | 28 | <groupId>org.thingsboard.rule-engine</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>2.5.2-SNAPSHOT</version> | |
23 | + <version>3.0.1-SNAPSHOT</version> | |
24 | 24 | <artifactId>thingsboard</artifactId> |
25 | 25 | </parent> |
26 | 26 | <artifactId>tools</artifactId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>2.5.2-SNAPSHOT</version> | |
23 | + <version>3.0.1-SNAPSHOT</version> | |
24 | 24 | <artifactId>transport</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.transport</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>2.5.2-SNAPSHOT</version> | |
23 | + <version>3.0.1-SNAPSHOT</version> | |
24 | 24 | <artifactId>transport</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.transport</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>2.5.2-SNAPSHOT</version> | |
23 | + <version>3.0.1-SNAPSHOT</version> | |
24 | 24 | <artifactId>transport</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.transport</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>2.5.2-SNAPSHOT</version> | |
23 | + <version>3.0.1-SNAPSHOT</version> | |
24 | 24 | <artifactId>thingsboard</artifactId> |
25 | 25 | </parent> |
26 | 26 | <artifactId>transport</artifactId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>2.5.2-SNAPSHOT</version> | |
23 | + <version>3.0.1-SNAPSHOT</version> | |
24 | 24 | <artifactId>thingsboard</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard</groupId> | ... | ... |