Commit ca8f04e1e970f319515e9d08c409355dd6c4189c

Authored by Vladyslav_Prykhodko
2 parents 22a1d242 5120ccb5

Merge remote-tracking branch 'upstream/master' into feature/dashboard/widget-select-preview

Showing 100 changed files with 499 additions and 264 deletions

Too many changes to show.

To preserve performance only 100 of 187 files are displayed.

@@ -275,7 +275,7 @@ @@ -275,7 +275,7 @@
275 </dependency> 275 </dependency>
276 <dependency> 276 <dependency>
277 <groupId>org.mockito</groupId> 277 <groupId>org.mockito</groupId>
278 - <artifactId>mockito-all</artifactId> 278 + <artifactId>mockito-core</artifactId>
279 <scope>test</scope> 279 <scope>test</scope>
280 </dependency> 280 </dependency>
281 <dependency> 281 <dependency>
@@ -15,11 +15,10 @@ @@ -15,11 +15,10 @@
15 # 15 #
16 16
17 export JAVA_OPTS="$JAVA_OPTS -Dplatform=@pkg.platform@ -Dinstall.data_dir=@pkg.installFolder@/data" 17 export JAVA_OPTS="$JAVA_OPTS -Dplatform=@pkg.platform@ -Dinstall.data_dir=@pkg.installFolder@/data"
18 -export JAVA_OPTS="$JAVA_OPTS -Xloggc:@pkg.logFolder@/gc.log -XX:+IgnoreUnrecognizedVMOptions -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDetails -XX:+PrintGCDateStamps"  
19 -export JAVA_OPTS="$JAVA_OPTS -XX:+PrintHeapAtGC -XX:+PrintTenuringDistribution -XX:+PrintGCApplicationStoppedTime -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10"  
20 -export JAVA_OPTS="$JAVA_OPTS -XX:GCLogFileSize=10M -XX:-UseBiasedLocking -XX:+UseTLAB -XX:+ResizeTLAB -XX:+PerfDisableSharedMem -XX:+UseCondCardMark"  
21 -export JAVA_OPTS="$JAVA_OPTS -XX:CMSWaitDuration=10000 -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+CMSParallelInitialMarkEnabled"  
22 -export JAVA_OPTS="$JAVA_OPTS -XX:+CMSEdenChunksRecordAlways -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly" 18 +export JAVA_OPTS="$JAVA_OPTS -Xlog:gc*,heap*,age*,safepoint=debug:file=@pkg.logFolder@/gc.log:time,uptime,level,tags:filecount=10,filesize=10M"
  19 +export JAVA_OPTS="$JAVA_OPTS -XX:+IgnoreUnrecognizedVMOptions -XX:+HeapDumpOnOutOfMemoryError"
  20 +export JAVA_OPTS="$JAVA_OPTS -XX:-UseBiasedLocking -XX:+UseTLAB -XX:+ResizeTLAB -XX:+PerfDisableSharedMem -XX:+UseCondCardMark"
  21 +export JAVA_OPTS="$JAVA_OPTS -XX:+UseG1GC -XX:MaxGCPauseMillis=500 -XX:+UseStringDeduplication -XX:+ParallelRefProcEnabled -XX:MaxTenuringThreshold=10"
23 export LOG_FILENAME=${pkg.name}.out 22 export LOG_FILENAME=${pkg.name}.out
24 export LOADER_PATH=${pkg.installFolder}/conf,${pkg.installFolder}/extensions 23 export LOADER_PATH=${pkg.installFolder}/conf,${pkg.installFolder}/extensions
25 export SQL_DATA_FOLDER=${pkg.installFolder}/data/sql 24 export SQL_DATA_FOLDER=${pkg.installFolder}/data/sql
@@ -134,12 +134,12 @@ public class AppActor extends ContextAwareActor { @@ -134,12 +134,12 @@ public class AppActor extends ContextAwareActor {
134 134
135 private void onQueueToRuleEngineMsg(QueueToRuleEngineMsg msg) { 135 private void onQueueToRuleEngineMsg(QueueToRuleEngineMsg msg) {
136 if (TenantId.SYS_TENANT_ID.equals(msg.getTenantId())) { 136 if (TenantId.SYS_TENANT_ID.equals(msg.getTenantId())) {
137 - msg.getTbMsg().getCallback().onFailure(new RuleEngineException("Message has system tenant id!")); 137 + msg.getMsg().getCallback().onFailure(new RuleEngineException("Message has system tenant id!"));
138 } else { 138 } else {
139 if (!deletedTenants.contains(msg.getTenantId())) { 139 if (!deletedTenants.contains(msg.getTenantId())) {
140 getOrCreateTenantActor(msg.getTenantId()).tell(msg); 140 getOrCreateTenantActor(msg.getTenantId()).tell(msg);
141 } else { 141 } else {
142 - msg.getTbMsg().getCallback().onSuccess(); 142 + msg.getMsg().getCallback().onSuccess();
143 } 143 }
144 } 144 }
145 } 145 }
@@ -19,7 +19,6 @@ import com.fasterxml.jackson.core.JsonProcessingException; @@ -19,7 +19,6 @@ import com.fasterxml.jackson.core.JsonProcessingException;
19 import com.fasterxml.jackson.databind.ObjectMapper; 19 import com.fasterxml.jackson.databind.ObjectMapper;
20 import io.netty.channel.EventLoopGroup; 20 import io.netty.channel.EventLoopGroup;
21 import lombok.extern.slf4j.Slf4j; 21 import lombok.extern.slf4j.Slf4j;
22 -import org.springframework.data.redis.core.RedisTemplate;  
23 import org.springframework.util.StringUtils; 22 import org.springframework.util.StringUtils;
24 import org.thingsboard.common.util.ListeningExecutor; 23 import org.thingsboard.common.util.ListeningExecutor;
25 import org.thingsboard.rule.engine.api.MailService; 24 import org.thingsboard.rule.engine.api.MailService;
@@ -34,7 +33,6 @@ import org.thingsboard.rule.engine.api.TbRelationTypes; @@ -34,7 +33,6 @@ import org.thingsboard.rule.engine.api.TbRelationTypes;
34 import org.thingsboard.rule.engine.api.sms.SmsSenderFactory; 33 import org.thingsboard.rule.engine.api.sms.SmsSenderFactory;
35 import org.thingsboard.server.actors.ActorSystemContext; 34 import org.thingsboard.server.actors.ActorSystemContext;
36 import org.thingsboard.server.actors.TbActorRef; 35 import org.thingsboard.server.actors.TbActorRef;
37 -import org.thingsboard.server.common.data.ApiUsageRecordKey;  
38 import org.thingsboard.server.common.data.Customer; 36 import org.thingsboard.server.common.data.Customer;
39 import org.thingsboard.server.common.data.DataConstants; 37 import org.thingsboard.server.common.data.DataConstants;
40 import org.thingsboard.server.common.data.Device; 38 import org.thingsboard.server.common.data.Device;
@@ -90,10 +88,12 @@ class DefaultTbContext implements TbContext { @@ -90,10 +88,12 @@ class DefaultTbContext implements TbContext {
90 public final static ObjectMapper mapper = new ObjectMapper(); 88 public final static ObjectMapper mapper = new ObjectMapper();
91 89
92 private final ActorSystemContext mainCtx; 90 private final ActorSystemContext mainCtx;
  91 + private final String ruleChainName;
93 private final RuleNodeCtx nodeCtx; 92 private final RuleNodeCtx nodeCtx;
94 93
95 - public DefaultTbContext(ActorSystemContext mainCtx, RuleNodeCtx nodeCtx) { 94 + public DefaultTbContext(ActorSystemContext mainCtx, String ruleChainName, RuleNodeCtx nodeCtx) {
96 this.mainCtx = mainCtx; 95 this.mainCtx = mainCtx;
  96 + this.ruleChainName = ruleChainName;
97 this.nodeCtx = nodeCtx; 97 this.nodeCtx = nodeCtx;
98 } 98 }
99 99
@@ -117,13 +117,13 @@ class DefaultTbContext implements TbContext { @@ -117,13 +117,13 @@ class DefaultTbContext implements TbContext {
117 relationTypes.forEach(relationType -> mainCtx.persistDebugOutput(nodeCtx.getTenantId(), nodeCtx.getSelf().getId(), msg, relationType, th)); 117 relationTypes.forEach(relationType -> mainCtx.persistDebugOutput(nodeCtx.getTenantId(), nodeCtx.getSelf().getId(), msg, relationType, th));
118 } 118 }
119 msg.getCallback().onProcessingEnd(nodeCtx.getSelf().getId()); 119 msg.getCallback().onProcessingEnd(nodeCtx.getSelf().getId());
120 - nodeCtx.getChainActor().tell(new RuleNodeToRuleChainTellNextMsg(nodeCtx.getSelf().getId(), relationTypes, msg, th != null ? th.getMessage() : null)); 120 + nodeCtx.getChainActor().tell(new RuleNodeToRuleChainTellNextMsg(nodeCtx.getSelf().getRuleChainId(), nodeCtx.getSelf().getId(), relationTypes, msg, th != null ? th.getMessage() : null));
121 } 121 }
122 122
123 @Override 123 @Override
124 public void tellSelf(TbMsg msg, long delayMs) { 124 public void tellSelf(TbMsg msg, long delayMs) {
125 //TODO: add persistence layer 125 //TODO: add persistence layer
126 - scheduleMsgWithDelay(new RuleNodeToSelfMsg(msg), delayMs, nodeCtx.getSelfActor()); 126 + scheduleMsgWithDelay(new RuleNodeToSelfMsg(this, msg), delayMs, nodeCtx.getSelfActor());
127 } 127 }
128 128
129 @Override 129 @Override
@@ -254,7 +254,8 @@ class DefaultTbContext implements TbContext { @@ -254,7 +254,8 @@ class DefaultTbContext implements TbContext {
254 } else { 254 } else {
255 failureMessage = null; 255 failureMessage = null;
256 } 256 }
257 - nodeCtx.getChainActor().tell(new RuleNodeToRuleChainTellNextMsg(nodeCtx.getSelf().getId(), Collections.singleton(TbRelationTypes.FAILURE), 257 + nodeCtx.getChainActor().tell(new RuleNodeToRuleChainTellNextMsg(nodeCtx.getSelf().getRuleChainId(),
  258 + nodeCtx.getSelf().getId(), Collections.singleton(TbRelationTypes.FAILURE),
258 msg, failureMessage)); 259 msg, failureMessage));
259 } 260 }
260 261
@@ -302,6 +303,16 @@ class DefaultTbContext implements TbContext { @@ -302,6 +303,16 @@ class DefaultTbContext implements TbContext {
302 } 303 }
303 304
304 @Override 305 @Override
  306 + public RuleNode getSelf() {
  307 + return nodeCtx.getSelf();
  308 + }
  309 +
  310 + @Override
  311 + public String getRuleChainName() {
  312 + return ruleChainName;
  313 + }
  314 +
  315 + @Override
305 public TenantId getTenantId() { 316 public TenantId getTenantId() {
306 return nodeCtx.getTenantId(); 317 return nodeCtx.getTenantId();
307 } 318 }
@@ -476,11 +487,6 @@ class DefaultTbContext implements TbContext { @@ -476,11 +487,6 @@ class DefaultTbContext implements TbContext {
476 } 487 }
477 488
478 @Override 489 @Override
479 - public RedisTemplate<String, Object> getRedisTemplate() {  
480 - return mainCtx.getRedisTemplate();  
481 - }  
482 -  
483 - @Override  
484 public PageData<RuleNodeState> findRuleNodeStates(PageLink pageLink) { 490 public PageData<RuleNodeState> findRuleNodeStates(PageLink pageLink) {
485 if (log.isDebugEnabled()) { 491 if (log.isDebugEnabled()) {
486 log.debug("[{}][{}] Fetch Rule Node States.", getTenantId(), getSelfId()); 492 log.debug("[{}][{}] Fetch Rule Node States.", getTenantId(), getSelfId());
@@ -23,7 +23,6 @@ import org.thingsboard.server.actors.TbActorRef; @@ -23,7 +23,6 @@ import org.thingsboard.server.actors.TbActorRef;
23 import org.thingsboard.server.actors.TbEntityActorId; 23 import org.thingsboard.server.actors.TbEntityActorId;
24 import org.thingsboard.server.actors.service.DefaultActorService; 24 import org.thingsboard.server.actors.service.DefaultActorService;
25 import org.thingsboard.server.actors.shared.ComponentMsgProcessor; 25 import org.thingsboard.server.actors.shared.ComponentMsgProcessor;
26 -import org.thingsboard.server.common.data.ApiUsageRecordKey;  
27 import org.thingsboard.server.common.data.EntityType; 26 import org.thingsboard.server.common.data.EntityType;
28 import org.thingsboard.server.common.data.id.EntityId; 27 import org.thingsboard.server.common.data.id.EntityId;
29 import org.thingsboard.server.common.data.id.RuleChainId; 28 import org.thingsboard.server.common.data.id.RuleChainId;
@@ -197,11 +196,11 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh @@ -197,11 +196,11 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh
197 } 196 }
198 197
199 void onQueueToRuleEngineMsg(QueueToRuleEngineMsg envelope) { 198 void onQueueToRuleEngineMsg(QueueToRuleEngineMsg envelope) {
200 - TbMsg msg = envelope.getTbMsg(); 199 + TbMsg msg = envelope.getMsg();
201 log.trace("[{}][{}] Processing message [{}]: {}", entityId, firstId, msg.getId(), msg); 200 log.trace("[{}][{}] Processing message [{}]: {}", entityId, firstId, msg.getId(), msg);
202 if (envelope.getRelationTypes() == null || envelope.getRelationTypes().isEmpty()) { 201 if (envelope.getRelationTypes() == null || envelope.getRelationTypes().isEmpty()) {
203 try { 202 try {
204 - checkActive(envelope.getTbMsg()); 203 + checkActive(envelope.getMsg());
205 RuleNodeId targetId = msg.getRuleNodeId(); 204 RuleNodeId targetId = msg.getRuleNodeId();
206 RuleNodeCtx targetCtx; 205 RuleNodeCtx targetCtx;
207 if (targetId == null) { 206 if (targetId == null) {
@@ -218,12 +217,12 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh @@ -218,12 +217,12 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh
218 msg.getCallback().onSuccess(); 217 msg.getCallback().onSuccess();
219 } 218 }
220 } catch (RuleNodeException rne) { 219 } catch (RuleNodeException rne) {
221 - envelope.getTbMsg().getCallback().onFailure(rne); 220 + envelope.getMsg().getCallback().onFailure(rne);
222 } catch (Exception e) { 221 } catch (Exception e) {
223 - envelope.getTbMsg().getCallback().onFailure(new RuleEngineException(e.getMessage())); 222 + envelope.getMsg().getCallback().onFailure(new RuleEngineException(e.getMessage()));
224 } 223 }
225 } else { 224 } else {
226 - onTellNext(envelope.getTbMsg(), envelope.getTbMsg().getRuleNodeId(), envelope.getRelationTypes(), envelope.getFailureMessage()); 225 + onTellNext(envelope.getMsg(), envelope.getMsg().getRuleNodeId(), envelope.getRelationTypes(), envelope.getFailureMessage());
227 } 226 }
228 } 227 }
229 228
@@ -335,7 +334,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh @@ -335,7 +334,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh
335 334
336 private void pushMsgToNode(RuleNodeCtx nodeCtx, TbMsg msg, String fromRelationType) { 335 private void pushMsgToNode(RuleNodeCtx nodeCtx, TbMsg msg, String fromRelationType) {
337 if (nodeCtx != null) { 336 if (nodeCtx != null) {
338 - nodeCtx.getSelfActor().tell(new RuleChainToRuleNodeMsg(new DefaultTbContext(systemContext, nodeCtx), msg, fromRelationType)); 337 + nodeCtx.getSelfActor().tell(new RuleChainToRuleNodeMsg(new DefaultTbContext(systemContext, ruleChainName, nodeCtx), msg, fromRelationType));
339 } else { 338 } else {
340 log.error("[{}][{}] RuleNodeCtx is empty", entityId, ruleChainName); 339 log.error("[{}][{}] RuleNodeCtx is empty", entityId, ruleChainName);
341 msg.getCallback().onFailure(new RuleEngineException("Rule Node CTX is empty")); 340 msg.getCallback().onFailure(new RuleEngineException("Rule Node CTX is empty"));
@@ -15,24 +15,44 @@ @@ -15,24 +15,44 @@
15 */ 15 */
16 package org.thingsboard.server.actors.ruleChain; 16 package org.thingsboard.server.actors.ruleChain;
17 17
18 -import lombok.Data; 18 +import lombok.EqualsAndHashCode;
  19 +import lombok.Getter;
  20 +import lombok.ToString;
19 import org.thingsboard.server.common.data.id.RuleChainId; 21 import org.thingsboard.server.common.data.id.RuleChainId;
20 import org.thingsboard.server.common.msg.MsgType; 22 import org.thingsboard.server.common.msg.MsgType;
21 -import org.thingsboard.server.common.msg.TbActorMsg; 23 +import org.thingsboard.server.common.msg.TbActorStopReason;
22 import org.thingsboard.server.common.msg.TbMsg; 24 import org.thingsboard.server.common.msg.TbMsg;
  25 +import org.thingsboard.server.common.msg.TbRuleEngineActorMsg;
23 import org.thingsboard.server.common.msg.aware.RuleChainAwareMsg; 26 import org.thingsboard.server.common.msg.aware.RuleChainAwareMsg;
  27 +import org.thingsboard.server.common.msg.queue.RuleEngineException;
24 28
25 /** 29 /**
26 * Created by ashvayka on 19.03.18. 30 * Created by ashvayka on 19.03.18.
27 */ 31 */
28 -@Data  
29 -public final class RuleChainToRuleChainMsg implements TbActorMsg, RuleChainAwareMsg { 32 +@EqualsAndHashCode(callSuper = true)
  33 +@ToString
  34 +public final class RuleChainToRuleChainMsg extends TbRuleEngineActorMsg implements RuleChainAwareMsg {
30 35
  36 + @Getter
31 private final RuleChainId target; 37 private final RuleChainId target;
  38 + @Getter
32 private final RuleChainId source; 39 private final RuleChainId source;
33 - private final TbMsg msg; 40 + @Getter
34 private final String fromRelationType; 41 private final String fromRelationType;
35 42
  43 + public RuleChainToRuleChainMsg(RuleChainId target, RuleChainId source, TbMsg tbMsg, String fromRelationType) {
  44 + super(tbMsg);
  45 + this.target = target;
  46 + this.source = source;
  47 + this.fromRelationType = fromRelationType;
  48 + }
  49 +
  50 + @Override
  51 + public void onTbActorStopped(TbActorStopReason reason) {
  52 + String message = reason == TbActorStopReason.STOPPED ? String.format("Rule chain [%s] stopped", target.getId()) : String.format("Failed to initialize rule chain [%s]!", target.getId());
  53 + msg.getCallback().onFailure(new RuleEngineException(message));
  54 + }
  55 +
36 @Override 56 @Override
37 public RuleChainId getRuleChainId() { 57 public RuleChainId getRuleChainId() {
38 return target; 58 return target;
@@ -15,22 +15,28 @@ @@ -15,22 +15,28 @@
15 */ 15 */
16 package org.thingsboard.server.actors.ruleChain; 16 package org.thingsboard.server.actors.ruleChain;
17 17
18 -import lombok.Data; 18 +import lombok.EqualsAndHashCode;
  19 +import lombok.Getter;
  20 +import lombok.ToString;
19 import org.thingsboard.rule.engine.api.TbContext; 21 import org.thingsboard.rule.engine.api.TbContext;
20 import org.thingsboard.server.common.msg.MsgType; 22 import org.thingsboard.server.common.msg.MsgType;
21 -import org.thingsboard.server.common.msg.TbActorMsg;  
22 import org.thingsboard.server.common.msg.TbMsg; 23 import org.thingsboard.server.common.msg.TbMsg;
23 24
24 /** 25 /**
25 * Created by ashvayka on 19.03.18. 26 * Created by ashvayka on 19.03.18.
26 */ 27 */
27 -@Data  
28 -final class RuleChainToRuleNodeMsg implements TbActorMsg { 28 +@EqualsAndHashCode(callSuper = true)
  29 +@ToString
  30 +final class RuleChainToRuleNodeMsg extends TbToRuleNodeActorMsg {
29 31
30 - private final TbContext ctx;  
31 - private final TbMsg msg; 32 + @Getter
32 private final String fromRelationType; 33 private final String fromRelationType;
33 34
  35 + public RuleChainToRuleNodeMsg(TbContext ctx, TbMsg tbMsg, String fromRelationType) {
  36 + super(ctx, tbMsg);
  37 + this.fromRelationType = fromRelationType;
  38 + }
  39 +
34 @Override 40 @Override
35 public MsgType getMsgType() { 41 public MsgType getMsgType() {
36 return MsgType.RULE_CHAIN_TO_RULE_MSG; 42 return MsgType.RULE_CHAIN_TO_RULE_MSG;
@@ -59,9 +59,6 @@ public class RuleNodeActor extends ComponentActor<RuleNodeId, RuleNodeActorMessa @@ -59,9 +59,6 @@ public class RuleNodeActor extends ComponentActor<RuleNodeId, RuleNodeActorMessa
59 case RULE_CHAIN_TO_RULE_MSG: 59 case RULE_CHAIN_TO_RULE_MSG:
60 onRuleChainToRuleNodeMsg((RuleChainToRuleNodeMsg) msg); 60 onRuleChainToRuleNodeMsg((RuleChainToRuleNodeMsg) msg);
61 break; 61 break;
62 - case RULE_TO_SELF_ERROR_MSG:  
63 - onRuleNodeToSelfErrorMsg((RuleNodeToSelfErrorMsg) msg);  
64 - break;  
65 case RULE_TO_SELF_MSG: 62 case RULE_TO_SELF_MSG:
66 onRuleNodeToSelfMsg((RuleNodeToSelfMsg) msg); 63 onRuleNodeToSelfMsg((RuleNodeToSelfMsg) msg);
67 break; 64 break;
@@ -101,10 +98,6 @@ public class RuleNodeActor extends ComponentActor<RuleNodeId, RuleNodeActorMessa @@ -101,10 +98,6 @@ public class RuleNodeActor extends ComponentActor<RuleNodeId, RuleNodeActorMessa
101 } 98 }
102 } 99 }
103 100
104 - private void onRuleNodeToSelfErrorMsg(RuleNodeToSelfErrorMsg msg) {  
105 - logAndPersist("onRuleMsg", ActorSystemContext.toException(msg.getError()));  
106 - }  
107 -  
108 public static class ActorCreator extends ContextBasedCreator { 101 public static class ActorCreator extends ContextBasedCreator {
109 102
110 private final TenantId tenantId; 103 private final TenantId tenantId;
@@ -54,7 +54,7 @@ public class RuleNodeActorMessageProcessor extends ComponentMsgProcessor<RuleNod @@ -54,7 +54,7 @@ public class RuleNodeActorMessageProcessor extends ComponentMsgProcessor<RuleNod
54 this.ruleChainName = ruleChainName; 54 this.ruleChainName = ruleChainName;
55 this.self = self; 55 this.self = self;
56 this.ruleNode = systemContext.getRuleChainService().findRuleNodeById(tenantId, entityId); 56 this.ruleNode = systemContext.getRuleChainService().findRuleNodeById(tenantId, entityId);
57 - this.defaultCtx = new DefaultTbContext(systemContext, new RuleNodeCtx(tenantId, parent, self, ruleNode)); 57 + this.defaultCtx = new DefaultTbContext(systemContext, ruleChainName, new RuleNodeCtx(tenantId, parent, self, ruleNode));
58 this.info = new RuleNodeInfo(ruleNodeId, ruleChainName, ruleNode != null ? ruleNode.getName() : "Unknown"); 58 this.info = new RuleNodeInfo(ruleNodeId, ruleChainName, ruleNode != null ? ruleNode.getName() : "Unknown");
59 } 59 }
60 60
@@ -147,7 +147,7 @@ public class RuleNodeActorMessageProcessor extends ComponentMsgProcessor<RuleNod @@ -147,7 +147,7 @@ public class RuleNodeActorMessageProcessor extends ComponentMsgProcessor<RuleNod
147 TbNode tbNode = null; 147 TbNode tbNode = null;
148 if (ruleNode != null) { 148 if (ruleNode != null) {
149 Class<?> componentClazz = Class.forName(ruleNode.getType()); 149 Class<?> componentClazz = Class.forName(ruleNode.getType());
150 - tbNode = (TbNode) (componentClazz.newInstance()); 150 + tbNode = (TbNode) (componentClazz.getDeclaredConstructor().newInstance());
151 tbNode.init(defaultCtx, new TbNodeConfiguration(ruleNode.getConfiguration())); 151 tbNode.init(defaultCtx, new TbNodeConfiguration(ruleNode.getConfiguration()));
152 } 152 }
153 return tbNode; 153 return tbNode;
@@ -15,11 +15,16 @@ @@ -15,11 +15,16 @@
15 */ 15 */
16 package org.thingsboard.server.actors.ruleChain; 16 package org.thingsboard.server.actors.ruleChain;
17 17
18 -import lombok.Data; 18 +import lombok.EqualsAndHashCode;
  19 +import lombok.Getter;
  20 +import lombok.ToString;
  21 +import org.thingsboard.server.common.data.id.RuleChainId;
19 import org.thingsboard.server.common.data.id.RuleNodeId; 22 import org.thingsboard.server.common.data.id.RuleNodeId;
20 import org.thingsboard.server.common.msg.MsgType; 23 import org.thingsboard.server.common.msg.MsgType;
21 -import org.thingsboard.server.common.msg.TbActorMsg; 24 +import org.thingsboard.server.common.msg.TbActorStopReason;
22 import org.thingsboard.server.common.msg.TbMsg; 25 import org.thingsboard.server.common.msg.TbMsg;
  26 +import org.thingsboard.server.common.msg.TbRuleEngineActorMsg;
  27 +import org.thingsboard.server.common.msg.queue.RuleEngineException;
23 28
24 import java.io.Serializable; 29 import java.io.Serializable;
25 import java.util.Set; 30 import java.util.Set;
@@ -27,15 +32,34 @@ import java.util.Set; @@ -27,15 +32,34 @@ import java.util.Set;
27 /** 32 /**
28 * Created by ashvayka on 19.03.18. 33 * Created by ashvayka on 19.03.18.
29 */ 34 */
30 -@Data  
31 -class RuleNodeToRuleChainTellNextMsg implements TbActorMsg, Serializable { 35 +@EqualsAndHashCode(callSuper = true)
  36 +@ToString
  37 +class RuleNodeToRuleChainTellNextMsg extends TbRuleEngineActorMsg implements Serializable {
32 38
33 private static final long serialVersionUID = 4577026446412871820L; 39 private static final long serialVersionUID = 4577026446412871820L;
  40 + @Getter
  41 + private final RuleChainId ruleChainId;
  42 + @Getter
34 private final RuleNodeId originator; 43 private final RuleNodeId originator;
  44 + @Getter
35 private final Set<String> relationTypes; 45 private final Set<String> relationTypes;
36 - private final TbMsg msg; 46 + @Getter
37 private final String failureMessage; 47 private final String failureMessage;
38 48
  49 + public RuleNodeToRuleChainTellNextMsg(RuleChainId ruleChainId, RuleNodeId originator, Set<String> relationTypes, TbMsg tbMsg, String failureMessage) {
  50 + super(tbMsg);
  51 + this.ruleChainId = ruleChainId;
  52 + this.originator = originator;
  53 + this.relationTypes = relationTypes;
  54 + this.failureMessage = failureMessage;
  55 + }
  56 +
  57 + @Override
  58 + public void onTbActorStopped(TbActorStopReason reason) {
  59 + String message = reason == TbActorStopReason.STOPPED ? String.format("Rule chain [%s] stopped", ruleChainId.getId()) : String.format("Failed to initialize rule chain [%s]!", ruleChainId.getId());
  60 + msg.getCallback().onFailure(new RuleEngineException(message));
  61 + }
  62 +
39 @Override 63 @Override
40 public MsgType getMsgType() { 64 public MsgType getMsgType() {
41 return MsgType.RULE_TO_RULE_CHAIN_TELL_NEXT_MSG; 65 return MsgType.RULE_TO_RULE_CHAIN_TELL_NEXT_MSG;
@@ -15,18 +15,25 @@ @@ -15,18 +15,25 @@
15 */ 15 */
16 package org.thingsboard.server.actors.ruleChain; 16 package org.thingsboard.server.actors.ruleChain;
17 17
18 -import lombok.Data; 18 +import lombok.EqualsAndHashCode;
  19 +import lombok.ToString;
  20 +import org.thingsboard.rule.engine.api.TbContext;
19 import org.thingsboard.server.common.msg.MsgType; 21 import org.thingsboard.server.common.msg.MsgType;
20 -import org.thingsboard.server.common.msg.TbActorMsg; 22 +import org.thingsboard.server.common.msg.TbActorStopReason;
21 import org.thingsboard.server.common.msg.TbMsg; 23 import org.thingsboard.server.common.msg.TbMsg;
  24 +import org.thingsboard.server.common.msg.TbRuleEngineActorMsg;
  25 +import org.thingsboard.server.common.msg.queue.RuleNodeException;
22 26
23 /** 27 /**
24 * Created by ashvayka on 19.03.18. 28 * Created by ashvayka on 19.03.18.
25 */ 29 */
26 -@Data  
27 -final class RuleNodeToSelfMsg implements TbActorMsg { 30 +@EqualsAndHashCode(callSuper = true)
  31 +@ToString
  32 +final class RuleNodeToSelfMsg extends TbToRuleNodeActorMsg {
28 33
29 - private final TbMsg msg; 34 + public RuleNodeToSelfMsg(TbContext ctx, TbMsg tbMsg) {
  35 + super(ctx, tbMsg);
  36 + }
30 37
31 @Override 38 @Override
32 public MsgType getMsgType() { 39 public MsgType getMsgType() {
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.actors.ruleChain;
  17 +
  18 +import lombok.EqualsAndHashCode;
  19 +import lombok.Getter;
  20 +import org.thingsboard.rule.engine.api.TbContext;
  21 +import org.thingsboard.server.common.msg.TbActorStopReason;
  22 +import org.thingsboard.server.common.msg.TbMsg;
  23 +import org.thingsboard.server.common.msg.TbRuleEngineActorMsg;
  24 +import org.thingsboard.server.common.msg.queue.RuleNodeException;
  25 +
  26 +@EqualsAndHashCode(callSuper = true)
  27 +public abstract class TbToRuleNodeActorMsg extends TbRuleEngineActorMsg {
  28 +
  29 + @Getter
  30 + private final TbContext ctx;
  31 +
  32 + public TbToRuleNodeActorMsg(TbContext ctx, TbMsg tbMsg) {
  33 + super(tbMsg);
  34 + this.ctx = ctx;
  35 + }
  36 +
  37 + @Override
  38 + public void onTbActorStopped(TbActorStopReason reason) {
  39 + String message = reason == TbActorStopReason.STOPPED ? "Rule node stopped" : "Failed to initialize rule node!";
  40 + msg.getCallback().onFailure(new RuleNodeException(message, ctx.getRuleChainName(), ctx.getSelf()));
  41 + }
  42 +}
@@ -28,10 +28,10 @@ import org.thingsboard.server.common.msg.TbActorMsg; @@ -28,10 +28,10 @@ import org.thingsboard.server.common.msg.TbActorMsg;
28 @ToString 28 @ToString
29 public final class StatsPersistMsg implements TbActorMsg { 29 public final class StatsPersistMsg implements TbActorMsg {
30 30
31 - private long messagesProcessed;  
32 - private long errorsOccurred;  
33 - private TenantId tenantId;  
34 - private EntityId entityId; 31 + private final long messagesProcessed;
  32 + private final long errorsOccurred;
  33 + private final TenantId tenantId;
  34 + private final EntityId entityId;
35 35
36 @Override 36 @Override
37 public MsgType getMsgType() { 37 public MsgType getMsgType() {
@@ -18,7 +18,7 @@ package org.thingsboard.server.actors.stats; @@ -18,7 +18,7 @@ package org.thingsboard.server.actors.stats;
18 import org.thingsboard.server.common.msg.MsgType; 18 import org.thingsboard.server.common.msg.MsgType;
19 import org.thingsboard.server.common.msg.TbActorMsg; 19 import org.thingsboard.server.common.msg.TbActorMsg;
20 20
21 -public final class StatsPersistTick implements TbActorMsg{ 21 +public final class StatsPersistTick implements TbActorMsg {
22 @Override 22 @Override
23 public MsgType getMsgType() { 23 public MsgType getMsgType() {
24 return MsgType.STATS_PERSIST_TICK_MSG; 24 return MsgType.STATS_PERSIST_TICK_MSG;
@@ -119,7 +119,7 @@ public class TenantActor extends RuleChainManagerActor { @@ -119,7 +119,7 @@ public class TenantActor extends RuleChainManagerActor {
119 log.info("[{}] Processing missing Tenant msg: {}", tenantId, msg); 119 log.info("[{}] Processing missing Tenant msg: {}", tenantId, msg);
120 if (msg.getMsgType().equals(MsgType.QUEUE_TO_RULE_ENGINE_MSG)) { 120 if (msg.getMsgType().equals(MsgType.QUEUE_TO_RULE_ENGINE_MSG)) {
121 QueueToRuleEngineMsg queueMsg = (QueueToRuleEngineMsg) msg; 121 QueueToRuleEngineMsg queueMsg = (QueueToRuleEngineMsg) msg;
122 - queueMsg.getTbMsg().getCallback().onSuccess(); 122 + queueMsg.getMsg().getCallback().onSuccess();
123 } else if (msg.getMsgType().equals(MsgType.TRANSPORT_TO_DEVICE_ACTOR_MSG)) { 123 } else if (msg.getMsgType().equals(MsgType.TRANSPORT_TO_DEVICE_ACTOR_MSG)) {
124 TransportToDeviceActorMsgWrapper transportMsg = (TransportToDeviceActorMsgWrapper) msg; 124 TransportToDeviceActorMsgWrapper transportMsg = (TransportToDeviceActorMsgWrapper) msg;
125 transportMsg.getCallback().onSuccess(); 125 transportMsg.getCallback().onSuccess();
@@ -177,7 +177,7 @@ public class TenantActor extends RuleChainManagerActor { @@ -177,7 +177,7 @@ public class TenantActor extends RuleChainManagerActor {
177 log.warn("RECEIVED INVALID MESSAGE: {}", msg); 177 log.warn("RECEIVED INVALID MESSAGE: {}", msg);
178 return; 178 return;
179 } 179 }
180 - TbMsg tbMsg = msg.getTbMsg(); 180 + TbMsg tbMsg = msg.getMsg();
181 if (apiUsageState.isReExecEnabled()) { 181 if (apiUsageState.isReExecEnabled()) {
182 if (tbMsg.getRuleChainId() == null) { 182 if (tbMsg.getRuleChainId() == null) {
183 if (getRootChainActor() != null) { 183 if (getRootChainActor() != null) {
@@ -91,6 +91,7 @@ public class CustomOAuth2AuthorizationRequestResolver implements OAuth2Authoriza @@ -91,6 +91,7 @@ public class CustomOAuth2AuthorizationRequestResolver implements OAuth2Authoriza
91 return action; 91 return action;
92 } 92 }
93 93
  94 + @SuppressWarnings("deprecation")
94 private OAuth2AuthorizationRequest resolve(HttpServletRequest request, String registrationId, String redirectUriAction) { 95 private OAuth2AuthorizationRequest resolve(HttpServletRequest request, String registrationId, String redirectUriAction) {
95 if (registrationId == null) { 96 if (registrationId == null) {
96 return null; 97 return null;
@@ -127,7 +127,7 @@ public class ThingsboardSecurityConfiguration extends WebSecurityConfigurerAdapt @@ -127,7 +127,7 @@ public class ThingsboardSecurityConfiguration extends WebSecurityConfigurerAdapt
127 } 127 }
128 128
129 protected JwtTokenAuthenticationProcessingFilter buildJwtTokenAuthenticationProcessingFilter() throws Exception { 129 protected JwtTokenAuthenticationProcessingFilter buildJwtTokenAuthenticationProcessingFilter() throws Exception {
130 - List<String> pathsToSkip = new ArrayList(Arrays.asList(NON_TOKEN_BASED_AUTH_ENTRY_POINTS)); 130 + List<String> pathsToSkip = new ArrayList<>(Arrays.asList(NON_TOKEN_BASED_AUTH_ENTRY_POINTS));
131 pathsToSkip.addAll(Arrays.asList(WS_TOKEN_BASED_AUTH_ENTRY_POINT, TOKEN_REFRESH_ENTRY_POINT, FORM_BASED_LOGIN_ENTRY_POINT, 131 pathsToSkip.addAll(Arrays.asList(WS_TOKEN_BASED_AUTH_ENTRY_POINT, TOKEN_REFRESH_ENTRY_POINT, FORM_BASED_LOGIN_ENTRY_POINT,
132 PUBLIC_LOGIN_ENTRY_POINT, DEVICE_API_ENTRY_POINT, WEBJARS_ENTRY_POINT)); 132 PUBLIC_LOGIN_ENTRY_POINT, DEVICE_API_ENTRY_POINT, WEBJARS_ENTRY_POINT));
133 SkipPathRequestMatcher matcher = new SkipPathRequestMatcher(pathsToSkip, TOKEN_BASED_AUTH_ENTRY_POINT); 133 SkipPathRequestMatcher matcher = new SkipPathRequestMatcher(pathsToSkip, TOKEN_BASED_AUTH_ENTRY_POINT);
@@ -645,6 +645,7 @@ public abstract class BaseController { @@ -645,6 +645,7 @@ public abstract class BaseController {
645 return ruleNode; 645 return ruleNode;
646 } 646 }
647 647
  648 + @SuppressWarnings("unchecked")
648 protected <I extends EntityId> I emptyId(EntityType entityType) { 649 protected <I extends EntityId> I emptyId(EntityType entityType) {
649 return (I) EntityIdFactory.getByTypeAndUuid(entityType, ModelConstants.NULL_UUID); 650 return (I) EntityIdFactory.getByTypeAndUuid(entityType, ModelConstants.NULL_UUID);
650 } 651 }
@@ -759,6 +760,7 @@ public abstract class BaseController { @@ -759,6 +760,7 @@ public abstract class BaseController {
759 entityNode = json.createObjectNode(); 760 entityNode = json.createObjectNode();
760 if (actionType == ActionType.ATTRIBUTES_UPDATED) { 761 if (actionType == ActionType.ATTRIBUTES_UPDATED) {
761 String scope = extractParameter(String.class, 0, additionalInfo); 762 String scope = extractParameter(String.class, 0, additionalInfo);
  763 + @SuppressWarnings("unchecked")
762 List<AttributeKvEntry> attributes = extractParameter(List.class, 1, additionalInfo); 764 List<AttributeKvEntry> attributes = extractParameter(List.class, 1, additionalInfo);
763 metaData.putValue("scope", scope); 765 metaData.putValue("scope", scope);
764 if (attributes != null) { 766 if (attributes != null) {
@@ -768,6 +770,7 @@ public abstract class BaseController { @@ -768,6 +770,7 @@ public abstract class BaseController {
768 } 770 }
769 } else if (actionType == ActionType.ATTRIBUTES_DELETED) { 771 } else if (actionType == ActionType.ATTRIBUTES_DELETED) {
770 String scope = extractParameter(String.class, 0, additionalInfo); 772 String scope = extractParameter(String.class, 0, additionalInfo);
  773 + @SuppressWarnings("unchecked")
771 List<String> keys = extractParameter(List.class, 1, additionalInfo); 774 List<String> keys = extractParameter(List.class, 1, additionalInfo);
772 metaData.putValue("scope", scope); 775 metaData.putValue("scope", scope);
773 ArrayNode attrsArrayNode = entityNode.putArray("attributes"); 776 ArrayNode attrsArrayNode = entityNode.putArray("attributes");
@@ -775,9 +778,11 @@ public abstract class BaseController { @@ -775,9 +778,11 @@ public abstract class BaseController {
775 keys.forEach(attrsArrayNode::add); 778 keys.forEach(attrsArrayNode::add);
776 } 779 }
777 } else if (actionType == ActionType.TIMESERIES_UPDATED) { 780 } else if (actionType == ActionType.TIMESERIES_UPDATED) {
  781 + @SuppressWarnings("unchecked")
778 List<TsKvEntry> timeseries = extractParameter(List.class, 0, additionalInfo); 782 List<TsKvEntry> timeseries = extractParameter(List.class, 0, additionalInfo);
779 addTimeseries(entityNode, timeseries); 783 addTimeseries(entityNode, timeseries);
780 } else if (actionType == ActionType.TIMESERIES_DELETED) { 784 } else if (actionType == ActionType.TIMESERIES_DELETED) {
  785 + @SuppressWarnings("unchecked")
781 List<String> keys = extractParameter(List.class, 0, additionalInfo); 786 List<String> keys = extractParameter(List.class, 0, additionalInfo);
782 if (keys != null) { 787 if (keys != null) {
783 ArrayNode timeseriesArrayNode = entityNode.putArray("timeseries"); 788 ArrayNode timeseriesArrayNode = entityNode.putArray("timeseries");
@@ -63,7 +63,7 @@ import java.util.List; @@ -63,7 +63,7 @@ import java.util.List;
63 import java.util.concurrent.ExecutionException; 63 import java.util.concurrent.ExecutionException;
64 import java.util.stream.Collectors; 64 import java.util.stream.Collectors;
65 65
66 -import static org.apache.commons.lang.StringUtils.isBlank; 66 +import static org.apache.commons.lang3.StringUtils.isBlank;
67 import static org.thingsboard.server.controller.CustomerController.CUSTOMER_ID; 67 import static org.thingsboard.server.controller.CustomerController.CUSTOMER_ID;
68 68
69 /** 69 /**
@@ -24,6 +24,7 @@ import org.springframework.beans.factory.annotation.Value; @@ -24,6 +24,7 @@ import org.springframework.beans.factory.annotation.Value;
24 import org.springframework.beans.factory.config.BeanDefinition; 24 import org.springframework.beans.factory.config.BeanDefinition;
25 import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; 25 import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
26 import org.springframework.core.env.Environment; 26 import org.springframework.core.env.Environment;
  27 +import org.springframework.core.env.Profiles;
27 import org.springframework.core.type.filter.AnnotationTypeFilter; 28 import org.springframework.core.type.filter.AnnotationTypeFilter;
28 import org.springframework.stereotype.Service; 29 import org.springframework.stereotype.Service;
29 import org.thingsboard.rule.engine.api.NodeConfiguration; 30 import org.thingsboard.rule.engine.api.NodeConfiguration;
@@ -69,7 +70,7 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe @@ -69,7 +70,7 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe
69 private ObjectMapper mapper = new ObjectMapper(); 70 private ObjectMapper mapper = new ObjectMapper();
70 71
71 private boolean isInstall() { 72 private boolean isInstall() {
72 - return environment.acceptsProfiles("install"); 73 + return environment.acceptsProfiles(Profiles.of("install"));
73 } 74 }
74 75
75 @PostConstruct 76 @PostConstruct
@@ -185,7 +186,7 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe @@ -185,7 +186,7 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe
185 nodeDefinition.setRelationTypes(getRelationTypesWithFailureRelation(nodeAnnotation)); 186 nodeDefinition.setRelationTypes(getRelationTypesWithFailureRelation(nodeAnnotation));
186 nodeDefinition.setCustomRelations(nodeAnnotation.customRelations()); 187 nodeDefinition.setCustomRelations(nodeAnnotation.customRelations());
187 Class<? extends NodeConfiguration> configClazz = nodeAnnotation.configClazz(); 188 Class<? extends NodeConfiguration> configClazz = nodeAnnotation.configClazz();
188 - NodeConfiguration config = configClazz.newInstance(); 189 + NodeConfiguration config = configClazz.getDeclaredConstructor().newInstance();
189 NodeConfiguration defaultConfiguration = config.defaultConfiguration(); 190 NodeConfiguration defaultConfiguration = config.defaultConfiguration();
190 nodeDefinition.setDefaultConfiguration(mapper.valueToTree(defaultConfiguration)); 191 nodeDefinition.setDefaultConfiguration(mapper.valueToTree(defaultConfiguration));
191 nodeDefinition.setUiResources(nodeAnnotation.uiResources()); 192 nodeDefinition.setUiResources(nodeAnnotation.uiResources());
@@ -20,7 +20,7 @@ import com.fasterxml.jackson.databind.JsonNode; @@ -20,7 +20,7 @@ import com.fasterxml.jackson.databind.JsonNode;
20 import com.fasterxml.jackson.databind.node.ObjectNode; 20 import com.fasterxml.jackson.databind.node.ObjectNode;
21 import com.google.common.util.concurrent.ListenableFuture; 21 import com.google.common.util.concurrent.ListenableFuture;
22 import lombok.extern.slf4j.Slf4j; 22 import lombok.extern.slf4j.Slf4j;
23 -import org.apache.commons.lang.RandomStringUtils; 23 +import org.apache.commons.lang3.RandomStringUtils;
24 import org.springframework.beans.factory.annotation.Autowired; 24 import org.springframework.beans.factory.annotation.Autowired;
25 import org.springframework.stereotype.Service; 25 import org.springframework.stereotype.Service;
26 import org.springframework.util.StringUtils; 26 import org.springframework.util.StringUtils;
@@ -146,17 +146,17 @@ public class CassandraDbHelper { @@ -146,17 +146,17 @@ public class CassandraDbHelper {
146 if (row.isNull(index)) { 146 if (row.isNull(index)) {
147 return null; 147 return null;
148 } else if (type.getProtocolCode() == ProtocolConstants.DataType.DOUBLE) { 148 } else if (type.getProtocolCode() == ProtocolConstants.DataType.DOUBLE) {
149 - str = new Double(row.getDouble(index)).toString(); 149 + str = Double.valueOf(row.getDouble(index)).toString();
150 } else if (type.getProtocolCode() == ProtocolConstants.DataType.INT) { 150 } else if (type.getProtocolCode() == ProtocolConstants.DataType.INT) {
151 - str = new Integer(row.getInt(index)).toString(); 151 + str = Integer.valueOf(row.getInt(index)).toString();
152 } else if (type.getProtocolCode() == ProtocolConstants.DataType.BIGINT) { 152 } else if (type.getProtocolCode() == ProtocolConstants.DataType.BIGINT) {
153 - str = new Long(row.getLong(index)).toString(); 153 + str = Long.valueOf(row.getLong(index)).toString();
154 } else if (type.getProtocolCode() == ProtocolConstants.DataType.UUID) { 154 } else if (type.getProtocolCode() == ProtocolConstants.DataType.UUID) {
155 str = row.getUuid(index).toString(); 155 str = row.getUuid(index).toString();
156 } else if (type.getProtocolCode() == ProtocolConstants.DataType.TIMEUUID) { 156 } else if (type.getProtocolCode() == ProtocolConstants.DataType.TIMEUUID) {
157 str = row.getUuid(index).toString(); 157 str = row.getUuid(index).toString();
158 } else if (type.getProtocolCode() == ProtocolConstants.DataType.FLOAT) { 158 } else if (type.getProtocolCode() == ProtocolConstants.DataType.FLOAT) {
159 - str = new Float(row.getFloat(index)).toString(); 159 + str = Float.valueOf(row.getFloat(index)).toString();
160 } else if (type.getProtocolCode() == ProtocolConstants.DataType.TIMESTAMP) { 160 } else if (type.getProtocolCode() == ProtocolConstants.DataType.TIMESTAMP) {
161 str = ""+row.getInstant(index).toEpochMilli(); 161 str = ""+row.getInstant(index).toEpochMilli();
162 } else { 162 } else {
@@ -153,7 +153,8 @@ public class CassandraToSqlColumn { @@ -153,7 +153,8 @@ public class CassandraToSqlColumn {
153 sqlInsertStatement.setBoolean(this.sqlIndex, Boolean.parseBoolean(value)); 153 sqlInsertStatement.setBoolean(this.sqlIndex, Boolean.parseBoolean(value));
154 break; 154 break;
155 case ENUM_TO_INT: 155 case ENUM_TO_INT:
156 - Enum enumVal = Enum.valueOf(this.enumClass, value); 156 + @SuppressWarnings("unchecked")
  157 + Enum<?> enumVal = Enum.valueOf(this.enumClass, value);
157 int intValue = enumVal.ordinal(); 158 int intValue = enumVal.ordinal();
158 sqlInsertStatement.setInt(this.sqlIndex, intValue); 159 sqlInsertStatement.setInt(this.sqlIndex, intValue);
159 break; 160 break;
@@ -57,7 +57,7 @@ import java.util.List; @@ -57,7 +57,7 @@ import java.util.List;
57 import java.util.concurrent.ExecutionException; 57 import java.util.concurrent.ExecutionException;
58 import java.util.stream.Collectors; 58 import java.util.stream.Collectors;
59 59
60 -import static org.apache.commons.lang.StringUtils.isBlank; 60 +import static org.apache.commons.lang3.StringUtils.isBlank;
61 import static org.thingsboard.server.service.install.DatabaseHelper.objectMapper; 61 import static org.thingsboard.server.service.install.DatabaseHelper.objectMapper;
62 62
63 @Service 63 @Service
@@ -206,7 +206,7 @@ public class DefaultEntityQueryService implements EntityQueryService { @@ -206,7 +206,7 @@ public class DefaultEntityQueryService implements EntityQueryService {
206 addItemsToArrayNode(json.putArray("entityTypes"), types); 206 addItemsToArrayNode(json.putArray("entityTypes"), types);
207 addItemsToArrayNode(json.putArray("timeseries"), timeseriesKeys); 207 addItemsToArrayNode(json.putArray("timeseries"), timeseriesKeys);
208 addItemsToArrayNode(json.putArray("attribute"), attributesKeys); 208 addItemsToArrayNode(json.putArray("attribute"), attributesKeys);
209 - response.setResult(new ResponseEntity(json, HttpStatus.OK)); 209 + response.setResult(new ResponseEntity<>(json, HttpStatus.OK));
210 } 210 }
211 211
212 private void replyWithEmptyResponse(DeferredResult<ResponseEntity> response) { 212 private void replyWithEmptyResponse(DeferredResult<ResponseEntity> response) {
@@ -181,7 +181,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< @@ -181,7 +181,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService<
181 new TbMsgPackCallback(id, tenantId, ctx, stats.getTimer(tenantId, SUCCESSFUL_STATUS), stats.getTimer(tenantId, FAILED_STATUS)) : 181 new TbMsgPackCallback(id, tenantId, ctx, stats.getTimer(tenantId, SUCCESSFUL_STATUS), stats.getTimer(tenantId, FAILED_STATUS)) :
182 new TbMsgPackCallback(id, tenantId, ctx); 182 new TbMsgPackCallback(id, tenantId, ctx);
183 try { 183 try {
184 - if (toRuleEngineMsg.getTbMsg() != null && !toRuleEngineMsg.getTbMsg().isEmpty()) { 184 + if (!toRuleEngineMsg.getTbMsg().isEmpty()) {
185 forwardToRuleEngineActor(configuration.getName(), tenantId, toRuleEngineMsg, callback); 185 forwardToRuleEngineActor(configuration.getName(), tenantId, toRuleEngineMsg, callback);
186 } else { 186 } else {
187 callback.onSuccess(); 187 callback.onSuccess();
@@ -209,6 +209,9 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< @@ -209,6 +209,9 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService<
209 if (statsEnabled) { 209 if (statsEnabled) {
210 stats.log(result, decision.isCommit()); 210 stats.log(result, decision.isCommit());
211 } 211 }
  212 +
  213 + ctx.cleanup();
  214 +
212 if (decision.isCommit()) { 215 if (decision.isCommit()) {
213 submitStrategy.stop(); 216 submitStrategy.stop();
214 break; 217 break;
@@ -147,4 +147,10 @@ public class TbMsgPackProcessingContext { @@ -147,4 +147,10 @@ public class TbMsgPackProcessingContext {
147 .forEach(info -> log.info("[{}][{}] execution count: {}. {}", queueName, info.getRuleNodeId(), info.getExecutionCount(), info.getLabel())); 147 .forEach(info -> log.info("[{}][{}] execution count: {}. {}", queueName, info.getRuleNodeId(), info.getExecutionCount(), info.getLabel()));
148 } 148 }
149 } 149 }
  150 +
  151 + public void cleanup() {
  152 + pendingMap.clear();
  153 + successMap.clear();
  154 + failedMap.clear();
  155 + }
150 } 156 }
@@ -31,6 +31,8 @@ import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest; @@ -31,6 +31,8 @@ import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest;
31 @RequiredArgsConstructor 31 @RequiredArgsConstructor
32 public class ToDeviceRpcRequestActorMsg implements ToDeviceActorNotificationMsg { 32 public class ToDeviceRpcRequestActorMsg implements ToDeviceActorNotificationMsg {
33 33
  34 + private static final long serialVersionUID = -8592877558138716589L;
  35 +
34 @Getter 36 @Getter
35 private final String serviceId; 37 private final String serviceId;
36 @Getter 38 @Getter
@@ -21,7 +21,6 @@ import com.google.common.util.concurrent.ListenableFuture; @@ -21,7 +21,6 @@ import com.google.common.util.concurrent.ListenableFuture;
21 import com.google.common.util.concurrent.MoreExecutors; 21 import com.google.common.util.concurrent.MoreExecutors;
22 import delight.nashornsandbox.NashornSandbox; 22 import delight.nashornsandbox.NashornSandbox;
23 import delight.nashornsandbox.NashornSandboxes; 23 import delight.nashornsandbox.NashornSandboxes;
24 -import jdk.nashorn.api.scripting.NashornScriptEngineFactory;  
25 import lombok.Getter; 24 import lombok.Getter;
26 import lombok.extern.slf4j.Slf4j; 25 import lombok.extern.slf4j.Slf4j;
27 import org.springframework.beans.factory.annotation.Value; 26 import org.springframework.beans.factory.annotation.Value;
@@ -33,6 +32,7 @@ import javax.annotation.PostConstruct; @@ -33,6 +32,7 @@ import javax.annotation.PostConstruct;
33 import javax.annotation.PreDestroy; 32 import javax.annotation.PreDestroy;
34 import javax.script.Invocable; 33 import javax.script.Invocable;
35 import javax.script.ScriptEngine; 34 import javax.script.ScriptEngine;
  35 +import javax.script.ScriptEngineManager;
36 import javax.script.ScriptException; 36 import javax.script.ScriptException;
37 import java.util.UUID; 37 import java.util.UUID;
38 import java.util.concurrent.ExecutionException; 38 import java.util.concurrent.ExecutionException;
@@ -97,8 +97,8 @@ public abstract class AbstractNashornJsInvokeService extends AbstractJsInvokeSer @@ -97,8 +97,8 @@ public abstract class AbstractNashornJsInvokeService extends AbstractJsInvokeSer
97 sandbox.allowLoadFunctions(true); 97 sandbox.allowLoadFunctions(true);
98 sandbox.setMaxPreparedStatements(30); 98 sandbox.setMaxPreparedStatements(30);
99 } else { 99 } else {
100 - NashornScriptEngineFactory factory = new NashornScriptEngineFactory();  
101 - engine = factory.getScriptEngine(new String[]{"--no-java"}); 100 + ScriptEngineManager factory = new ScriptEngineManager();
  101 + engine = factory.getEngineByName("nashorn");
102 } 102 }
103 } 103 }
104 104
@@ -29,7 +29,7 @@ public class SkipPathRequestMatcher implements RequestMatcher { @@ -29,7 +29,7 @@ public class SkipPathRequestMatcher implements RequestMatcher {
29 private RequestMatcher processingMatcher; 29 private RequestMatcher processingMatcher;
30 30
31 public SkipPathRequestMatcher(List<String> pathsToSkip, String processingPath) { 31 public SkipPathRequestMatcher(List<String> pathsToSkip, String processingPath) {
32 - Assert.notNull(pathsToSkip); 32 + Assert.notNull(pathsToSkip, "List of paths to skip is required.");
33 List<RequestMatcher> m = pathsToSkip.stream().map(path -> new AntPathRequestMatcher(path)).collect(Collectors.toList()); 33 List<RequestMatcher> m = pathsToSkip.stream().map(path -> new AntPathRequestMatcher(path)).collect(Collectors.toList());
34 matchers = new OrRequestMatcher(m); 34 matchers = new OrRequestMatcher(m);
35 processingMatcher = new AntPathRequestMatcher(processingPath); 35 processingMatcher = new AntPathRequestMatcher(processingPath);
@@ -100,6 +100,7 @@ public class JwtTokenFactory { @@ -100,6 +100,7 @@ public class JwtTokenFactory {
100 Jws<Claims> jwsClaims = rawAccessToken.parseClaims(settings.getTokenSigningKey()); 100 Jws<Claims> jwsClaims = rawAccessToken.parseClaims(settings.getTokenSigningKey());
101 Claims claims = jwsClaims.getBody(); 101 Claims claims = jwsClaims.getBody();
102 String subject = claims.getSubject(); 102 String subject = claims.getSubject();
  103 + @SuppressWarnings("unchecked")
103 List<String> scopes = claims.get(SCOPES, List.class); 104 List<String> scopes = claims.get(SCOPES, List.class);
104 if (scopes == null || scopes.isEmpty()) { 105 if (scopes == null || scopes.isEmpty()) {
105 throw new IllegalArgumentException("JWT Token doesn't have any scopes"); 106 throw new IllegalArgumentException("JWT Token doesn't have any scopes");
@@ -155,6 +156,7 @@ public class JwtTokenFactory { @@ -155,6 +156,7 @@ public class JwtTokenFactory {
155 Jws<Claims> jwsClaims = rawAccessToken.parseClaims(settings.getTokenSigningKey()); 156 Jws<Claims> jwsClaims = rawAccessToken.parseClaims(settings.getTokenSigningKey());
156 Claims claims = jwsClaims.getBody(); 157 Claims claims = jwsClaims.getBody();
157 String subject = claims.getSubject(); 158 String subject = claims.getSubject();
  159 + @SuppressWarnings("unchecked")
158 List<String> scopes = claims.get(SCOPES, List.class); 160 List<String> scopes = claims.get(SCOPES, List.class);
159 if (scopes == null || scopes.isEmpty()) { 161 if (scopes == null || scopes.isEmpty()) {
160 throw new IllegalArgumentException("Refresh Token doesn't have any scopes"); 162 throw new IllegalArgumentException("Refresh Token doesn't have any scopes");
@@ -47,6 +47,7 @@ public class CustomerUserPermissions extends AbstractPermissions { @@ -47,6 +47,7 @@ public class CustomerUserPermissions extends AbstractPermissions {
47 Operation.READ_ATTRIBUTES, Operation.READ_TELEMETRY, Operation.RPC_CALL, Operation.CLAIM_DEVICES) { 47 Operation.READ_ATTRIBUTES, Operation.READ_TELEMETRY, Operation.RPC_CALL, Operation.CLAIM_DEVICES) {
48 48
49 @Override 49 @Override
  50 + @SuppressWarnings("unchecked")
50 public boolean hasPermission(SecurityUser user, Operation operation, EntityId entityId, HasTenantId entity) { 51 public boolean hasPermission(SecurityUser user, Operation operation, EntityId entityId, HasTenantId entity) {
51 52
52 if (!super.hasPermission(user, operation, entityId, entity)) { 53 if (!super.hasPermission(user, operation, entityId, entity)) {
@@ -69,6 +70,7 @@ public class CustomerUserPermissions extends AbstractPermissions { @@ -69,6 +70,7 @@ public class CustomerUserPermissions extends AbstractPermissions {
69 new PermissionChecker.GenericPermissionChecker(Operation.READ, Operation.READ_ATTRIBUTES, Operation.READ_TELEMETRY) { 70 new PermissionChecker.GenericPermissionChecker(Operation.READ, Operation.READ_ATTRIBUTES, Operation.READ_TELEMETRY) {
70 71
71 @Override 72 @Override
  73 + @SuppressWarnings("unchecked")
72 public boolean hasPermission(SecurityUser user, Operation operation, EntityId entityId, HasTenantId entity) { 74 public boolean hasPermission(SecurityUser user, Operation operation, EntityId entityId, HasTenantId entity) {
73 if (!super.hasPermission(user, operation, entityId, entity)) { 75 if (!super.hasPermission(user, operation, entityId, entity)) {
74 return false; 76 return false;
@@ -119,6 +121,7 @@ public class CustomerUserPermissions extends AbstractPermissions { @@ -119,6 +121,7 @@ public class CustomerUserPermissions extends AbstractPermissions {
119 private static final PermissionChecker widgetsPermissionChecker = new PermissionChecker.GenericPermissionChecker(Operation.READ) { 121 private static final PermissionChecker widgetsPermissionChecker = new PermissionChecker.GenericPermissionChecker(Operation.READ) {
120 122
121 @Override 123 @Override
  124 + @SuppressWarnings("unchecked")
122 public boolean hasPermission(SecurityUser user, Operation operation, EntityId entityId, HasTenantId entity) { 125 public boolean hasPermission(SecurityUser user, Operation operation, EntityId entityId, HasTenantId entity) {
123 if (!super.hasPermission(user, operation, entityId, entity)) { 126 if (!super.hasPermission(user, operation, entityId, entity)) {
124 return false; 127 return false;
@@ -56,6 +56,7 @@ public class DefaultAccessControlService implements AccessControlService { @@ -56,6 +56,7 @@ public class DefaultAccessControlService implements AccessControlService {
56 } 56 }
57 57
58 @Override 58 @Override
  59 + @SuppressWarnings("unchecked")
59 public <I extends EntityId, T extends HasTenantId> void checkPermission(SecurityUser user, Resource resource, 60 public <I extends EntityId, T extends HasTenantId> void checkPermission(SecurityUser user, Resource resource,
60 Operation operation, I entityId, T entity) throws ThingsboardException { 61 Operation operation, I entityId, T entity) throws ThingsboardException {
61 PermissionChecker permissionChecker = getPermissionChecker(user.getAuthority(), resource); 62 PermissionChecker permissionChecker = getPermissionChecker(user.getAuthority(), resource);
@@ -59,6 +59,7 @@ public class TenantAdminPermissions extends AbstractPermissions { @@ -59,6 +59,7 @@ public class TenantAdminPermissions extends AbstractPermissions {
59 new PermissionChecker.GenericPermissionChecker(Operation.READ, Operation.READ_ATTRIBUTES, Operation.READ_TELEMETRY) { 59 new PermissionChecker.GenericPermissionChecker(Operation.READ, Operation.READ_ATTRIBUTES, Operation.READ_TELEMETRY) {
60 60
61 @Override 61 @Override
  62 + @SuppressWarnings("unchecked")
62 public boolean hasPermission(SecurityUser user, Operation operation, EntityId entityId, HasTenantId entity) { 63 public boolean hasPermission(SecurityUser user, Operation operation, EntityId entityId, HasTenantId entity) {
63 if (!super.hasPermission(user, operation, entityId, entity)) { 64 if (!super.hasPermission(user, operation, entityId, entity)) {
64 return false; 65 return false;
@@ -15,8 +15,8 @@ @@ -15,8 +15,8 @@
15 */ 15 */
16 package org.thingsboard.server.service.security.system; 16 package org.thingsboard.server.service.security.system;
17 17
  18 +import com.fasterxml.jackson.core.type.TypeReference;
18 import com.fasterxml.jackson.databind.JsonNode; 19 import com.fasterxml.jackson.databind.JsonNode;
19 -import com.fasterxml.jackson.databind.ObjectMapper;  
20 import com.fasterxml.jackson.databind.node.ObjectNode; 20 import com.fasterxml.jackson.databind.node.ObjectNode;
21 import lombok.extern.slf4j.Slf4j; 21 import lombok.extern.slf4j.Slf4j;
22 import org.apache.commons.lang3.StringUtils; 22 import org.apache.commons.lang3.StringUtils;
@@ -49,6 +49,7 @@ import org.thingsboard.server.dao.exception.DataValidationException; @@ -49,6 +49,7 @@ import org.thingsboard.server.dao.exception.DataValidationException;
49 import org.thingsboard.server.dao.settings.AdminSettingsService; 49 import org.thingsboard.server.dao.settings.AdminSettingsService;
50 import org.thingsboard.server.dao.user.UserService; 50 import org.thingsboard.server.dao.user.UserService;
51 import org.thingsboard.server.dao.user.UserServiceImpl; 51 import org.thingsboard.server.dao.user.UserServiceImpl;
  52 +import org.thingsboard.server.dao.util.mapping.JacksonUtil;
52 import org.thingsboard.server.service.security.exception.UserPasswordExpiredException; 53 import org.thingsboard.server.service.security.exception.UserPasswordExpiredException;
53 import org.thingsboard.server.utils.MiscUtils; 54 import org.thingsboard.server.utils.MiscUtils;
54 55
@@ -65,8 +66,6 @@ import static org.thingsboard.server.common.data.CacheConstants.SECURITY_SETTING @@ -65,8 +66,6 @@ import static org.thingsboard.server.common.data.CacheConstants.SECURITY_SETTING
65 @Slf4j 66 @Slf4j
66 public class DefaultSystemSecurityService implements SystemSecurityService { 67 public class DefaultSystemSecurityService implements SystemSecurityService {
67 68
68 - private static final ObjectMapper objectMapper = new ObjectMapper();  
69 -  
70 @Autowired 69 @Autowired
71 private AdminSettingsService adminSettingsService; 70 private AdminSettingsService adminSettingsService;
72 71
@@ -89,7 +88,7 @@ public class DefaultSystemSecurityService implements SystemSecurityService { @@ -89,7 +88,7 @@ public class DefaultSystemSecurityService implements SystemSecurityService {
89 AdminSettings adminSettings = adminSettingsService.findAdminSettingsByKey(tenantId, "securitySettings"); 88 AdminSettings adminSettings = adminSettingsService.findAdminSettingsByKey(tenantId, "securitySettings");
90 if (adminSettings != null) { 89 if (adminSettings != null) {
91 try { 90 try {
92 - securitySettings = objectMapper.treeToValue(adminSettings.getJsonValue(), SecuritySettings.class); 91 + securitySettings = JacksonUtil.convertValue(adminSettings.getJsonValue(), SecuritySettings.class);
93 } catch (Exception e) { 92 } catch (Exception e) {
94 throw new RuntimeException("Failed to load security settings!", e); 93 throw new RuntimeException("Failed to load security settings!", e);
95 } 94 }
@@ -109,10 +108,10 @@ public class DefaultSystemSecurityService implements SystemSecurityService { @@ -109,10 +108,10 @@ public class DefaultSystemSecurityService implements SystemSecurityService {
109 adminSettings = new AdminSettings(); 108 adminSettings = new AdminSettings();
110 adminSettings.setKey("securitySettings"); 109 adminSettings.setKey("securitySettings");
111 } 110 }
112 - adminSettings.setJsonValue(objectMapper.valueToTree(securitySettings)); 111 + adminSettings.setJsonValue(JacksonUtil.valueToTree(securitySettings));
113 AdminSettings savedAdminSettings = adminSettingsService.saveAdminSettings(tenantId, adminSettings); 112 AdminSettings savedAdminSettings = adminSettingsService.saveAdminSettings(tenantId, adminSettings);
114 try { 113 try {
115 - return objectMapper.treeToValue(savedAdminSettings.getJsonValue(), SecuritySettings.class); 114 + return JacksonUtil.convertValue(savedAdminSettings.getJsonValue(), SecuritySettings.class);
116 } catch (Exception e) { 115 } catch (Exception e) {
117 throw new RuntimeException("Failed to load security settings!", e); 116 throw new RuntimeException("Failed to load security settings!", e);
118 } 117 }
@@ -189,7 +188,7 @@ public class DefaultSystemSecurityService implements SystemSecurityService { @@ -189,7 +188,7 @@ public class DefaultSystemSecurityService implements SystemSecurityService {
189 JsonNode additionalInfo = user.getAdditionalInfo(); 188 JsonNode additionalInfo = user.getAdditionalInfo();
190 if (additionalInfo instanceof ObjectNode && additionalInfo.has(UserServiceImpl.USER_PASSWORD_HISTORY)) { 189 if (additionalInfo instanceof ObjectNode && additionalInfo.has(UserServiceImpl.USER_PASSWORD_HISTORY)) {
191 JsonNode userPasswordHistoryJson = additionalInfo.get(UserServiceImpl.USER_PASSWORD_HISTORY); 190 JsonNode userPasswordHistoryJson = additionalInfo.get(UserServiceImpl.USER_PASSWORD_HISTORY);
192 - Map<String, String> userPasswordHistoryMap = objectMapper.convertValue(userPasswordHistoryJson, Map.class); 191 + Map<String, String> userPasswordHistoryMap = JacksonUtil.convertValue(userPasswordHistoryJson, new TypeReference<>() {});
193 for (Map.Entry<String, String> entry : userPasswordHistoryMap.entrySet()) { 192 for (Map.Entry<String, String> entry : userPasswordHistoryMap.entrySet()) {
194 if (encoder.matches(password, entry.getValue()) && Long.parseLong(entry.getKey()) > passwordReuseFrequencyTs) { 193 if (encoder.matches(password, entry.getValue()) && Long.parseLong(entry.getKey()) > passwordReuseFrequencyTs) {
195 throw new DataValidationException("Password was already used for the last " + passwordPolicy.getPasswordReuseFrequencyDays() + " days"); 194 throw new DataValidationException("Password was already used for the last " + passwordPolicy.getPasswordReuseFrequencyDays() + " days");
@@ -318,6 +318,7 @@ public class DefaultTbEntityDataSubscriptionService implements TbEntityDataSubsc @@ -318,6 +318,7 @@ public class DefaultTbEntityDataSubscriptionService implements TbEntityDataSubsc
318 return ctx; 318 return ctx;
319 } 319 }
320 320
  321 + @SuppressWarnings("unchecked")
321 private <T extends TbAbstractDataSubCtx> T getSubCtx(String sessionId, int cmdId) { 322 private <T extends TbAbstractDataSubCtx> T getSubCtx(String sessionId, int cmdId) {
322 Map<Integer, TbAbstractDataSubCtx> sessionSubs = subscriptionsBySessionId.get(sessionId); 323 Map<Integer, TbAbstractDataSubCtx> sessionSubs = subscriptionsBySessionId.get(sessionId);
323 if (sessionSubs != null) { 324 if (sessionSubs != null) {
@@ -123,6 +123,7 @@ public class DefaultTbLocalSubscriptionService implements TbLocalSubscriptionSer @@ -123,6 +123,7 @@ public class DefaultTbLocalSubscriptionService implements TbLocalSubscriptionSer
123 } 123 }
124 124
125 @Override 125 @Override
  126 + @SuppressWarnings("unchecked")
126 public void onSubscriptionUpdate(String sessionId, TelemetrySubscriptionUpdate update, TbCallback callback) { 127 public void onSubscriptionUpdate(String sessionId, TelemetrySubscriptionUpdate update, TbCallback callback) {
127 TbSubscription subscription = subscriptionsBySessionId 128 TbSubscription subscription = subscriptionsBySessionId
128 .getOrDefault(sessionId, Collections.emptyMap()).get(update.getSubscriptionId()); 129 .getOrDefault(sessionId, Collections.emptyMap()).get(update.getSubscriptionId());
@@ -143,6 +144,7 @@ public class DefaultTbLocalSubscriptionService implements TbLocalSubscriptionSer @@ -143,6 +144,7 @@ public class DefaultTbLocalSubscriptionService implements TbLocalSubscriptionSer
143 } 144 }
144 145
145 @Override 146 @Override
  147 + @SuppressWarnings("unchecked")
146 public void onSubscriptionUpdate(String sessionId, AlarmSubscriptionUpdate update, TbCallback callback) { 148 public void onSubscriptionUpdate(String sessionId, AlarmSubscriptionUpdate update, TbCallback callback) {
147 TbSubscription subscription = subscriptionsBySessionId 149 TbSubscription subscription = subscriptionsBySessionId
148 .getOrDefault(sessionId, Collections.emptyMap()).get(update.getSubscriptionId()); 150 .getOrDefault(sessionId, Collections.emptyMap()).get(update.getSubscriptionId());
@@ -264,6 +264,7 @@ public abstract class TbAbstractDataSubCtx<T extends AbstractDataQuery<? extends @@ -264,6 +264,7 @@ public abstract class TbAbstractDataSubCtx<T extends AbstractDataQuery<? extends
264 }, MoreExecutors.directExecutor()); 264 }, MoreExecutors.directExecutor());
265 } 265 }
266 266
  267 + @SuppressWarnings("unchecked")
267 private void updateDynamicValuesByKey(DynamicValueKeySub sub, TsValue tsValue) { 268 private void updateDynamicValuesByKey(DynamicValueKeySub sub, TsValue tsValue) {
268 DynamicValueKey dvk = sub.getKey(); 269 DynamicValueKey dvk = sub.getKey();
269 switch (dvk.getPredicateType()) { 270 switch (dvk.getPredicateType()) {
@@ -285,6 +286,7 @@ public abstract class TbAbstractDataSubCtx<T extends AbstractDataQuery<? extends @@ -285,6 +286,7 @@ public abstract class TbAbstractDataSubCtx<T extends AbstractDataQuery<? extends
285 } 286 }
286 } 287 }
287 288
  289 + @SuppressWarnings("unchecked")
288 private void registerDynamicValues(KeyFilterPredicate predicate) { 290 private void registerDynamicValues(KeyFilterPredicate predicate) {
289 switch (predicate.getType()) { 291 switch (predicate.getType()) {
290 case STRING: 292 case STRING:
@@ -34,6 +34,8 @@ import java.util.UUID; @@ -34,6 +34,8 @@ import java.util.UUID;
34 @Data 34 @Data
35 public class TransportToDeviceActorMsgWrapper implements TbActorMsg, DeviceAwareMsg, TenantAwareMsg, Serializable { 35 public class TransportToDeviceActorMsgWrapper implements TbActorMsg, DeviceAwareMsg, TenantAwareMsg, Serializable {
36 36
  37 + private static final long serialVersionUID = 7191333353202935941L;
  38 +
37 private final TenantId tenantId; 39 private final TenantId tenantId;
38 private final DeviceId deviceId; 40 private final DeviceId deviceId;
39 private final TransportToDeviceActorMsg msg; 41 private final TransportToDeviceActorMsg msg;
@@ -33,6 +33,7 @@ public class MiscUtils { @@ -33,6 +33,7 @@ public class MiscUtils {
33 return "The " + propertyName + " property need to be set!"; 33 return "The " + propertyName + " property need to be set!";
34 } 34 }
35 35
  36 + @SuppressWarnings("deprecation")
36 public static HashFunction forName(String name) { 37 public static HashFunction forName(String name) {
37 switch (name) { 38 switch (name) {
38 case "murmur3_32": 39 case "murmur3_32":
@@ -375,6 +375,10 @@ public abstract class AbstractWebTest { @@ -375,6 +375,10 @@ public abstract class AbstractWebTest {
375 return readResponse(doGetAsync(urlTemplate, urlVariables).andExpect(status().isOk()), responseClass); 375 return readResponse(doGetAsync(urlTemplate, urlVariables).andExpect(status().isOk()), responseClass);
376 } 376 }
377 377
  378 + protected <T> T doGetAsyncTyped(String urlTemplate, TypeReference<T> responseType, Object... urlVariables) throws Exception {
  379 + return readResponse(doGetAsync(urlTemplate, urlVariables).andExpect(status().isOk()), responseType);
  380 + }
  381 +
378 protected ResultActions doGetAsync(String urlTemplate, Object... urlVariables) throws Exception { 382 protected ResultActions doGetAsync(String urlTemplate, Object... urlVariables) throws Exception {
379 MockHttpServletRequestBuilder getRequest; 383 MockHttpServletRequestBuilder getRequest;
380 getRequest = get(urlTemplate, urlVariables); 384 getRequest = get(urlTemplate, urlVariables);
@@ -347,8 +347,8 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes @@ -347,8 +347,8 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes
347 347
348 Thread.sleep(1000); 348 Thread.sleep(1000);
349 349
350 - List<Map<String, Object>> values = doGetAsync("/api/plugins/telemetry/ENTITY_VIEW/" + savedView.getId().getId().toString() +  
351 - "/values/attributes?keys=" + String.join(",", actualAttributesSet), List.class); 350 + List<Map<String, Object>> values = doGetAsyncTyped("/api/plugins/telemetry/ENTITY_VIEW/" + savedView.getId().getId().toString() +
  351 + "/values/attributes?keys=" + String.join(",", actualAttributesSet), new TypeReference<>() {});
352 352
353 assertEquals("value1", getValue(values, "caKey1")); 353 assertEquals("value1", getValue(values, "caKey1"));
354 assertEquals(true, getValue(values, "caKey2")); 354 assertEquals(true, getValue(values, "caKey2"));
@@ -364,8 +364,8 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes @@ -364,8 +364,8 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes
364 Set<String> expectedActualAttributesSet = new HashSet<>(Arrays.asList("caKey1", "caKey2", "caKey3", "caKey4")); 364 Set<String> expectedActualAttributesSet = new HashSet<>(Arrays.asList("caKey1", "caKey2", "caKey3", "caKey4"));
365 assertTrue(actualAttributesSet.containsAll(expectedActualAttributesSet)); 365 assertTrue(actualAttributesSet.containsAll(expectedActualAttributesSet));
366 366
367 - List<Map<String, Object>> valueTelemetryOfDevices = doGetAsync("/api/plugins/telemetry/DEVICE/" + testDevice.getId().getId().toString() +  
368 - "/values/attributes?keys=" + String.join(",", actualAttributesSet), List.class); 367 + List<Map<String, Object>> valueTelemetryOfDevices = doGetAsyncTyped("/api/plugins/telemetry/DEVICE/" + testDevice.getId().getId().toString() +
  368 + "/values/attributes?keys=" + String.join(",", actualAttributesSet), new TypeReference<>() {});
369 369
370 EntityView view = new EntityView(); 370 EntityView view = new EntityView();
371 view.setEntityId(testDevice.getId()); 371 view.setEntityId(testDevice.getId());
@@ -379,8 +379,8 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes @@ -379,8 +379,8 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes
379 379
380 Thread.sleep(1000); 380 Thread.sleep(1000);
381 381
382 - List<Map<String, Object>> values = doGetAsync("/api/plugins/telemetry/ENTITY_VIEW/" + savedView.getId().getId().toString() +  
383 - "/values/attributes?keys=" + String.join(",", actualAttributesSet), List.class); 382 + List<Map<String, Object>> values = doGetAsyncTyped("/api/plugins/telemetry/ENTITY_VIEW/" + savedView.getId().getId().toString() +
  383 + "/values/attributes?keys=" + String.join(",", actualAttributesSet), new TypeReference<>() {});
384 assertEquals(0, values.size()); 384 assertEquals(0, values.size());
385 } 385 }
386 386
@@ -449,12 +449,12 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes @@ -449,12 +449,12 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes
449 } 449 }
450 450
451 private Set<String> getTelemetryKeys(String type, String id) throws Exception { 451 private Set<String> getTelemetryKeys(String type, String id) throws Exception {
452 - return new HashSet<>(doGetAsync("/api/plugins/telemetry/" + type + "/" + id + "/keys/timeseries", List.class)); 452 + return new HashSet<>(doGetAsyncTyped("/api/plugins/telemetry/" + type + "/" + id + "/keys/timeseries", new TypeReference<>() {}));
453 } 453 }
454 454
455 private Map<String, List<Map<String, String>>> getTelemetryValues(String type, String id, Set<String> keys, Long startTs, Long endTs) throws Exception { 455 private Map<String, List<Map<String, String>>> getTelemetryValues(String type, String id, Set<String> keys, Long startTs, Long endTs) throws Exception {
456 - return doGetAsync("/api/plugins/telemetry/" + type + "/" + id +  
457 - "/values/timeseries?keys=" + String.join(",", keys) + "&startTs=" + startTs + "&endTs=" + endTs, Map.class); 456 + return doGetAsyncTyped("/api/plugins/telemetry/" + type + "/" + id +
  457 + "/values/timeseries?keys=" + String.join(",", keys) + "&startTs=" + startTs + "&endTs=" + endTs, new TypeReference<>() {});
458 } 458 }
459 459
460 private Set<String> getAttributesByKeys(String stringKV) throws Exception { 460 private Set<String> getAttributesByKeys(String stringKV) throws Exception {
@@ -479,7 +479,7 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes @@ -479,7 +479,7 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes
479 client.publish("v1/devices/me/attributes", message); 479 client.publish("v1/devices/me/attributes", message);
480 Thread.sleep(1000); 480 Thread.sleep(1000);
481 client.disconnect(); 481 client.disconnect();
482 - return new HashSet<>(doGetAsync("/api/plugins/telemetry/DEVICE/" + viewDeviceId + "/keys/attributes", List.class)); 482 + return new HashSet<>(doGetAsyncTyped("/api/plugins/telemetry/DEVICE/" + viewDeviceId + "/keys/attributes", new TypeReference<>() {}));
483 } 483 }
484 484
485 private Object getValue(List<Map<String, Object>> values, String stringValue) { 485 private Object getValue(List<Map<String, Object>> values, String stringValue) {
@@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
16 package org.thingsboard.server.mqtt.telemetry.attributes; 16 package org.thingsboard.server.mqtt.telemetry.attributes;
17 17
18 import com.fasterxml.jackson.core.JsonProcessingException; 18 import com.fasterxml.jackson.core.JsonProcessingException;
  19 +import com.fasterxml.jackson.core.type.TypeReference;
19 import lombok.extern.slf4j.Slf4j; 20 import lombok.extern.slf4j.Slf4j;
20 import org.eclipse.paho.client.mqttv3.MqttAsyncClient; 21 import org.eclipse.paho.client.mqttv3.MqttAsyncClient;
21 import org.junit.After; 22 import org.junit.After;
@@ -80,7 +81,7 @@ public abstract class AbstractMqttAttributesIntegrationTest extends AbstractMqtt @@ -80,7 +81,7 @@ public abstract class AbstractMqttAttributesIntegrationTest extends AbstractMqtt
80 81
81 List<String> actualKeys = null; 82 List<String> actualKeys = null;
82 while (start <= end) { 83 while (start <= end) {
83 - actualKeys = doGetAsync("/api/plugins/telemetry/DEVICE/" + deviceId + "/keys/attributes/CLIENT_SCOPE", List.class); 84 + actualKeys = doGetAsyncTyped("/api/plugins/telemetry/DEVICE/" + deviceId + "/keys/attributes/CLIENT_SCOPE", new TypeReference<>() {});
84 if (actualKeys.size() == expectedKeys.size()) { 85 if (actualKeys.size() == expectedKeys.size()) {
85 break; 86 break;
86 } 87 }
@@ -96,7 +97,7 @@ public abstract class AbstractMqttAttributesIntegrationTest extends AbstractMqtt @@ -96,7 +97,7 @@ public abstract class AbstractMqttAttributesIntegrationTest extends AbstractMqtt
96 assertEquals(expectedKeySet, actualKeySet); 97 assertEquals(expectedKeySet, actualKeySet);
97 98
98 String getAttributesValuesUrl = getAttributesValuesUrl(deviceId, actualKeySet); 99 String getAttributesValuesUrl = getAttributesValuesUrl(deviceId, actualKeySet);
99 - List<Map<String, Object>> values = doGetAsync(getAttributesValuesUrl, List.class); 100 + List<Map<String, Object>> values = doGetAsyncTyped(getAttributesValuesUrl, new TypeReference<>() {});
100 assertAttributesValues(values, expectedKeySet); 101 assertAttributesValues(values, expectedKeySet);
101 String deleteAttributesUrl = "/api/plugins/telemetry/DEVICE/" + deviceId + "/CLIENT_SCOPE?keys=" + String.join(",", actualKeySet); 102 String deleteAttributesUrl = "/api/plugins/telemetry/DEVICE/" + deviceId + "/CLIENT_SCOPE?keys=" + String.join(",", actualKeySet);
102 doDelete(deleteAttributesUrl); 103 doDelete(deleteAttributesUrl);
@@ -121,10 +122,10 @@ public abstract class AbstractMqttAttributesIntegrationTest extends AbstractMqtt @@ -121,10 +122,10 @@ public abstract class AbstractMqttAttributesIntegrationTest extends AbstractMqtt
121 122
122 Thread.sleep(2000); 123 Thread.sleep(2000);
123 124
124 - List<String> firstDeviceActualKeys = doGetAsync("/api/plugins/telemetry/DEVICE/" + firstDevice.getId() + "/keys/attributes/CLIENT_SCOPE", List.class); 125 + List<String> firstDeviceActualKeys = doGetAsyncTyped("/api/plugins/telemetry/DEVICE/" + firstDevice.getId() + "/keys/attributes/CLIENT_SCOPE", new TypeReference<>() {});
125 Set<String> firstDeviceActualKeySet = new HashSet<>(firstDeviceActualKeys); 126 Set<String> firstDeviceActualKeySet = new HashSet<>(firstDeviceActualKeys);
126 127
127 - List<String> secondDeviceActualKeys = doGetAsync("/api/plugins/telemetry/DEVICE/" + secondDevice.getId() + "/keys/attributes/CLIENT_SCOPE", List.class); 128 + List<String> secondDeviceActualKeys = doGetAsyncTyped("/api/plugins/telemetry/DEVICE/" + secondDevice.getId() + "/keys/attributes/CLIENT_SCOPE", new TypeReference<>() {});
128 Set<String> secondDeviceActualKeySet = new HashSet<>(secondDeviceActualKeys); 129 Set<String> secondDeviceActualKeySet = new HashSet<>(secondDeviceActualKeys);
129 130
130 Set<String> expectedKeySet = new HashSet<>(expectedKeys); 131 Set<String> expectedKeySet = new HashSet<>(expectedKeys);
@@ -135,14 +136,15 @@ public abstract class AbstractMqttAttributesIntegrationTest extends AbstractMqtt @@ -135,14 +136,15 @@ public abstract class AbstractMqttAttributesIntegrationTest extends AbstractMqtt
135 String getAttributesValuesUrlFirstDevice = getAttributesValuesUrl(firstDevice.getId(), firstDeviceActualKeySet); 136 String getAttributesValuesUrlFirstDevice = getAttributesValuesUrl(firstDevice.getId(), firstDeviceActualKeySet);
136 String getAttributesValuesUrlSecondDevice = getAttributesValuesUrl(firstDevice.getId(), secondDeviceActualKeySet); 137 String getAttributesValuesUrlSecondDevice = getAttributesValuesUrl(firstDevice.getId(), secondDeviceActualKeySet);
137 138
138 - List<Map<String, Object>> firstDeviceValues = doGetAsync(getAttributesValuesUrlFirstDevice, List.class);  
139 - List<Map<String, Object>> secondDeviceValues = doGetAsync(getAttributesValuesUrlSecondDevice, List.class); 139 + List<Map<String, Object>> firstDeviceValues = doGetAsyncTyped(getAttributesValuesUrlFirstDevice, new TypeReference<>() {});
  140 + List<Map<String, Object>> secondDeviceValues = doGetAsyncTyped(getAttributesValuesUrlSecondDevice, new TypeReference<>() {});
140 141
141 assertAttributesValues(firstDeviceValues, expectedKeySet); 142 assertAttributesValues(firstDeviceValues, expectedKeySet);
142 assertAttributesValues(secondDeviceValues, expectedKeySet); 143 assertAttributesValues(secondDeviceValues, expectedKeySet);
143 144
144 } 145 }
145 146
  147 + @SuppressWarnings("unchecked")
146 protected void assertAttributesValues(List<Map<String, Object>> deviceValues, Set<String> expectedKeySet) throws JsonProcessingException { 148 protected void assertAttributesValues(List<Map<String, Object>> deviceValues, Set<String> expectedKeySet) throws JsonProcessingException {
147 for (Map<String, Object> map : deviceValues) { 149 for (Map<String, Object> map : deviceValues) {
148 String key = (String) map.get("key"); 150 String key = (String) map.get("key");
@@ -15,6 +15,7 @@ @@ -15,6 +15,7 @@
15 */ 15 */
16 package org.thingsboard.server.mqtt.telemetry.timeseries; 16 package org.thingsboard.server.mqtt.telemetry.timeseries;
17 17
  18 +import com.fasterxml.jackson.core.type.TypeReference;
18 import io.netty.handler.codec.mqtt.MqttQoS; 19 import io.netty.handler.codec.mqtt.MqttQoS;
19 import lombok.extern.slf4j.Slf4j; 20 import lombok.extern.slf4j.Slf4j;
20 import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken; 21 import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
@@ -25,6 +26,7 @@ import org.eclipse.paho.client.mqttv3.MqttMessage; @@ -25,6 +26,7 @@ import org.eclipse.paho.client.mqttv3.MqttMessage;
25 import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; 26 import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
26 import org.junit.After; 27 import org.junit.After;
27 import org.junit.Before; 28 import org.junit.Before;
  29 +import org.junit.Ignore;
28 import org.junit.Test; 30 import org.junit.Test;
29 import org.thingsboard.server.common.data.Device; 31 import org.thingsboard.server.common.data.Device;
30 import org.thingsboard.server.common.data.device.profile.MqttTopics; 32 import org.thingsboard.server.common.data.device.profile.MqttTopics;
@@ -107,7 +109,7 @@ public abstract class AbstractMqttTimeseriesIntegrationTest extends AbstractMqtt @@ -107,7 +109,7 @@ public abstract class AbstractMqttTimeseriesIntegrationTest extends AbstractMqtt
107 109
108 List<String> actualKeys = null; 110 List<String> actualKeys = null;
109 while (start <= end) { 111 while (start <= end) {
110 - actualKeys = doGetAsync("/api/plugins/telemetry/DEVICE/" + deviceId + "/keys/timeseries", List.class); 112 + actualKeys = doGetAsyncTyped("/api/plugins/telemetry/DEVICE/" + deviceId + "/keys/timeseries", new TypeReference<>() {});
111 if (actualKeys.size() == expectedKeys.size()) { 113 if (actualKeys.size() == expectedKeys.size()) {
112 break; 114 break;
113 } 115 }
@@ -129,13 +131,13 @@ public abstract class AbstractMqttTimeseriesIntegrationTest extends AbstractMqtt @@ -129,13 +131,13 @@ public abstract class AbstractMqttTimeseriesIntegrationTest extends AbstractMqtt
129 } 131 }
130 start = System.currentTimeMillis(); 132 start = System.currentTimeMillis();
131 end = System.currentTimeMillis() + 5000; 133 end = System.currentTimeMillis() + 5000;
132 - Map<String, List<Map<String, String>>> values = null; 134 + Map<String, List<Map<String, Object>>> values = null;
133 while (start <= end) { 135 while (start <= end) {
134 - values = doGetAsync(getTelemetryValuesUrl, Map.class); 136 + values = doGetAsyncTyped(getTelemetryValuesUrl, new TypeReference<>() {});
135 boolean valid = values.size() == expectedKeys.size(); 137 boolean valid = values.size() == expectedKeys.size();
136 if (valid) { 138 if (valid) {
137 for (String key : expectedKeys) { 139 for (String key : expectedKeys) {
138 - List<Map<String, String>> tsValues = values.get(key); 140 + List<Map<String, Object>> tsValues = values.get(key);
139 if (tsValues != null && tsValues.size() > 0) { 141 if (tsValues != null && tsValues.size() > 0) {
140 Object ts = tsValues.get(0).get("ts"); 142 Object ts = tsValues.get(0).get("ts");
141 if (ts == null) { 143 if (ts == null) {
@@ -181,10 +183,10 @@ public abstract class AbstractMqttTimeseriesIntegrationTest extends AbstractMqtt @@ -181,10 +183,10 @@ public abstract class AbstractMqttTimeseriesIntegrationTest extends AbstractMqtt
181 183
182 Thread.sleep(2000); 184 Thread.sleep(2000);
183 185
184 - List<String> firstDeviceActualKeys = doGetAsync("/api/plugins/telemetry/DEVICE/" + firstDevice.getId() + "/keys/timeseries", List.class); 186 + List<String> firstDeviceActualKeys = doGetAsyncTyped("/api/plugins/telemetry/DEVICE/" + firstDevice.getId() + "/keys/timeseries", new TypeReference<>() {});
185 Set<String> firstDeviceActualKeySet = new HashSet<>(firstDeviceActualKeys); 187 Set<String> firstDeviceActualKeySet = new HashSet<>(firstDeviceActualKeys);
186 188
187 - List<String> secondDeviceActualKeys = doGetAsync("/api/plugins/telemetry/DEVICE/" + secondDevice.getId() + "/keys/timeseries", List.class); 189 + List<String> secondDeviceActualKeys = doGetAsyncTyped("/api/plugins/telemetry/DEVICE/" + secondDevice.getId() + "/keys/timeseries", new TypeReference<>() {});
188 Set<String> secondDeviceActualKeySet = new HashSet<>(secondDeviceActualKeys); 190 Set<String> secondDeviceActualKeySet = new HashSet<>(secondDeviceActualKeys);
189 191
190 Set<String> expectedKeySet = new HashSet<>(expectedKeys); 192 Set<String> expectedKeySet = new HashSet<>(expectedKeys);
@@ -195,8 +197,8 @@ public abstract class AbstractMqttTimeseriesIntegrationTest extends AbstractMqtt @@ -195,8 +197,8 @@ public abstract class AbstractMqttTimeseriesIntegrationTest extends AbstractMqtt
195 String getTelemetryValuesUrlFirstDevice = getTelemetryValuesUrl(firstDevice.getId(), firstDeviceActualKeySet); 197 String getTelemetryValuesUrlFirstDevice = getTelemetryValuesUrl(firstDevice.getId(), firstDeviceActualKeySet);
196 String getTelemetryValuesUrlSecondDevice = getTelemetryValuesUrl(firstDevice.getId(), secondDeviceActualKeySet); 198 String getTelemetryValuesUrlSecondDevice = getTelemetryValuesUrl(firstDevice.getId(), secondDeviceActualKeySet);
197 199
198 - Map<String, List<Map<String, String>>> firstDeviceValues = doGetAsync(getTelemetryValuesUrlFirstDevice, Map.class);  
199 - Map<String, List<Map<String, String>>> secondDeviceValues = doGetAsync(getTelemetryValuesUrlSecondDevice, Map.class); 200 + Map<String, List<Map<String, Object>>> firstDeviceValues = doGetAsyncTyped(getTelemetryValuesUrlFirstDevice, new TypeReference<>() {});
  201 + Map<String, List<Map<String, Object>>> secondDeviceValues = doGetAsyncTyped(getTelemetryValuesUrlSecondDevice, new TypeReference<>() {});
200 202
201 assertGatewayDeviceData(firstDeviceValues, expectedKeys); 203 assertGatewayDeviceData(firstDeviceValues, expectedKeys);
202 assertGatewayDeviceData(secondDeviceValues, expectedKeys); 204 assertGatewayDeviceData(secondDeviceValues, expectedKeys);
@@ -212,7 +214,7 @@ public abstract class AbstractMqttTimeseriesIntegrationTest extends AbstractMqtt @@ -212,7 +214,7 @@ public abstract class AbstractMqttTimeseriesIntegrationTest extends AbstractMqtt
212 return "/api/plugins/telemetry/DEVICE/" + deviceId + "/values/timeseries?startTs=0&endTs=25000&keys=" + String.join(",", actualKeySet); 214 return "/api/plugins/telemetry/DEVICE/" + deviceId + "/values/timeseries?startTs=0&endTs=25000&keys=" + String.join(",", actualKeySet);
213 } 215 }
214 216
215 - private void assertGatewayDeviceData(Map<String, List<Map<String, String>>> deviceValues, List<String> expectedKeys) { 217 + private void assertGatewayDeviceData(Map<String, List<Map<String, Object>>> deviceValues, List<String> expectedKeys) {
216 218
217 assertEquals(2, deviceValues.get(expectedKeys.get(0)).size()); 219 assertEquals(2, deviceValues.get(expectedKeys.get(0)).size());
218 assertEquals(2, deviceValues.get(expectedKeys.get(1)).size()); 220 assertEquals(2, deviceValues.get(expectedKeys.get(1)).size());
@@ -228,11 +230,11 @@ public abstract class AbstractMqttTimeseriesIntegrationTest extends AbstractMqtt @@ -228,11 +230,11 @@ public abstract class AbstractMqttTimeseriesIntegrationTest extends AbstractMqtt
228 230
229 } 231 }
230 232
231 - private void assertValues(Map<String, List<Map<String, String>>> deviceValues, int arrayIndex) {  
232 - for (Map.Entry<String, List<Map<String, String>>> entry : deviceValues.entrySet()) { 233 + private void assertValues(Map<String, List<Map<String, Object>>> deviceValues, int arrayIndex) {
  234 + for (Map.Entry<String, List<Map<String, Object>>> entry : deviceValues.entrySet()) {
233 String key = entry.getKey(); 235 String key = entry.getKey();
234 - List<Map<String, String>> tsKv = entry.getValue();  
235 - String value = tsKv.get(arrayIndex).get("value"); 236 + List<Map<String, Object>> tsKv = entry.getValue();
  237 + String value = (String) tsKv.get(arrayIndex).get("value");
236 switch (key) { 238 switch (key) {
237 case "key1": 239 case "key1":
238 assertEquals("value1", value); 240 assertEquals("value1", value);
@@ -253,7 +255,7 @@ public abstract class AbstractMqttTimeseriesIntegrationTest extends AbstractMqtt @@ -253,7 +255,7 @@ public abstract class AbstractMqttTimeseriesIntegrationTest extends AbstractMqtt
253 } 255 }
254 } 256 }
255 257
256 - private void assertTs(Map<String, List<Map<String, String>>> deviceValues, List<String> expectedKeys, int ts, int arrayIndex) { 258 + private void assertTs(Map<String, List<Map<String, Object>>> deviceValues, List<String> expectedKeys, int ts, int arrayIndex) {
257 assertEquals(ts, deviceValues.get(expectedKeys.get(0)).get(arrayIndex).get("ts")); 259 assertEquals(ts, deviceValues.get(expectedKeys.get(0)).get(arrayIndex).get("ts"));
258 assertEquals(ts, deviceValues.get(expectedKeys.get(1)).get(arrayIndex).get("ts")); 260 assertEquals(ts, deviceValues.get(expectedKeys.get(1)).get(arrayIndex).get("ts"));
259 assertEquals(ts, deviceValues.get(expectedKeys.get(2)).get(arrayIndex).get("ts")); 261 assertEquals(ts, deviceValues.get(expectedKeys.get(2)).get(arrayIndex).get("ts"));
@@ -21,12 +21,11 @@ import org.junit.Assert; @@ -21,12 +21,11 @@ import org.junit.Assert;
21 import org.junit.Before; 21 import org.junit.Before;
22 import org.junit.Test; 22 import org.junit.Test;
23 import org.junit.runner.RunWith; 23 import org.junit.runner.RunWith;
24 -import org.mockito.runners.MockitoJUnitRunner; 24 +import org.mockito.junit.MockitoJUnitRunner;
25 import org.springframework.context.ApplicationEventPublisher; 25 import org.springframework.context.ApplicationEventPublisher;
26 import org.springframework.test.util.ReflectionTestUtils; 26 import org.springframework.test.util.ReflectionTestUtils;
27 import org.thingsboard.server.common.data.id.DeviceId; 27 import org.thingsboard.server.common.data.id.DeviceId;
28 import org.thingsboard.server.common.data.id.TenantId; 28 import org.thingsboard.server.common.data.id.TenantId;
29 -import org.thingsboard.server.common.msg.queue.ServiceQueue;  
30 import org.thingsboard.server.queue.discovery.HashPartitionService; 29 import org.thingsboard.server.queue.discovery.HashPartitionService;
31 import org.thingsboard.server.common.msg.queue.ServiceType; 30 import org.thingsboard.server.common.msg.queue.ServiceType;
32 import org.thingsboard.server.queue.discovery.TbServiceInfoProvider; 31 import org.thingsboard.server.queue.discovery.TbServiceInfoProvider;
@@ -20,7 +20,7 @@ import org.junit.Assert; @@ -20,7 +20,7 @@ import org.junit.Assert;
20 import org.junit.Test; 20 import org.junit.Test;
21 import org.junit.runner.RunWith; 21 import org.junit.runner.RunWith;
22 import org.mockito.Mockito; 22 import org.mockito.Mockito;
23 -import org.mockito.runners.MockitoJUnitRunner; 23 +import org.mockito.junit.MockitoJUnitRunner;
24 import org.thingsboard.server.gen.transport.TransportProtos; 24 import org.thingsboard.server.gen.transport.TransportProtos;
25 import org.thingsboard.server.queue.common.TbProtoQueueMsg; 25 import org.thingsboard.server.queue.common.TbProtoQueueMsg;
26 import org.thingsboard.server.service.queue.processing.TbRuleEngineSubmitStrategy; 26 import org.thingsboard.server.service.queue.processing.TbRuleEngineSubmitStrategy;
@@ -20,7 +20,7 @@ import lombok.extern.slf4j.Slf4j; @@ -20,7 +20,7 @@ import lombok.extern.slf4j.Slf4j;
20 import org.junit.Test; 20 import org.junit.Test;
21 import org.junit.runner.RunWith; 21 import org.junit.runner.RunWith;
22 import org.mockito.Mockito; 22 import org.mockito.Mockito;
23 -import org.mockito.runners.MockitoJUnitRunner; 23 +import org.mockito.junit.MockitoJUnitRunner;
24 import org.thingsboard.server.utils.EventDeduplicationExecutor; 24 import org.thingsboard.server.utils.EventDeduplicationExecutor;
25 25
26 import java.util.concurrent.ExecutorService; 26 import java.util.concurrent.ExecutorService;
@@ -67,7 +67,7 @@ @@ -67,7 +67,7 @@
67 </dependency> 67 </dependency>
68 <dependency> 68 <dependency>
69 <groupId>org.mockito</groupId> 69 <groupId>org.mockito</groupId>
70 - <artifactId>mockito-all</artifactId> 70 + <artifactId>mockito-core</artifactId>
71 <scope>test</scope> 71 <scope>test</scope>
72 </dependency> 72 </dependency>
73 </dependencies> 73 </dependencies>
@@ -30,7 +30,7 @@ public interface TbActor { @@ -30,7 +30,7 @@ public interface TbActor {
30 } 30 }
31 31
32 default InitFailureStrategy onInitFailure(int attempt, Throwable t) { 32 default InitFailureStrategy onInitFailure(int attempt, Throwable t) {
33 - return InitFailureStrategy.retryWithDelay(5000 * attempt); 33 + return InitFailureStrategy.retryWithDelay(5000L * attempt);
34 } 34 }
35 35
36 default ProcessFailureStrategy onProcessFailure(Throwable t) { 36 default ProcessFailureStrategy onProcessFailure(Throwable t) {
@@ -17,6 +17,8 @@ package org.thingsboard.server.actors; @@ -17,6 +17,8 @@ package org.thingsboard.server.actors;
17 17
18 public class TbActorException extends Exception { 18 public class TbActorException extends Exception {
19 19
  20 + private static final long serialVersionUID = 8209771144711980882L;
  21 +
20 public TbActorException(String message, Throwable cause) { 22 public TbActorException(String message, Throwable cause) {
21 super(message, cause); 23 super(message, cause);
22 } 24 }
@@ -18,6 +18,7 @@ package org.thingsboard.server.actors; @@ -18,6 +18,7 @@ package org.thingsboard.server.actors;
18 import lombok.Data; 18 import lombok.Data;
19 import lombok.extern.slf4j.Slf4j; 19 import lombok.extern.slf4j.Slf4j;
20 import org.thingsboard.server.common.msg.TbActorMsg; 20 import org.thingsboard.server.common.msg.TbActorMsg;
  21 +import org.thingsboard.server.common.msg.TbActorStopReason;
21 22
22 import java.util.List; 23 import java.util.List;
23 import java.util.concurrent.ConcurrentLinkedQueue; 24 import java.util.concurrent.ConcurrentLinkedQueue;
@@ -49,6 +50,7 @@ public final class TbActorMailbox implements TbActorCtx { @@ -49,6 +50,7 @@ public final class TbActorMailbox implements TbActorCtx {
49 private final AtomicBoolean busy = new AtomicBoolean(FREE); 50 private final AtomicBoolean busy = new AtomicBoolean(FREE);
50 private final AtomicBoolean ready = new AtomicBoolean(NOT_READY); 51 private final AtomicBoolean ready = new AtomicBoolean(NOT_READY);
51 private final AtomicBoolean destroyInProgress = new AtomicBoolean(); 52 private final AtomicBoolean destroyInProgress = new AtomicBoolean();
  53 + private volatile TbActorStopReason stopReason;
52 54
53 public void initActor() { 55 public void initActor() {
54 dispatcher.getExecutor().execute(() -> tryInit(1)); 56 dispatcher.getExecutor().execute(() -> tryInit(1));
@@ -70,6 +72,7 @@ public final class TbActorMailbox implements TbActorCtx { @@ -70,6 +72,7 @@ public final class TbActorMailbox implements TbActorCtx {
70 InitFailureStrategy strategy = actor.onInitFailure(attempt, t); 72 InitFailureStrategy strategy = actor.onInitFailure(attempt, t);
71 if (strategy.isStop() || (settings.getMaxActorInitAttempts() > 0 && attemptIdx > settings.getMaxActorInitAttempts())) { 73 if (strategy.isStop() || (settings.getMaxActorInitAttempts() > 0 && attemptIdx > settings.getMaxActorInitAttempts())) {
72 log.info("[{}] Failed to init actor, attempt {}, going to stop attempts.", selfId, attempt, t); 74 log.info("[{}] Failed to init actor, attempt {}, going to stop attempts.", selfId, attempt, t);
  75 + stopReason = TbActorStopReason.INIT_FAILED;
73 system.stop(selfId); 76 system.stop(selfId);
74 } else if (strategy.getRetryDelay() > 0) { 77 } else if (strategy.getRetryDelay() > 0) {
75 log.info("[{}] Failed to init actor, attempt {}, going to retry in attempts in {}ms", selfId, attempt, strategy.getRetryDelay()); 78 log.info("[{}] Failed to init actor, attempt {}, going to retry in attempts in {}ms", selfId, attempt, strategy.getRetryDelay());
@@ -84,12 +87,16 @@ public final class TbActorMailbox implements TbActorCtx { @@ -84,12 +87,16 @@ public final class TbActorMailbox implements TbActorCtx {
84 } 87 }
85 88
86 private void enqueue(TbActorMsg msg, boolean highPriority) { 89 private void enqueue(TbActorMsg msg, boolean highPriority) {
87 - if (highPriority) {  
88 - highPriorityMsgs.add(msg); 90 + if (!destroyInProgress.get()) {
  91 + if (highPriority) {
  92 + highPriorityMsgs.add(msg);
  93 + } else {
  94 + normalPriorityMsgs.add(msg);
  95 + }
  96 + tryProcessQueue(true);
89 } else { 97 } else {
90 - normalPriorityMsgs.add(msg); 98 + msg.onTbActorStopped(stopReason);
91 } 99 }
92 - tryProcessQueue(true);  
93 } 100 }
94 101
95 private void tryProcessQueue(boolean newMsg) { 102 private void tryProcessQueue(boolean newMsg) {
@@ -180,11 +187,16 @@ public final class TbActorMailbox implements TbActorCtx { @@ -180,11 +187,16 @@ public final class TbActorMailbox implements TbActorCtx {
180 } 187 }
181 188
182 public void destroy() { 189 public void destroy() {
  190 + if (stopReason == null) {
  191 + stopReason = TbActorStopReason.STOPPED;
  192 + }
183 destroyInProgress.set(true); 193 destroyInProgress.set(true);
184 dispatcher.getExecutor().execute(() -> { 194 dispatcher.getExecutor().execute(() -> {
185 try { 195 try {
186 ready.set(NOT_READY); 196 ready.set(NOT_READY);
187 actor.destroy(); 197 actor.destroy();
  198 + highPriorityMsgs.forEach(msg -> msg.onTbActorStopped(stopReason));
  199 + normalPriorityMsgs.forEach(msg -> msg.onTbActorStopped(stopReason));
188 } catch (Throwable t) { 200 } catch (Throwable t) {
189 log.warn("[{}] Failed to destroy actor: {}", selfId, t); 201 log.warn("[{}] Failed to destroy actor: {}", selfId, t);
190 } 202 }
@@ -21,7 +21,7 @@ import org.junit.Assert; @@ -21,7 +21,7 @@ import org.junit.Assert;
21 import org.junit.Before; 21 import org.junit.Before;
22 import org.junit.Test; 22 import org.junit.Test;
23 import org.junit.runner.RunWith; 23 import org.junit.runner.RunWith;
24 -import org.mockito.runners.MockitoJUnitRunner; 24 +import org.mockito.junit.MockitoJUnitRunner;
25 import org.thingsboard.server.common.data.id.DeviceId; 25 import org.thingsboard.server.common.data.id.DeviceId;
26 26
27 import java.util.ArrayList; 27 import java.util.ArrayList;
@@ -49,6 +49,10 @@ @@ -49,6 +49,10 @@
49 <artifactId>guava</artifactId> 49 <artifactId>guava</artifactId>
50 </dependency> 50 </dependency>
51 <dependency> 51 <dependency>
  52 + <groupId>javax.annotation</groupId>
  53 + <artifactId>javax.annotation-api</artifactId>
  54 + </dependency>
  55 + <dependency>
52 <groupId>com.github.fge</groupId> 56 <groupId>com.github.fge</groupId>
53 <artifactId>json-schema-validator</artifactId> 57 <artifactId>json-schema-validator</artifactId>
54 </dependency> 58 </dependency>
@@ -99,7 +103,7 @@ @@ -99,7 +103,7 @@
99 </dependency> 103 </dependency>
100 <dependency> 104 <dependency>
101 <groupId>org.mockito</groupId> 105 <groupId>org.mockito</groupId>
102 - <artifactId>mockito-all</artifactId> 106 + <artifactId>mockito-core</artifactId>
103 <scope>test</scope> 107 <scope>test</scope>
104 </dependency> 108 </dependency>
105 </dependencies> 109 </dependencies>
@@ -23,6 +23,7 @@ import lombok.extern.slf4j.Slf4j; @@ -23,6 +23,7 @@ import lombok.extern.slf4j.Slf4j;
23 import org.springframework.beans.factory.annotation.Autowired; 23 import org.springframework.beans.factory.annotation.Autowired;
24 import org.springframework.beans.factory.annotation.Value; 24 import org.springframework.beans.factory.annotation.Value;
25 import org.springframework.core.env.Environment; 25 import org.springframework.core.env.Environment;
  26 +import org.springframework.core.env.Profiles;
26 import org.thingsboard.server.dao.cassandra.guava.GuavaSession; 27 import org.thingsboard.server.dao.cassandra.guava.GuavaSession;
27 import org.thingsboard.server.dao.cassandra.guava.GuavaSessionBuilder; 28 import org.thingsboard.server.dao.cassandra.guava.GuavaSessionBuilder;
28 import org.thingsboard.server.dao.cassandra.guava.GuavaSessionUtils; 29 import org.thingsboard.server.dao.cassandra.guava.GuavaSessionUtils;
@@ -77,7 +78,7 @@ public abstract class AbstractCassandraCluster { @@ -77,7 +78,7 @@ public abstract class AbstractCassandraCluster {
77 } 78 }
78 79
79 private boolean isInstall() { 80 private boolean isInstall() {
80 - return environment.acceptsProfiles("install"); 81 + return environment.acceptsProfiles(Profiles.of("install"));
81 } 82 }
82 83
83 private void initSession() { 84 private void initSession() {
@@ -18,38 +18,25 @@ package org.thingsboard.server.dao.cassandra.guava; @@ -18,38 +18,25 @@ package org.thingsboard.server.dao.cassandra.guava;
18 import com.datastax.oss.driver.api.core.CqlSession; 18 import com.datastax.oss.driver.api.core.CqlSession;
19 import com.datastax.oss.driver.api.core.config.DriverConfigLoader; 19 import com.datastax.oss.driver.api.core.config.DriverConfigLoader;
20 import com.datastax.oss.driver.api.core.context.DriverContext; 20 import com.datastax.oss.driver.api.core.context.DriverContext;
21 -import com.datastax.oss.driver.api.core.metadata.Node;  
22 -import com.datastax.oss.driver.api.core.metadata.NodeStateListener;  
23 -import com.datastax.oss.driver.api.core.metadata.schema.SchemaChangeListener; 21 +import com.datastax.oss.driver.api.core.session.ProgrammaticArguments;
24 import com.datastax.oss.driver.api.core.session.SessionBuilder; 22 import com.datastax.oss.driver.api.core.session.SessionBuilder;
25 -import com.datastax.oss.driver.api.core.tracker.RequestTracker;  
26 -import com.datastax.oss.driver.api.core.type.codec.TypeCodec;  
27 import edu.umd.cs.findbugs.annotations.NonNull; 23 import edu.umd.cs.findbugs.annotations.NonNull;
28 -import java.util.List;  
29 -import java.util.Map;  
30 -import java.util.function.Predicate;  
31 24
32 public class GuavaSessionBuilder extends SessionBuilder<GuavaSessionBuilder, GuavaSession> { 25 public class GuavaSessionBuilder extends SessionBuilder<GuavaSessionBuilder, GuavaSession> {
33 26
34 @Override 27 @Override
35 protected DriverContext buildContext( 28 protected DriverContext buildContext(
36 DriverConfigLoader configLoader, 29 DriverConfigLoader configLoader,
37 - List<TypeCodec<?>> typeCodecs,  
38 - NodeStateListener nodeStateListener,  
39 - SchemaChangeListener schemaChangeListener,  
40 - RequestTracker requestTracker,  
41 - Map<String, String> localDatacenters,  
42 - Map<String, Predicate<Node>> nodeFilters,  
43 - ClassLoader classLoader) { 30 + ProgrammaticArguments programmaticArguments) {
44 return new GuavaDriverContext( 31 return new GuavaDriverContext(
45 configLoader, 32 configLoader,
46 - typeCodecs,  
47 - nodeStateListener,  
48 - schemaChangeListener,  
49 - requestTracker,  
50 - localDatacenters,  
51 - nodeFilters,  
52 - classLoader); 33 + programmaticArguments.getTypeCodecs(),
  34 + programmaticArguments.getNodeStateListener(),
  35 + programmaticArguments.getSchemaChangeListener(),
  36 + programmaticArguments.getRequestTracker(),
  37 + programmaticArguments.getLocalDatacenters(),
  38 + programmaticArguments.getNodeFilters(),
  39 + programmaticArguments.getClassLoader());
53 } 40 }
54 41
55 @Override 42 @Override
common/dao-api/src/main/java/org/thingsboard/server/dao/util/mapping/JacksonUtil.java renamed from dao/src/main/java/org/thingsboard/server/dao/util/mapping/JacksonUtil.java
@@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
16 package org.thingsboard.server.dao.util.mapping; 16 package org.thingsboard.server.dao.util.mapping;
17 17
18 import com.fasterxml.jackson.core.JsonProcessingException; 18 import com.fasterxml.jackson.core.JsonProcessingException;
  19 +import com.fasterxml.jackson.core.type.TypeReference;
19 import com.fasterxml.jackson.databind.JsonNode; 20 import com.fasterxml.jackson.databind.JsonNode;
20 import com.fasterxml.jackson.databind.ObjectMapper; 21 import com.fasterxml.jackson.databind.ObjectMapper;
21 import com.fasterxml.jackson.databind.node.ObjectNode; 22 import com.fasterxml.jackson.databind.node.ObjectNode;
@@ -38,6 +39,15 @@ public class JacksonUtil { @@ -38,6 +39,15 @@ public class JacksonUtil {
38 } 39 }
39 } 40 }
40 41
  42 + public static <T> T convertValue(Object fromValue, TypeReference<T> toValueTypeRef) {
  43 + try {
  44 + return fromValue != null ? OBJECT_MAPPER.convertValue(fromValue, toValueTypeRef) : null;
  45 + } catch (IllegalArgumentException e) {
  46 + throw new IllegalArgumentException("The given object value: "
  47 + + fromValue + " cannot be converted to " + toValueTypeRef, e);
  48 + }
  49 + }
  50 +
41 public static <T> T fromString(String string, Class<T> clazz) { 51 public static <T> T fromString(String string, Class<T> clazz) {
42 try { 52 try {
43 return string != null ? OBJECT_MAPPER.readValue(string, clazz) : null; 53 return string != null ? OBJECT_MAPPER.readValue(string, clazz) : null;
@@ -72,7 +82,9 @@ public class JacksonUtil { @@ -72,7 +82,9 @@ public class JacksonUtil {
72 } 82 }
73 83
74 public static <T> T clone(T value) { 84 public static <T> T clone(T value) {
75 - return fromString(toString(value), (Class<T>) value.getClass()); 85 + @SuppressWarnings("unchecked")
  86 + Class<T> valueClass = (Class<T>) value.getClass();
  87 + return fromString(toString(value), valueClass);
76 } 88 }
77 89
78 public static <T> JsonNode valueToTree(T value) { 90 public static <T> JsonNode valueToTree(T value) {
@@ -63,7 +63,7 @@ @@ -63,7 +63,7 @@
63 </dependency> 63 </dependency>
64 <dependency> 64 <dependency>
65 <groupId>org.mockito</groupId> 65 <groupId>org.mockito</groupId>
66 - <artifactId>mockito-all</artifactId> 66 + <artifactId>mockito-core</artifactId>
67 <scope>test</scope> 67 <scope>test</scope>
68 </dependency> 68 </dependency>
69 <dependency> 69 <dependency>
@@ -19,7 +19,7 @@ import com.datastax.oss.driver.api.core.uuid.Uuids; @@ -19,7 +19,7 @@ import com.datastax.oss.driver.api.core.uuid.Uuids;
19 import org.junit.Assert; 19 import org.junit.Assert;
20 import org.junit.Test; 20 import org.junit.Test;
21 import org.junit.runner.RunWith; 21 import org.junit.runner.RunWith;
22 -import org.mockito.runners.MockitoJUnitRunner; 22 +import org.mockito.junit.MockitoJUnitRunner;
23 23
24 import java.util.ArrayList; 24 import java.util.ArrayList;
25 import java.util.Arrays; 25 import java.util.Arrays;
@@ -76,7 +76,7 @@ @@ -76,7 +76,7 @@
76 </dependency> 76 </dependency>
77 <dependency> 77 <dependency>
78 <groupId>org.mockito</groupId> 78 <groupId>org.mockito</groupId>
79 - <artifactId>mockito-all</artifactId> 79 + <artifactId>mockito-core</artifactId>
80 <scope>test</scope> 80 <scope>test</scope>
81 </dependency> 81 </dependency>
82 </dependencies> 82 </dependencies>
@@ -67,11 +67,6 @@ public enum MsgType { @@ -67,11 +67,6 @@ public enum MsgType {
67 REMOTE_TO_RULE_CHAIN_TELL_NEXT_MSG, 67 REMOTE_TO_RULE_CHAIN_TELL_NEXT_MSG,
68 68
69 /** 69 /**
70 - * Message that is sent by RuleActor implementation to RuleActor itself to log the error.  
71 - */  
72 - RULE_TO_SELF_ERROR_MSG,  
73 -  
74 - /**  
75 * Message that is sent by RuleActor implementation to RuleActor itself to process the message. 70 * Message that is sent by RuleActor implementation to RuleActor itself to process the message.
76 */ 71 */
77 RULE_TO_SELF_MSG, 72 RULE_TO_SELF_MSG,
@@ -22,4 +22,12 @@ public interface TbActorMsg { @@ -22,4 +22,12 @@ public interface TbActorMsg {
22 22
23 MsgType getMsgType(); 23 MsgType getMsgType();
24 24
  25 + /**
  26 + * Executed when the target TbActor is stopped or destroyed.
  27 + * For example, rule node failed to initialize or removed from rule chain.
  28 + * Implementation should cleanup the resources.
  29 + */
  30 + default void onTbActorStopped(TbActorStopReason reason) {
  31 + }
  32 +
25 } 33 }
common/message/src/main/java/org/thingsboard/server/common/msg/TbActorStopReason.java renamed from application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleNodeToSelfErrorMsg.java
@@ -13,25 +13,10 @@ @@ -13,25 +13,10 @@
13 * See the License for the specific language governing permissions and 13 * See the License for the specific language governing permissions and
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 -package org.thingsboard.server.actors.ruleChain; 16 +package org.thingsboard.server.common.msg;
17 17
18 -import lombok.Data;  
19 -import org.thingsboard.server.common.msg.MsgType;  
20 -import org.thingsboard.server.common.msg.TbActorMsg;  
21 -import org.thingsboard.server.common.msg.TbMsg; 18 +public enum TbActorStopReason {
22 19
23 -/**  
24 - * Created by ashvayka on 19.03.18.  
25 - */  
26 -@Data  
27 -final class RuleNodeToSelfErrorMsg implements TbActorMsg {  
28 -  
29 - private final TbMsg msg;  
30 - private final Throwable error;  
31 -  
32 - @Override  
33 - public MsgType getMsgType() {  
34 - return MsgType.RULE_TO_SELF_ERROR_MSG;  
35 - } 20 + INIT_FAILED, STOPPED
36 21
37 } 22 }
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.common.msg;
  17 +
  18 +import lombok.EqualsAndHashCode;
  19 +import lombok.Getter;
  20 +
  21 +@EqualsAndHashCode
  22 +public abstract class TbRuleEngineActorMsg implements TbActorMsg {
  23 +
  24 + @Getter
  25 + protected final TbMsg msg;
  26 +
  27 + public TbRuleEngineActorMsg(TbMsg msg) {
  28 + this.msg = msg;
  29 + }
  30 +}
@@ -15,32 +15,58 @@ @@ -15,32 +15,58 @@
15 */ 15 */
16 package org.thingsboard.server.common.msg.queue; 16 package org.thingsboard.server.common.msg.queue;
17 17
18 -import lombok.Data; 18 +import lombok.EqualsAndHashCode;
  19 +import lombok.Getter;
  20 +import lombok.ToString;
19 import org.thingsboard.server.common.data.id.TenantId; 21 import org.thingsboard.server.common.data.id.TenantId;
20 import org.thingsboard.server.common.msg.MsgType; 22 import org.thingsboard.server.common.msg.MsgType;
21 -import org.thingsboard.server.common.msg.TbActorMsg; 23 +import org.thingsboard.server.common.msg.TbActorStopReason;
22 import org.thingsboard.server.common.msg.TbMsg; 24 import org.thingsboard.server.common.msg.TbMsg;
  25 +import org.thingsboard.server.common.msg.TbRuleEngineActorMsg;
23 26
24 -import java.io.Serializable;  
25 import java.util.Set; 27 import java.util.Set;
26 28
27 /** 29 /**
28 * Created by ashvayka on 15.03.18. 30 * Created by ashvayka on 15.03.18.
29 */ 31 */
30 -@Data  
31 -public final class QueueToRuleEngineMsg implements TbActorMsg { 32 +@ToString
  33 +@EqualsAndHashCode(callSuper = true)
  34 +public final class QueueToRuleEngineMsg extends TbRuleEngineActorMsg {
32 35
  36 + @Getter
33 private final TenantId tenantId; 37 private final TenantId tenantId;
34 - private final TbMsg tbMsg; 38 + @Getter
35 private final Set<String> relationTypes; 39 private final Set<String> relationTypes;
  40 + @Getter
36 private final String failureMessage; 41 private final String failureMessage;
37 42
  43 + public QueueToRuleEngineMsg(TenantId tenantId, TbMsg tbMsg, Set<String> relationTypes, String failureMessage) {
  44 + super(tbMsg);
  45 + this.tenantId = tenantId;
  46 + this.relationTypes = relationTypes;
  47 + this.failureMessage = failureMessage;
  48 + }
  49 +
38 @Override 50 @Override
39 public MsgType getMsgType() { 51 public MsgType getMsgType() {
40 return MsgType.QUEUE_TO_RULE_ENGINE_MSG; 52 return MsgType.QUEUE_TO_RULE_ENGINE_MSG;
41 } 53 }
42 54
  55 + @Override
  56 + public void onTbActorStopped(TbActorStopReason reason) {
  57 + String message;
  58 + if (msg.getRuleChainId() != null) {
  59 + message = reason == TbActorStopReason.STOPPED ?
  60 + String.format("Rule chain [%s] stopped", msg.getRuleChainId().getId()) :
  61 + String.format("Failed to initialize rule chain [%s]!", msg.getRuleChainId().getId());
  62 + } else {
  63 + message = reason == TbActorStopReason.STOPPED ? "Rule chain stopped" : "Failed to initialize rule chain!";
  64 + }
  65 + msg.getCallback().onFailure(new RuleEngineException(message));
  66 + }
  67 +
43 public boolean isTellNext() { 68 public boolean isTellNext() {
44 return relationTypes != null && !relationTypes.isEmpty(); 69 return relationTypes != null && !relationTypes.isEmpty();
45 } 70 }
  71 +
46 } 72 }
@@ -24,6 +24,9 @@ import org.thingsboard.server.common.data.rule.RuleNode; @@ -24,6 +24,9 @@ import org.thingsboard.server.common.data.rule.RuleNode;
24 24
25 @Slf4j 25 @Slf4j
26 public class RuleNodeException extends RuleEngineException { 26 public class RuleNodeException extends RuleEngineException {
  27 +
  28 + private static final long serialVersionUID = -1776681087370749776L;
  29 +
27 @Getter 30 @Getter
28 private final String ruleChainName; 31 private final String ruleChainName;
29 @Getter 32 @Getter
@@ -33,6 +36,7 @@ public class RuleNodeException extends RuleEngineException { @@ -33,6 +36,7 @@ public class RuleNodeException extends RuleEngineException {
33 @Getter 36 @Getter
34 private final RuleNodeId ruleNodeId; 37 private final RuleNodeId ruleNodeId;
35 38
  39 +
36 public RuleNodeException(String message, String ruleChainName, RuleNode ruleNode) { 40 public RuleNodeException(String message, String ruleChainName, RuleNode ruleNode) {
37 super(message); 41 super(message);
38 this.ruleChainName = ruleChainName; 42 this.ruleChainName = ruleChainName;
@@ -124,7 +124,7 @@ @@ -124,7 +124,7 @@
124 </dependency> 124 </dependency>
125 <dependency> 125 <dependency>
126 <groupId>org.mockito</groupId> 126 <groupId>org.mockito</groupId>
127 - <artifactId>mockito-all</artifactId> 127 + <artifactId>mockito-core</artifactId>
128 <scope>test</scope> 128 <scope>test</scope>
129 </dependency> 129 </dependency>
130 </dependencies> 130 </dependencies>
@@ -154,6 +154,7 @@ public class TbServiceBusConsumerTemplate<T extends TbQueueMsg> extends Abstract @@ -154,6 +154,7 @@ public class TbServiceBusConsumerTemplate<T extends TbQueueMsg> extends Abstract
154 } 154 }
155 155
156 private <V> CompletableFuture<List<V>> fromList(List<CompletableFuture<V>> futures) { 156 private <V> CompletableFuture<List<V>> fromList(List<CompletableFuture<V>> futures) {
  157 + @SuppressWarnings("unchecked")
157 CompletableFuture<Collection<V>>[] arrayFuture = new CompletableFuture[futures.size()]; 158 CompletableFuture<Collection<V>>[] arrayFuture = new CompletableFuture[futures.size()];
158 futures.toArray(arrayFuture); 159 futures.toArray(arrayFuture);
159 160
@@ -22,6 +22,10 @@ import org.apache.kafka.clients.CommonClientConfigs; @@ -22,6 +22,10 @@ import org.apache.kafka.clients.CommonClientConfigs;
22 import org.apache.kafka.clients.admin.AdminClientConfig; 22 import org.apache.kafka.clients.admin.AdminClientConfig;
23 import org.apache.kafka.clients.consumer.ConsumerConfig; 23 import org.apache.kafka.clients.consumer.ConsumerConfig;
24 import org.apache.kafka.clients.producer.ProducerConfig; 24 import org.apache.kafka.clients.producer.ProducerConfig;
  25 +import org.apache.kafka.common.serialization.ByteArrayDeserializer;
  26 +import org.apache.kafka.common.serialization.ByteArraySerializer;
  27 +import org.apache.kafka.common.serialization.StringDeserializer;
  28 +import org.apache.kafka.common.serialization.StringSerializer;
25 import org.springframework.beans.factory.annotation.Value; 29 import org.springframework.beans.factory.annotation.Value;
26 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 30 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
27 import org.springframework.boot.context.properties.ConfigurationProperties; 31 import org.springframework.boot.context.properties.ConfigurationProperties;
@@ -107,8 +111,8 @@ public class TbKafkaSettings { @@ -107,8 +111,8 @@ public class TbKafkaSettings {
107 props.put(ConsumerConfig.FETCH_MAX_BYTES_CONFIG, fetchMaxBytes); 111 props.put(ConsumerConfig.FETCH_MAX_BYTES_CONFIG, fetchMaxBytes);
108 props.put(ConsumerConfig.MAX_POLL_INTERVAL_MS_CONFIG, maxPollIntervalMs); 112 props.put(ConsumerConfig.MAX_POLL_INTERVAL_MS_CONFIG, maxPollIntervalMs);
109 113
110 - props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer");  
111 - props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.ByteArrayDeserializer"); 114 + props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
  115 + props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, ByteArrayDeserializer.class);
112 return props; 116 return props;
113 } 117 }
114 118
@@ -120,8 +124,8 @@ public class TbKafkaSettings { @@ -120,8 +124,8 @@ public class TbKafkaSettings {
120 props.put(ProducerConfig.BATCH_SIZE_CONFIG, batchSize); 124 props.put(ProducerConfig.BATCH_SIZE_CONFIG, batchSize);
121 props.put(ProducerConfig.LINGER_MS_CONFIG, lingerMs); 125 props.put(ProducerConfig.LINGER_MS_CONFIG, lingerMs);
122 props.put(ProducerConfig.BUFFER_MEMORY_CONFIG, bufferMemory); 126 props.put(ProducerConfig.BUFFER_MEMORY_CONFIG, bufferMemory);
123 - props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");  
124 - props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.ByteArraySerializer"); 127 + props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
  128 + props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, ByteArraySerializer.class);
125 return props; 129 return props;
126 } 130 }
127 131
@@ -60,6 +60,7 @@ public final class InMemoryStorage { @@ -60,6 +60,7 @@ public final class InMemoryStorage {
60 public <T extends TbQueueMsg> List<T> get(String topic) throws InterruptedException { 60 public <T extends TbQueueMsg> List<T> get(String topic) throws InterruptedException {
61 if (storage.containsKey(topic)) { 61 if (storage.containsKey(topic)) {
62 List<T> entities; 62 List<T> entities;
  63 + @SuppressWarnings("unchecked")
63 T first = (T) storage.get(topic).poll(); 64 T first = (T) storage.get(topic).poll();
64 if (first != null) { 65 if (first != null) {
65 entities = new ArrayList<>(); 66 entities = new ArrayList<>();
@@ -67,7 +68,9 @@ public final class InMemoryStorage { @@ -67,7 +68,9 @@ public final class InMemoryStorage {
67 List<TbQueueMsg> otherList = new ArrayList<>(); 68 List<TbQueueMsg> otherList = new ArrayList<>();
68 storage.get(topic).drainTo(otherList, 999); 69 storage.get(topic).drainTo(otherList, 999);
69 for (TbQueueMsg other : otherList) { 70 for (TbQueueMsg other : otherList) {
70 - entities.add((T) other); 71 + @SuppressWarnings("unchecked")
  72 + T entity = (T) other;
  73 + entities.add(entity);
71 } 74 }
72 } else { 75 } else {
73 entities = Collections.emptyList(); 76 entities = Collections.emptyList();
@@ -64,6 +64,7 @@ public class InMemoryTbQueueConsumer<T extends TbQueueMsg> implements TbQueueCon @@ -64,6 +64,7 @@ public class InMemoryTbQueueConsumer<T extends TbQueueMsg> implements TbQueueCon
64 @Override 64 @Override
65 public List<T> poll(long durationInMillis) { 65 public List<T> poll(long durationInMillis) {
66 if (subscribed) { 66 if (subscribed) {
  67 + @SuppressWarnings("unchecked")
67 List<T> messages = partitions 68 List<T> messages = partitions
68 .stream() 69 .stream()
69 .map(tpi -> { 70 .map(tpi -> {
@@ -47,6 +47,7 @@ public class DefaultTbApiUsageClient implements TbApiUsageClient { @@ -47,6 +47,7 @@ public class DefaultTbApiUsageClient implements TbApiUsageClient {
47 @Value("${usage.stats.report.interval:10}") 47 @Value("${usage.stats.report.interval:10}")
48 private int interval; 48 private int interval;
49 49
  50 + @SuppressWarnings("unchecked")
50 private final ConcurrentMap<TenantId, AtomicLong>[] values = new ConcurrentMap[ApiUsageRecordKey.values().length]; 51 private final ConcurrentMap<TenantId, AtomicLong>[] values = new ConcurrentMap[ApiUsageRecordKey.values().length];
51 private final PartitionService partitionService; 52 private final PartitionService partitionService;
52 private final SchedulerComponent scheduler; 53 private final SchedulerComponent scheduler;
@@ -79,7 +79,7 @@ @@ -79,7 +79,7 @@
79 </dependency> 79 </dependency>
80 <dependency> 80 <dependency>
81 <groupId>org.mockito</groupId> 81 <groupId>org.mockito</groupId>
82 - <artifactId>mockito-all</artifactId> 82 + <artifactId>mockito-core</artifactId>
83 <scope>test</scope> 83 <scope>test</scope>
84 </dependency> 84 </dependency>
85 </dependencies> 85 </dependencies>
@@ -89,4 +89,4 @@ @@ -89,4 +89,4 @@
89 </plugins> 89 </plugins>
90 </build> 90 </build>
91 91
92 -</project>  
  92 +</project>
@@ -80,7 +80,7 @@ @@ -80,7 +80,7 @@
80 </dependency> 80 </dependency>
81 <dependency> 81 <dependency>
82 <groupId>org.mockito</groupId> 82 <groupId>org.mockito</groupId>
83 - <artifactId>mockito-all</artifactId> 83 + <artifactId>mockito-core</artifactId>
84 <scope>test</scope> 84 <scope>test</scope>
85 </dependency> 85 </dependency>
86 </dependencies> 86 </dependencies>
@@ -73,7 +73,7 @@ @@ -73,7 +73,7 @@
73 </dependency> 73 </dependency>
74 <dependency> 74 <dependency>
75 <groupId>org.mockito</groupId> 75 <groupId>org.mockito</groupId>
76 - <artifactId>mockito-all</artifactId> 76 + <artifactId>mockito-core</artifactId>
77 <scope>test</scope> 77 <scope>test</scope>
78 </dependency> 78 </dependency>
79 </dependencies> 79 </dependencies>
@@ -90,7 +90,7 @@ @@ -90,7 +90,7 @@
90 </dependency> 90 </dependency>
91 <dependency> 91 <dependency>
92 <groupId>org.mockito</groupId> 92 <groupId>org.mockito</groupId>
93 - <artifactId>mockito-all</artifactId> 93 + <artifactId>mockito-core</artifactId>
94 <scope>test</scope> 94 <scope>test</scope>
95 </dependency> 95 </dependency>
96 </dependencies> 96 </dependencies>
@@ -45,6 +45,7 @@ import java.io.IOException; @@ -45,6 +45,7 @@ import java.io.IOException;
45 import java.io.InputStream; 45 import java.io.InputStream;
46 import java.net.URL; 46 import java.net.URL;
47 import java.security.KeyStore; 47 import java.security.KeyStore;
  48 +import java.security.cert.CertificateEncodingException;
48 import java.security.cert.CertificateException; 49 import java.security.cert.CertificateException;
49 import java.security.cert.X509Certificate; 50 import java.security.cert.X509Certificate;
50 import java.util.concurrent.CountDownLatch; 51 import java.util.concurrent.CountDownLatch;
@@ -154,7 +155,7 @@ public class MqttSslHandlerProvider { @@ -154,7 +155,7 @@ public class MqttSslHandlerProvider {
154 String credentialsBody = null; 155 String credentialsBody = null;
155 for (X509Certificate cert : chain) { 156 for (X509Certificate cert : chain) {
156 try { 157 try {
157 - String strCert = SslUtil.getX509CertificateString(cert); 158 + String strCert = SslUtil.getCertificateString(cert);
158 String sha3Hash = EncryptionUtil.getSha3Hash(strCert); 159 String sha3Hash = EncryptionUtil.getSha3Hash(strCert);
159 final String[] credentialsBodyHolder = new String[1]; 160 final String[] credentialsBodyHolder = new String[1];
160 CountDownLatch latch = new CountDownLatch(1); 161 CountDownLatch latch = new CountDownLatch(1);
@@ -179,7 +180,7 @@ public class MqttSslHandlerProvider { @@ -179,7 +180,7 @@ public class MqttSslHandlerProvider {
179 credentialsBody = credentialsBodyHolder[0]; 180 credentialsBody = credentialsBodyHolder[0];
180 break; 181 break;
181 } 182 }
182 - } catch (InterruptedException | IOException e) { 183 + } catch (InterruptedException | CertificateEncodingException e) {
183 log.error(e.getMessage(), e); 184 log.error(e.getMessage(), e);
184 } 185 }
185 } 186 }
@@ -35,6 +35,7 @@ import io.netty.handler.codec.mqtt.MqttSubscribeMessage; @@ -35,6 +35,7 @@ import io.netty.handler.codec.mqtt.MqttSubscribeMessage;
35 import io.netty.handler.codec.mqtt.MqttTopicSubscription; 35 import io.netty.handler.codec.mqtt.MqttTopicSubscription;
36 import io.netty.handler.codec.mqtt.MqttUnsubscribeMessage; 36 import io.netty.handler.codec.mqtt.MqttUnsubscribeMessage;
37 import io.netty.handler.ssl.SslHandler; 37 import io.netty.handler.ssl.SslHandler;
  38 +import io.netty.util.CharsetUtil;
38 import io.netty.util.ReferenceCountUtil; 39 import io.netty.util.ReferenceCountUtil;
39 import io.netty.util.concurrent.Future; 40 import io.netty.util.concurrent.Future;
40 import io.netty.util.concurrent.GenericFutureListener; 41 import io.netty.util.concurrent.GenericFutureListener;
@@ -68,7 +69,8 @@ import org.thingsboard.server.transport.mqtt.session.MqttTopicMatcher; @@ -68,7 +69,8 @@ import org.thingsboard.server.transport.mqtt.session.MqttTopicMatcher;
68 import org.thingsboard.server.transport.mqtt.util.SslUtil; 69 import org.thingsboard.server.transport.mqtt.util.SslUtil;
69 70
70 import javax.net.ssl.SSLPeerUnverifiedException; 71 import javax.net.ssl.SSLPeerUnverifiedException;
71 -import javax.security.cert.X509Certificate; 72 +import java.security.cert.Certificate;
  73 +import java.security.cert.X509Certificate;
72 import java.io.IOException; 74 import java.io.IOException;
73 import java.net.InetSocketAddress; 75 import java.net.InetSocketAddress;
74 import java.util.ArrayList; 76 import java.util.ArrayList;
@@ -315,7 +317,7 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement @@ -315,7 +317,7 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement
315 } 317 }
316 318
317 private <T> TransportServiceCallback<Void> getPubAckCallback(final ChannelHandlerContext ctx, final int msgId, final T msg) { 319 private <T> TransportServiceCallback<Void> getPubAckCallback(final ChannelHandlerContext ctx, final int msgId, final T msg) {
318 - return new TransportServiceCallback<Void>() { 320 + return new TransportServiceCallback<>() {
319 @Override 321 @Override
320 public void onSuccess(Void dummy) { 322 public void onSuccess(Void dummy) {
321 log.trace("[{}] Published msg: {}", sessionId, msg); 323 log.trace("[{}] Published msg: {}", sessionId, msg);
@@ -482,12 +484,13 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement @@ -482,12 +484,13 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement
482 if (userName != null) { 484 if (userName != null) {
483 request.setUserName(userName); 485 request.setUserName(userName);
484 } 486 }
485 - String password = connectMessage.payload().password();  
486 - if (password != null) { 487 + byte[] passwordBytes = connectMessage.payload().passwordInBytes();
  488 + if (passwordBytes != null) {
  489 + String password = new String(passwordBytes, CharsetUtil.UTF_8);
487 request.setPassword(password); 490 request.setPassword(password);
488 } 491 }
489 transportService.process(DeviceTransportType.MQTT, request.build(), 492 transportService.process(DeviceTransportType.MQTT, request.build(),
490 - new TransportServiceCallback<ValidateDeviceCredentialsResponse>() { 493 + new TransportServiceCallback<>() {
491 @Override 494 @Override
492 public void onSuccess(ValidateDeviceCredentialsResponse msg) { 495 public void onSuccess(ValidateDeviceCredentialsResponse msg) {
493 onValidateDeviceResponse(msg, ctx, connectMessage); 496 onValidateDeviceResponse(msg, ctx, connectMessage);
@@ -507,10 +510,10 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement @@ -507,10 +510,10 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement
507 if (!context.isSkipValidityCheckForClientCert()) { 510 if (!context.isSkipValidityCheckForClientCert()) {
508 cert.checkValidity(); 511 cert.checkValidity();
509 } 512 }
510 - String strCert = SslUtil.getX509CertificateString(cert); 513 + String strCert = SslUtil.getCertificateString(cert);
511 String sha3Hash = EncryptionUtil.getSha3Hash(strCert); 514 String sha3Hash = EncryptionUtil.getSha3Hash(strCert);
512 transportService.process(DeviceTransportType.MQTT, ValidateDeviceX509CertRequestMsg.newBuilder().setHash(sha3Hash).build(), 515 transportService.process(DeviceTransportType.MQTT, ValidateDeviceX509CertRequestMsg.newBuilder().setHash(sha3Hash).build(),
513 - new TransportServiceCallback<ValidateDeviceCredentialsResponse>() { 516 + new TransportServiceCallback<>() {
514 @Override 517 @Override
515 public void onSuccess(ValidateDeviceCredentialsResponse msg) { 518 public void onSuccess(ValidateDeviceCredentialsResponse msg) {
516 onValidateDeviceResponse(msg, ctx, connectMessage); 519 onValidateDeviceResponse(msg, ctx, connectMessage);
@@ -531,9 +534,9 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement @@ -531,9 +534,9 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement
531 534
532 private X509Certificate getX509Certificate() { 535 private X509Certificate getX509Certificate() {
533 try { 536 try {
534 - X509Certificate[] certChain = sslHandler.engine().getSession().getPeerCertificateChain(); 537 + Certificate[] certChain = sslHandler.engine().getSession().getPeerCertificates();
535 if (certChain.length > 0) { 538 if (certChain.length > 0) {
536 - return certChain[0]; 539 + return (X509Certificate) certChain[0];
537 } 540 }
538 } catch (SSLPeerUnverifiedException e) { 541 } catch (SSLPeerUnverifiedException e) {
539 log.warn(e.getMessage()); 542 log.warn(e.getMessage());
@@ -20,8 +20,8 @@ import org.springframework.util.Base64Utils; @@ -20,8 +20,8 @@ import org.springframework.util.Base64Utils;
20 import org.thingsboard.server.common.msg.EncryptionUtil; 20 import org.thingsboard.server.common.msg.EncryptionUtil;
21 21
22 import java.io.IOException; 22 import java.io.IOException;
  23 +import java.security.cert.Certificate;
23 import java.security.cert.CertificateEncodingException; 24 import java.security.cert.CertificateEncodingException;
24 -import java.security.cert.X509Certificate;  
25 25
26 /** 26 /**
27 * @author Valerii Sosliuk 27 * @author Valerii Sosliuk
@@ -32,15 +32,8 @@ public class SslUtil { @@ -32,15 +32,8 @@ public class SslUtil {
32 private SslUtil() { 32 private SslUtil() {
33 } 33 }
34 34
35 - public static String getX509CertificateString(X509Certificate cert)  
36 - throws CertificateEncodingException, IOException {  
37 - Base64Utils.encodeToString(cert.getEncoded());  
38 - return EncryptionUtil.trimNewLines(Base64Utils.encodeToString(cert.getEncoded()));  
39 - }  
40 -  
41 - public static String getX509CertificateString(javax.security.cert.X509Certificate cert)  
42 - throws javax.security.cert.CertificateEncodingException, IOException {  
43 - Base64Utils.encodeToString(cert.getEncoded()); 35 + public static String getCertificateString(Certificate cert)
  36 + throws CertificateEncodingException {
44 return EncryptionUtil.trimNewLines(Base64Utils.encodeToString(cert.getEncoded())); 37 return EncryptionUtil.trimNewLines(Base64Utils.encodeToString(cert.getEncoded()));
45 } 38 }
46 } 39 }
@@ -17,7 +17,7 @@ package org.thingsboard.server.transport.mqtt.util; @@ -17,7 +17,7 @@ package org.thingsboard.server.transport.mqtt.util;
17 17
18 import org.junit.Test; 18 import org.junit.Test;
19 import org.junit.runner.RunWith; 19 import org.junit.runner.RunWith;
20 -import org.mockito.runners.MockitoJUnitRunner; 20 +import org.mockito.junit.MockitoJUnitRunner;
21 21
22 import javax.script.ScriptException; 22 import javax.script.ScriptException;
23 23
@@ -87,7 +87,7 @@ @@ -87,7 +87,7 @@
87 </dependency> 87 </dependency>
88 <dependency> 88 <dependency>
89 <groupId>org.mockito</groupId> 89 <groupId>org.mockito</groupId>
90 - <artifactId>mockito-all</artifactId> 90 + <artifactId>mockito-core</artifactId>
91 <scope>test</scope> 91 <scope>test</scope>
92 </dependency> 92 </dependency>
93 <dependency> 93 <dependency>
@@ -32,6 +32,7 @@ public class ProtoWithFSTService implements DataDecodingEncodingService { @@ -32,6 +32,7 @@ public class ProtoWithFSTService implements DataDecodingEncodingService {
32 @Override 32 @Override
33 public <T> Optional<T> decode(byte[] byteArray) { 33 public <T> Optional<T> decode(byte[] byteArray) {
34 try { 34 try {
  35 + @SuppressWarnings("unchecked")
35 T msg = (T) config.asObject(byteArray); 36 T msg = (T) config.asObject(byteArray);
36 return Optional.of(msg); 37 return Optional.of(msg);
37 } catch (IllegalArgumentException e) { 38 } catch (IllegalArgumentException e) {
@@ -42,6 +42,10 @@ @@ -42,6 +42,10 @@
42 <scope>provided</scope> 42 <scope>provided</scope>
43 </dependency> 43 </dependency>
44 <dependency> 44 <dependency>
  45 + <groupId>javax.annotation</groupId>
  46 + <artifactId>javax.annotation-api</artifactId>
  47 + </dependency>
  48 + <dependency>
45 <groupId>org.slf4j</groupId> 49 <groupId>org.slf4j</groupId>
46 <artifactId>slf4j-api</artifactId> 50 <artifactId>slf4j-api</artifactId>
47 </dependency> 51 </dependency>
@@ -64,7 +68,7 @@ @@ -64,7 +68,7 @@
64 </dependency> 68 </dependency>
65 <dependency> 69 <dependency>
66 <groupId>org.mockito</groupId> 70 <groupId>org.mockito</groupId>
67 - <artifactId>mockito-all</artifactId> 71 + <artifactId>mockito-core</artifactId>
68 <scope>test</scope> 72 <scope>test</scope>
69 </dependency> 73 </dependency>
70 </dependencies> 74 </dependencies>
@@ -92,7 +92,7 @@ @@ -92,7 +92,7 @@
92 </dependency> 92 </dependency>
93 <dependency> 93 <dependency>
94 <groupId>org.mockito</groupId> 94 <groupId>org.mockito</groupId>
95 - <artifactId>mockito-all</artifactId> 95 + <artifactId>mockito-core</artifactId>
96 <scope>test</scope> 96 <scope>test</scope>
97 </dependency> 97 </dependency>
98 <dependency> 98 <dependency>
@@ -40,11 +40,11 @@ public abstract class DaoUtil { @@ -40,11 +40,11 @@ public abstract class DaoUtil {
40 40
41 public static <T> PageData<T> toPageData(Page<? extends ToData<T>> page) { 41 public static <T> PageData<T> toPageData(Page<? extends ToData<T>> page) {
42 List<T> data = convertDataList(page.getContent()); 42 List<T> data = convertDataList(page.getContent());
43 - return new PageData(data, page.getTotalPages(), page.getTotalElements(), page.hasNext()); 43 + return new PageData<>(data, page.getTotalPages(), page.getTotalElements(), page.hasNext());
44 } 44 }
45 45
46 public static <T> PageData<T> pageToPageData(Page<T> page) { 46 public static <T> PageData<T> pageToPageData(Page<T> page) {
47 - return new PageData(page.getContent(), page.getTotalPages(), page.getTotalElements(), page.hasNext()); 47 + return new PageData<>(page.getContent(), page.getTotalPages(), page.getTotalElements(), page.hasNext());
48 } 48 }
49 49
50 public static Pageable toPageable(PageLink pageLink) { 50 public static Pageable toPageable(PageLink pageLink) {
@@ -306,7 +306,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ @@ -306,7 +306,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
306 )); 306 ));
307 } 307 }
308 return Futures.transform(Futures.successfulAsList(alarmFutures), 308 return Futures.transform(Futures.successfulAsList(alarmFutures),
309 - alarmInfos -> new PageData(alarmInfos, alarms.getTotalPages(), alarms.getTotalElements(), 309 + alarmInfos -> new PageData<>(alarmInfos, alarms.getTotalPages(), alarms.getTotalElements(),
310 alarms.hasNext()), MoreExecutors.directExecutor()); 310 alarms.hasNext()), MoreExecutors.directExecutor());
311 } 311 }
312 return Futures.immediateFuture(alarms); 312 return Futures.immediateFuture(alarms);
@@ -190,6 +190,7 @@ public class AuditLogServiceImpl implements AuditLogService { @@ -190,6 +190,7 @@ public class AuditLogServiceImpl implements AuditLogService {
190 case ATTRIBUTES_UPDATED: 190 case ATTRIBUTES_UPDATED:
191 actionData.put("entityId", entityId.toString()); 191 actionData.put("entityId", entityId.toString());
192 String scope = extractParameter(String.class, 0, additionalInfo); 192 String scope = extractParameter(String.class, 0, additionalInfo);
  193 + @SuppressWarnings("unchecked")
193 List<AttributeKvEntry> attributes = extractParameter(List.class, 1, additionalInfo); 194 List<AttributeKvEntry> attributes = extractParameter(List.class, 1, additionalInfo);
194 actionData.put("scope", scope); 195 actionData.put("scope", scope);
195 ObjectNode attrsNode = JacksonUtil.newObjectNode(); 196 ObjectNode attrsNode = JacksonUtil.newObjectNode();
@@ -205,6 +206,7 @@ public class AuditLogServiceImpl implements AuditLogService { @@ -205,6 +206,7 @@ public class AuditLogServiceImpl implements AuditLogService {
205 actionData.put("entityId", entityId.toString()); 206 actionData.put("entityId", entityId.toString());
206 scope = extractParameter(String.class, 0, additionalInfo); 207 scope = extractParameter(String.class, 0, additionalInfo);
207 actionData.put("scope", scope); 208 actionData.put("scope", scope);
  209 + @SuppressWarnings("unchecked")
208 List<String> keys = extractParameter(List.class, 1, additionalInfo); 210 List<String> keys = extractParameter(List.class, 1, additionalInfo);
209 ArrayNode attrsArrayNode = actionData.putArray("attributes"); 211 ArrayNode attrsArrayNode = actionData.putArray("attributes");
210 if (keys != null) { 212 if (keys != null) {
@@ -267,6 +269,7 @@ public class AuditLogServiceImpl implements AuditLogService { @@ -267,6 +269,7 @@ public class AuditLogServiceImpl implements AuditLogService {
267 break; 269 break;
268 case TIMESERIES_UPDATED: 270 case TIMESERIES_UPDATED:
269 actionData.put("entityId", entityId.toString()); 271 actionData.put("entityId", entityId.toString());
  272 + @SuppressWarnings("unchecked")
270 List<TsKvEntry> updatedTimeseries = extractParameter(List.class, 0, additionalInfo); 273 List<TsKvEntry> updatedTimeseries = extractParameter(List.class, 0, additionalInfo);
271 if (updatedTimeseries != null) { 274 if (updatedTimeseries != null) {
272 ArrayNode result = actionData.putArray("timeseries"); 275 ArrayNode result = actionData.putArray("timeseries");
@@ -283,6 +286,7 @@ public class AuditLogServiceImpl implements AuditLogService { @@ -283,6 +286,7 @@ public class AuditLogServiceImpl implements AuditLogService {
283 break; 286 break;
284 case TIMESERIES_DELETED: 287 case TIMESERIES_DELETED:
285 actionData.put("entityId", entityId.toString()); 288 actionData.put("entityId", entityId.toString());
  289 + @SuppressWarnings("unchecked")
286 List<String> timeseriesKeys = extractParameter(List.class, 0, additionalInfo); 290 List<String> timeseriesKeys = extractParameter(List.class, 0, additionalInfo);
287 if (timeseriesKeys != null) { 291 if (timeseriesKeys != null) {
288 ArrayNode timeseriesArrayNode = actionData.putArray("timeseries"); 292 ArrayNode timeseriesArrayNode = actionData.putArray("timeseries");
@@ -36,22 +36,22 @@ public class DummyAuditLogServiceImpl implements AuditLogService { @@ -36,22 +36,22 @@ public class DummyAuditLogServiceImpl implements AuditLogService {
36 36
37 @Override 37 @Override
38 public PageData<AuditLog> findAuditLogsByTenantIdAndCustomerId(TenantId tenantId, CustomerId customerId, List<ActionType> actionTypes, TimePageLink pageLink) { 38 public PageData<AuditLog> findAuditLogsByTenantIdAndCustomerId(TenantId tenantId, CustomerId customerId, List<ActionType> actionTypes, TimePageLink pageLink) {
39 - return new PageData(); 39 + return new PageData<>();
40 } 40 }
41 41
42 @Override 42 @Override
43 public PageData<AuditLog> findAuditLogsByTenantIdAndUserId(TenantId tenantId, UserId userId, List<ActionType> actionTypes, TimePageLink pageLink) { 43 public PageData<AuditLog> findAuditLogsByTenantIdAndUserId(TenantId tenantId, UserId userId, List<ActionType> actionTypes, TimePageLink pageLink) {
44 - return new PageData(); 44 + return new PageData<>();
45 } 45 }
46 46
47 @Override 47 @Override
48 public PageData<AuditLog> findAuditLogsByTenantIdAndEntityId(TenantId tenantId, EntityId entityId, List<ActionType> actionTypes, TimePageLink pageLink) { 48 public PageData<AuditLog> findAuditLogsByTenantIdAndEntityId(TenantId tenantId, EntityId entityId, List<ActionType> actionTypes, TimePageLink pageLink) {
49 - return new PageData(); 49 + return new PageData<>();
50 } 50 }
51 51
52 @Override 52 @Override
53 public PageData<AuditLog> findAuditLogsByTenantId(TenantId tenantId, List<ActionType> actionTypes, TimePageLink pageLink) { 53 public PageData<AuditLog> findAuditLogsByTenantId(TenantId tenantId, List<ActionType> actionTypes, TimePageLink pageLink) {
54 - return new PageData(); 54 + return new PageData<>();
55 } 55 }
56 56
57 @Override 57 @Override
@@ -203,6 +203,8 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe @@ -203,6 +203,8 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
203 } catch (Exception t) { 203 } catch (Exception t) {
204 ConstraintViolationException e = extractConstraintViolationException(t).orElse(null); 204 ConstraintViolationException e = extractConstraintViolationException(t).orElse(null);
205 if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("device_name_unq_key")) { 205 if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("device_name_unq_key")) {
  206 + // remove device from cache in case null value cached in the distributed redis.
  207 + removeDeviceFromCache(device.getTenantId(), device.getName());
206 throw new DataValidationException("Device with such name already exists!"); 208 throw new DataValidationException("Device with such name already exists!");
207 } else { 209 } else {
208 throw t; 210 throw t;
@@ -281,13 +283,17 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe @@ -281,13 +283,17 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
281 } 283 }
282 deleteEntityRelations(tenantId, deviceId); 284 deleteEntityRelations(tenantId, deviceId);
283 285
  286 + removeDeviceFromCache(tenantId, device.getName());
  287 +
  288 + deviceDao.removeById(tenantId, deviceId.getId());
  289 + }
  290 +
  291 + private void removeDeviceFromCache(TenantId tenantId, String name) {
284 List<Object> list = new ArrayList<>(); 292 List<Object> list = new ArrayList<>();
285 - list.add(device.getTenantId());  
286 - list.add(device.getName()); 293 + list.add(tenantId);
  294 + list.add(name);
287 Cache cache = cacheManager.getCache(DEVICE_CACHE); 295 Cache cache = cacheManager.getCache(DEVICE_CACHE);
288 cache.evict(list); 296 cache.evict(list);
289 -  
290 - deviceDao.removeById(tenantId, deviceId.getId());  
291 } 297 }
292 298
293 @Override 299 @Override
@@ -275,6 +275,7 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti @@ -275,6 +275,7 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
275 tenantIdAndEntityId.add(entityId); 275 tenantIdAndEntityId.add(entityId);
276 276
277 Cache cache = cacheManager.getCache(ENTITY_VIEW_CACHE); 277 Cache cache = cacheManager.getCache(ENTITY_VIEW_CACHE);
  278 + @SuppressWarnings("unchecked")
278 List<EntityView> fromCache = cache.get(tenantIdAndEntityId, List.class); 279 List<EntityView> fromCache = cache.get(tenantIdAndEntityId, List.class);
279 if (fromCache != null) { 280 if (fromCache != null) {
280 return Futures.immediateFuture(fromCache); 281 return Futures.immediateFuture(fromCache);
@@ -53,7 +53,7 @@ public class HybridClientRegistrationRepository implements ClientRegistrationRep @@ -53,7 +53,7 @@ public class HybridClientRegistrationRepository implements ClientRegistrationRep
53 .userNameAttributeName(localClientRegistration.getUserNameAttributeName()) 53 .userNameAttributeName(localClientRegistration.getUserNameAttributeName())
54 .jwkSetUri(localClientRegistration.getJwkSetUri()) 54 .jwkSetUri(localClientRegistration.getJwkSetUri())
55 .clientAuthenticationMethod(new ClientAuthenticationMethod(localClientRegistration.getClientAuthenticationMethod())) 55 .clientAuthenticationMethod(new ClientAuthenticationMethod(localClientRegistration.getClientAuthenticationMethod()))
56 - .redirectUriTemplate(defaultRedirectUriTemplate) 56 + .redirectUri(defaultRedirectUriTemplate)
57 .build(); 57 .build();
58 } 58 }
59 } 59 }
@@ -301,6 +301,7 @@ public class BaseRelationService implements RelationService { @@ -301,6 +301,7 @@ public class BaseRelationService implements RelationService {
301 fromAndTypeGroup.add(EntitySearchDirection.FROM.name()); 301 fromAndTypeGroup.add(EntitySearchDirection.FROM.name());
302 302
303 Cache cache = cacheManager.getCache(RELATIONS_CACHE); 303 Cache cache = cacheManager.getCache(RELATIONS_CACHE);
  304 + @SuppressWarnings("unchecked")
304 List<EntityRelation> fromCache = cache.get(fromAndTypeGroup, List.class); 305 List<EntityRelation> fromCache = cache.get(fromAndTypeGroup, List.class);
305 if (fromCache != null) { 306 if (fromCache != null) {
306 return Futures.immediateFuture(fromCache); 307 return Futures.immediateFuture(fromCache);
@@ -382,6 +383,7 @@ public class BaseRelationService implements RelationService { @@ -382,6 +383,7 @@ public class BaseRelationService implements RelationService {
382 toAndTypeGroup.add(EntitySearchDirection.TO.name()); 383 toAndTypeGroup.add(EntitySearchDirection.TO.name());
383 384
384 Cache cache = cacheManager.getCache(RELATIONS_CACHE); 385 Cache cache = cacheManager.getCache(RELATIONS_CACHE);
  386 + @SuppressWarnings("unchecked")
385 List<EntityRelation> fromCache = cache.get(toAndTypeGroup, List.class); 387 List<EntityRelation> fromCache = cache.get(toAndTypeGroup, List.class);
386 if (fromCache != null) { 388 if (fromCache != null) {
387 return Futures.immediateFuture(fromCache); 389 return Futures.immediateFuture(fromCache);
@@ -45,12 +45,12 @@ public class JpaDashboardInfoDao extends JpaAbstractSearchTextDao<DashboardInfoE @@ -45,12 +45,12 @@ public class JpaDashboardInfoDao extends JpaAbstractSearchTextDao<DashboardInfoE
45 private DashboardInfoRepository dashboardInfoRepository; 45 private DashboardInfoRepository dashboardInfoRepository;
46 46
47 @Override 47 @Override
48 - protected Class getEntityClass() { 48 + protected Class<DashboardInfoEntity> getEntityClass() {
49 return DashboardInfoEntity.class; 49 return DashboardInfoEntity.class;
50 } 50 }
51 51
52 @Override 52 @Override
53 - protected CrudRepository getCrudRepository() { 53 + protected CrudRepository<DashboardInfoEntity, UUID> getCrudRepository() {
54 return dashboardInfoRepository; 54 return dashboardInfoRepository;
55 } 55 }
56 56
@@ -15,7 +15,7 @@ @@ -15,7 +15,7 @@
15 */ 15 */
16 package org.thingsboard.server.dao.sql.device; 16 package org.thingsboard.server.dao.sql.device;
17 17
18 -import org.apache.commons.lang.StringUtils; 18 +import org.apache.commons.lang3.StringUtils;
19 import org.springframework.beans.factory.annotation.Autowired; 19 import org.springframework.beans.factory.annotation.Autowired;
20 import org.springframework.data.repository.CrudRepository; 20 import org.springframework.data.repository.CrudRepository;
21 import org.springframework.stereotype.Component; 21 import org.springframework.stereotype.Component;
@@ -49,7 +49,7 @@ public interface RelationRepository @@ -49,7 +49,7 @@ public interface RelationRepository
49 String fromType); 49 String fromType);
50 50
51 @Transactional 51 @Transactional
52 - RelationEntity save(RelationEntity entity); 52 + <S extends RelationEntity> S save(S entity);
53 53
54 @Transactional 54 @Transactional
55 void deleteById(RelationCompositeKey id); 55 void deleteById(RelationCompositeKey id);
@@ -39,12 +39,12 @@ public class JpaRuleChainDao extends JpaAbstractSearchTextDao<RuleChainEntity, R @@ -39,12 +39,12 @@ public class JpaRuleChainDao extends JpaAbstractSearchTextDao<RuleChainEntity, R
39 private RuleChainRepository ruleChainRepository; 39 private RuleChainRepository ruleChainRepository;
40 40
41 @Override 41 @Override
42 - protected Class getEntityClass() { 42 + protected Class<RuleChainEntity> getEntityClass() {
43 return RuleChainEntity.class; 43 return RuleChainEntity.class;
44 } 44 }
45 45
46 @Override 46 @Override
47 - protected CrudRepository getCrudRepository() { 47 + protected CrudRepository<RuleChainEntity, UUID> getCrudRepository() {
48 return ruleChainRepository; 48 return ruleChainRepository;
49 } 49 }
50 50
@@ -24,6 +24,8 @@ import org.thingsboard.server.dao.model.sql.RuleNodeEntity; @@ -24,6 +24,8 @@ import org.thingsboard.server.dao.model.sql.RuleNodeEntity;
24 import org.thingsboard.server.dao.rule.RuleNodeDao; 24 import org.thingsboard.server.dao.rule.RuleNodeDao;
25 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao; 25 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
26 26
  27 +import java.util.UUID;
  28 +
27 @Slf4j 29 @Slf4j
28 @Component 30 @Component
29 public class JpaRuleNodeDao extends JpaAbstractSearchTextDao<RuleNodeEntity, RuleNode> implements RuleNodeDao { 31 public class JpaRuleNodeDao extends JpaAbstractSearchTextDao<RuleNodeEntity, RuleNode> implements RuleNodeDao {
@@ -32,12 +34,12 @@ public class JpaRuleNodeDao extends JpaAbstractSearchTextDao<RuleNodeEntity, Rul @@ -32,12 +34,12 @@ public class JpaRuleNodeDao extends JpaAbstractSearchTextDao<RuleNodeEntity, Rul
32 private RuleNodeRepository ruleNodeRepository; 34 private RuleNodeRepository ruleNodeRepository;
33 35
34 @Override 36 @Override
35 - protected Class getEntityClass() { 37 + protected Class<RuleNodeEntity> getEntityClass() {
36 return RuleNodeEntity.class; 38 return RuleNodeEntity.class;
37 } 39 }
38 40
39 @Override 41 @Override
40 - protected CrudRepository getCrudRepository() { 42 + protected CrudRepository<RuleNodeEntity, UUID> getCrudRepository() {
41 return ruleNodeRepository; 43 return ruleNodeRepository;
42 } 44 }
43 45
@@ -39,12 +39,12 @@ public class JpaRuleNodeStateDao extends JpaAbstractDao<RuleNodeStateEntity, Rul @@ -39,12 +39,12 @@ public class JpaRuleNodeStateDao extends JpaAbstractDao<RuleNodeStateEntity, Rul
39 private RuleNodeStateRepository ruleNodeStateRepository; 39 private RuleNodeStateRepository ruleNodeStateRepository;
40 40
41 @Override 41 @Override
42 - protected Class getEntityClass() { 42 + protected Class<RuleNodeStateEntity> getEntityClass() {
43 return RuleNodeStateEntity.class; 43 return RuleNodeStateEntity.class;
44 } 44 }
45 45
46 @Override 46 @Override
47 - protected CrudRepository getCrudRepository() { 47 + protected CrudRepository<RuleNodeStateEntity, UUID> getCrudRepository() {
48 return ruleNodeStateRepository; 48 return ruleNodeStateRepository;
49 } 49 }
50 50
@@ -18,6 +18,8 @@ package org.thingsboard.server.dao.sql.rule; @@ -18,6 +18,8 @@ package org.thingsboard.server.dao.sql.rule;
18 import org.springframework.data.repository.CrudRepository; 18 import org.springframework.data.repository.CrudRepository;
19 import org.thingsboard.server.dao.model.sql.RuleNodeEntity; 19 import org.thingsboard.server.dao.model.sql.RuleNodeEntity;
20 20
21 -public interface RuleNodeRepository extends CrudRepository<RuleNodeEntity, String> { 21 +import java.util.UUID;
  22 +
  23 +public interface RuleNodeRepository extends CrudRepository<RuleNodeEntity, UUID> {
22 24
23 } 25 }
@@ -32,6 +32,7 @@ import lombok.extern.slf4j.Slf4j; @@ -32,6 +32,7 @@ import lombok.extern.slf4j.Slf4j;
32 import org.springframework.beans.factory.annotation.Autowired; 32 import org.springframework.beans.factory.annotation.Autowired;
33 import org.springframework.beans.factory.annotation.Value; 33 import org.springframework.beans.factory.annotation.Value;
34 import org.springframework.core.env.Environment; 34 import org.springframework.core.env.Environment;
  35 +import org.springframework.core.env.Profiles;
35 import org.springframework.stereotype.Component; 36 import org.springframework.stereotype.Component;
36 import org.thingsboard.server.common.data.id.EntityId; 37 import org.thingsboard.server.common.data.id.EntityId;
37 import org.thingsboard.server.common.data.id.TenantId; 38 import org.thingsboard.server.common.data.id.TenantId;
@@ -108,7 +109,7 @@ public class CassandraBaseTimeseriesDao extends AbstractCassandraBaseTimeseriesD @@ -108,7 +109,7 @@ public class CassandraBaseTimeseriesDao extends AbstractCassandraBaseTimeseriesD
108 private PreparedStatement deletePartitionStmt; 109 private PreparedStatement deletePartitionStmt;
109 110
110 private boolean isInstall() { 111 private boolean isInstall() {
111 - return environment.acceptsProfiles("install"); 112 + return environment.acceptsProfiles(Profiles.of("install"));
112 } 113 }
113 114
114 @PostConstruct 115 @PostConstruct
@@ -15,8 +15,8 @@ @@ -15,8 +15,8 @@
15 */ 15 */
16 package org.thingsboard.server.dao.user; 16 package org.thingsboard.server.dao.user;
17 17
  18 +import com.fasterxml.jackson.core.type.TypeReference;
18 import com.fasterxml.jackson.databind.JsonNode; 19 import com.fasterxml.jackson.databind.JsonNode;
19 -import com.fasterxml.jackson.databind.ObjectMapper;  
20 import com.fasterxml.jackson.databind.node.ObjectNode; 20 import com.fasterxml.jackson.databind.node.ObjectNode;
21 import com.google.common.util.concurrent.ListenableFuture; 21 import com.google.common.util.concurrent.ListenableFuture;
22 import lombok.extern.slf4j.Slf4j; 22 import lombok.extern.slf4j.Slf4j;
@@ -48,6 +48,7 @@ import org.thingsboard.server.dao.service.DataValidator; @@ -48,6 +48,7 @@ import org.thingsboard.server.dao.service.DataValidator;
48 import org.thingsboard.server.dao.service.PaginatedRemover; 48 import org.thingsboard.server.dao.service.PaginatedRemover;
49 import org.thingsboard.server.dao.tenant.TbTenantProfileCache; 49 import org.thingsboard.server.dao.tenant.TbTenantProfileCache;
50 import org.thingsboard.server.dao.tenant.TenantDao; 50 import org.thingsboard.server.dao.tenant.TenantDao;
  51 +import org.thingsboard.server.dao.util.mapping.JacksonUtil;
51 52
52 import java.util.HashMap; 53 import java.util.HashMap;
53 import java.util.Map; 54 import java.util.Map;
@@ -71,8 +72,6 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic @@ -71,8 +72,6 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic
71 72
72 private static final String USER_CREDENTIALS_ENABLED = "userCredentialsEnabled"; 73 private static final String USER_CREDENTIALS_ENABLED = "userCredentialsEnabled";
73 74
74 - private static final ObjectMapper objectMapper = new ObjectMapper();  
75 -  
76 @Value("${security.user_login_case_sensitive:true}") 75 @Value("${security.user_login_case_sensitive:true}")
77 private boolean userLoginCaseSensitive; 76 private boolean userLoginCaseSensitive;
78 77
@@ -279,7 +278,7 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic @@ -279,7 +278,7 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic
279 User user = findUserById(tenantId, userId); 278 User user = findUserById(tenantId, userId);
280 JsonNode additionalInfo = user.getAdditionalInfo(); 279 JsonNode additionalInfo = user.getAdditionalInfo();
281 if (!(additionalInfo instanceof ObjectNode)) { 280 if (!(additionalInfo instanceof ObjectNode)) {
282 - additionalInfo = objectMapper.createObjectNode(); 281 + additionalInfo = JacksonUtil.newObjectNode();
283 } 282 }
284 ((ObjectNode) additionalInfo).put(USER_CREDENTIALS_ENABLED, enabled); 283 ((ObjectNode) additionalInfo).put(USER_CREDENTIALS_ENABLED, enabled);
285 user.setAdditionalInfo(additionalInfo); 284 user.setAdditionalInfo(additionalInfo);
@@ -302,7 +301,7 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic @@ -302,7 +301,7 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic
302 private void setLastLoginTs(User user) { 301 private void setLastLoginTs(User user) {
303 JsonNode additionalInfo = user.getAdditionalInfo(); 302 JsonNode additionalInfo = user.getAdditionalInfo();
304 if (!(additionalInfo instanceof ObjectNode)) { 303 if (!(additionalInfo instanceof ObjectNode)) {
305 - additionalInfo = objectMapper.createObjectNode(); 304 + additionalInfo = JacksonUtil.newObjectNode();
306 } 305 }
307 ((ObjectNode) additionalInfo).put(LAST_LOGIN_TS, System.currentTimeMillis()); 306 ((ObjectNode) additionalInfo).put(LAST_LOGIN_TS, System.currentTimeMillis());
308 user.setAdditionalInfo(additionalInfo); 307 user.setAdditionalInfo(additionalInfo);
@@ -311,7 +310,7 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic @@ -311,7 +310,7 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic
311 private void resetFailedLoginAttempts(User user) { 310 private void resetFailedLoginAttempts(User user) {
312 JsonNode additionalInfo = user.getAdditionalInfo(); 311 JsonNode additionalInfo = user.getAdditionalInfo();
313 if (!(additionalInfo instanceof ObjectNode)) { 312 if (!(additionalInfo instanceof ObjectNode)) {
314 - additionalInfo = objectMapper.createObjectNode(); 313 + additionalInfo = JacksonUtil.newObjectNode();
315 } 314 }
316 ((ObjectNode) additionalInfo).put(FAILED_LOGIN_ATTEMPTS, 0); 315 ((ObjectNode) additionalInfo).put(FAILED_LOGIN_ATTEMPTS, 0);
317 user.setAdditionalInfo(additionalInfo); 316 user.setAdditionalInfo(additionalInfo);
@@ -329,7 +328,7 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic @@ -329,7 +328,7 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic
329 private int increaseFailedLoginAttempts(User user) { 328 private int increaseFailedLoginAttempts(User user) {
330 JsonNode additionalInfo = user.getAdditionalInfo(); 329 JsonNode additionalInfo = user.getAdditionalInfo();
331 if (!(additionalInfo instanceof ObjectNode)) { 330 if (!(additionalInfo instanceof ObjectNode)) {
332 - additionalInfo = objectMapper.createObjectNode(); 331 + additionalInfo = JacksonUtil.newObjectNode();
333 } 332 }
334 int failedLoginAttempts = 0; 333 int failedLoginAttempts = 0;
335 if (additionalInfo.has(FAILED_LOGIN_ATTEMPTS)) { 334 if (additionalInfo.has(FAILED_LOGIN_ATTEMPTS)) {
@@ -353,26 +352,30 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic @@ -353,26 +352,30 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic
353 private void updatePasswordHistory(User user, UserCredentials userCredentials) { 352 private void updatePasswordHistory(User user, UserCredentials userCredentials) {
354 JsonNode additionalInfo = user.getAdditionalInfo(); 353 JsonNode additionalInfo = user.getAdditionalInfo();
355 if (!(additionalInfo instanceof ObjectNode)) { 354 if (!(additionalInfo instanceof ObjectNode)) {
356 - additionalInfo = objectMapper.createObjectNode(); 355 + additionalInfo = JacksonUtil.newObjectNode();
357 } 356 }
  357 + Map<String, String> userPasswordHistoryMap = null;
  358 + JsonNode userPasswordHistoryJson;
358 if (additionalInfo.has(USER_PASSWORD_HISTORY)) { 359 if (additionalInfo.has(USER_PASSWORD_HISTORY)) {
359 - JsonNode userPasswordHistoryJson = additionalInfo.get(USER_PASSWORD_HISTORY);  
360 - Map<String, String> userPasswordHistoryMap = objectMapper.convertValue(userPasswordHistoryJson, Map.class); 360 + userPasswordHistoryJson = additionalInfo.get(USER_PASSWORD_HISTORY);
  361 + userPasswordHistoryMap = JacksonUtil.convertValue(userPasswordHistoryJson, new TypeReference<>(){});
  362 + }
  363 + if (userPasswordHistoryMap != null) {
361 userPasswordHistoryMap.put(Long.toString(System.currentTimeMillis()), userCredentials.getPassword()); 364 userPasswordHistoryMap.put(Long.toString(System.currentTimeMillis()), userCredentials.getPassword());
362 - userPasswordHistoryJson = objectMapper.valueToTree(userPasswordHistoryMap); 365 + userPasswordHistoryJson = JacksonUtil.valueToTree(userPasswordHistoryMap);
363 ((ObjectNode) additionalInfo).replace(USER_PASSWORD_HISTORY, userPasswordHistoryJson); 366 ((ObjectNode) additionalInfo).replace(USER_PASSWORD_HISTORY, userPasswordHistoryJson);
364 } else { 367 } else {
365 - Map<String, String> userPasswordHistoryMap = new HashMap<>(); 368 + userPasswordHistoryMap = new HashMap<>();
366 userPasswordHistoryMap.put(Long.toString(System.currentTimeMillis()), userCredentials.getPassword()); 369 userPasswordHistoryMap.put(Long.toString(System.currentTimeMillis()), userCredentials.getPassword());
367 - JsonNode userPasswordHistoryJson = objectMapper.valueToTree(userPasswordHistoryMap); 370 + userPasswordHistoryJson = JacksonUtil.valueToTree(userPasswordHistoryMap);
368 ((ObjectNode) additionalInfo).set(USER_PASSWORD_HISTORY, userPasswordHistoryJson); 371 ((ObjectNode) additionalInfo).set(USER_PASSWORD_HISTORY, userPasswordHistoryJson);
369 } 372 }
370 user.setAdditionalInfo(additionalInfo); 373 user.setAdditionalInfo(additionalInfo);
371 saveUser(user); 374 saveUser(user);
372 } 375 }
373 376
374 - private DataValidator<User> userValidator =  
375 - new DataValidator<User>() { 377 + private final DataValidator<User> userValidator =
  378 + new DataValidator<>() {
376 @Override 379 @Override
377 protected void validateCreate(TenantId tenantId, User user) { 380 protected void validateCreate(TenantId tenantId, User user) {
378 if (!user.getTenantId().getId().equals(ModelConstants.NULL_UUID)) { 381 if (!user.getTenantId().getId().equals(ModelConstants.NULL_UUID)) {
@@ -452,8 +455,8 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic @@ -452,8 +455,8 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic
452 } 455 }
453 }; 456 };
454 457
455 - private DataValidator<UserCredentials> userCredentialsValidator =  
456 - new DataValidator<UserCredentials>() { 458 + private final DataValidator<UserCredentials> userCredentialsValidator =
  459 + new DataValidator<>() {
457 460
458 @Override 461 @Override
459 protected void validateCreate(TenantId tenantId, UserCredentials userCredentials) { 462 protected void validateCreate(TenantId tenantId, UserCredentials userCredentials) {
@@ -484,7 +487,7 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic @@ -484,7 +487,7 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic
484 } 487 }
485 }; 488 };
486 489
487 - private PaginatedRemover<TenantId, User> tenantAdminsRemover = new PaginatedRemover<TenantId, User>() { 490 + private final PaginatedRemover<TenantId, User> tenantAdminsRemover = new PaginatedRemover<>() {
488 @Override 491 @Override
489 protected PageData<User> findEntities(TenantId tenantId, TenantId id, PageLink pageLink) { 492 protected PageData<User> findEntities(TenantId tenantId, TenantId id, PageLink pageLink) {
490 return userDao.findTenantAdmins(id.getId(), pageLink); 493 return userDao.findTenantAdmins(id.getId(), pageLink);
@@ -496,7 +499,7 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic @@ -496,7 +499,7 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic
496 } 499 }
497 }; 500 };
498 501
499 - private PaginatedRemover<CustomerId, User> customerUsersRemover = new PaginatedRemover<CustomerId, User>() { 502 + private final PaginatedRemover<CustomerId, User> customerUsersRemover = new PaginatedRemover<>() {
500 @Override 503 @Override
501 protected PageData<User> findEntities(TenantId tenantId, CustomerId id, PageLink pageLink) { 504 protected PageData<User> findEntities(TenantId tenantId, CustomerId id, PageLink pageLink) {
502 return userDao.findCustomerUsers(tenantId.getId(), id.getId(), pageLink); 505 return userDao.findCustomerUsers(tenantId.getId(), id.getId(), pageLink);