Commit 3612fa7ab90c0d6dfffc320a12571183b11b85cd

Authored by xp.Huang
2 parents e7607b4c 39b75022

Merge branch '20230425' into 'master_dev'

fix(DEFECT-1234): 给网关子设备下发RPC指令

See merge request yunteng/thingskit!183
Showing 20 changed files with 320 additions and 143 deletions
@@ -58,6 +58,7 @@ import org.thingsboard.server.common.data.rpc.RpcStatus; @@ -58,6 +58,7 @@ import org.thingsboard.server.common.data.rpc.RpcStatus;
58 import org.thingsboard.server.common.data.rpc.ToDeviceRpcRequestBody; 58 import org.thingsboard.server.common.data.rpc.ToDeviceRpcRequestBody;
59 import org.thingsboard.server.common.data.security.DeviceCredentials; 59 import org.thingsboard.server.common.data.security.DeviceCredentials;
60 import org.thingsboard.server.common.data.security.DeviceCredentialsType; 60 import org.thingsboard.server.common.data.security.DeviceCredentialsType;
  61 +import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants;
61 import org.thingsboard.server.common.data.yunteng.constant.ModelConstants; 62 import org.thingsboard.server.common.data.yunteng.constant.ModelConstants;
62 import org.thingsboard.server.common.data.yunteng.enums.CmdTypeEnum; 63 import org.thingsboard.server.common.data.yunteng.enums.CmdTypeEnum;
63 import org.thingsboard.server.common.msg.TbActorMsg; 64 import org.thingsboard.server.common.msg.TbActorMsg;
@@ -242,20 +243,26 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { @@ -242,20 +243,26 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
242 } 243 }
243 244
244 private Rpc createRpc(ToDeviceRpcRequest request, RpcStatus status) { 245 private Rpc createRpc(ToDeviceRpcRequest request, RpcStatus status) {
  246 + //Thingskit function
  247 + JsonNode old = JacksonUtil.toJsonNode(request.getAdditionalInfo());
  248 + ObjectNode additional = (old == null || old.isEmpty()) ?mapper.createObjectNode():(ObjectNode)old;
  249 + if(!additional.has(ModelConstants.TablePropertyMapping.COMMAND_TYPE)){
  250 + additional.put(ModelConstants.TablePropertyMapping.COMMAND_TYPE, CmdTypeEnum.DIY.ordinal());
  251 + }
  252 + DeviceId saveDeviceId = deviceId;
  253 + if(additional.has(FastIotConstants.Rpc.TARGET_ID)){
  254 + saveDeviceId = new DeviceId(UUID.fromString(additional.get(FastIotConstants.Rpc.TARGET_ID).asText()));
  255 + }
  256 +
245 Rpc rpc = new Rpc(new RpcId(request.getId())); 257 Rpc rpc = new Rpc(new RpcId(request.getId()));
246 rpc.setCreatedTime(System.currentTimeMillis()); 258 rpc.setCreatedTime(System.currentTimeMillis());
247 rpc.setTenantId(tenantId); 259 rpc.setTenantId(tenantId);
248 - rpc.setDeviceId(deviceId); 260 + rpc.setDeviceId(saveDeviceId);
249 rpc.setExpirationTime(request.getExpirationTime()); 261 rpc.setExpirationTime(request.getExpirationTime());
250 rpc.setRequest(JacksonUtil.valueToTree(request)); 262 rpc.setRequest(JacksonUtil.valueToTree(request));
251 rpc.setStatus(status); 263 rpc.setStatus(status);
252 rpc.setAdditionalInfo(JacksonUtil.toJsonNode(request.getAdditionalInfo())); 264 rpc.setAdditionalInfo(JacksonUtil.toJsonNode(request.getAdditionalInfo()));
253 - //Thingskit function  
254 - JsonNode old = JacksonUtil.toJsonNode(request.getAdditionalInfo());  
255 - ObjectNode additional = (old == null || old.isEmpty()) ?mapper.createObjectNode():(ObjectNode)old;  
256 - if(!additional.has(ModelConstants.TablePropertyMapping.COMMAND_TYPE)){  
257 - additional.put(ModelConstants.TablePropertyMapping.COMMAND_TYPE, CmdTypeEnum.DIY.ordinal());  
258 - } 265 +
259 rpc.setAdditionalInfo(additional); 266 rpc.setAdditionalInfo(additional);
260 267
261 return systemContext.getTbRpcService().save(tenantId, rpc); 268 return systemContext.getTbRpcService().save(tenantId, rpc);
@@ -16,7 +16,9 @@ @@ -16,7 +16,9 @@
16 package org.thingsboard.server.controller; 16 package org.thingsboard.server.controller;
17 17
18 import com.fasterxml.jackson.databind.JsonNode; 18 import com.fasterxml.jackson.databind.JsonNode;
  19 +import com.fasterxml.jackson.databind.node.ObjectNode;
19 import com.google.common.util.concurrent.FutureCallback; 20 import com.google.common.util.concurrent.FutureCallback;
  21 +import com.google.gson.JsonObject;
20 import lombok.extern.slf4j.Slf4j; 22 import lombok.extern.slf4j.Slf4j;
21 import org.springframework.beans.factory.annotation.Autowired; 23 import org.springframework.beans.factory.annotation.Autowired;
22 import org.springframework.beans.factory.annotation.Value; 24 import org.springframework.beans.factory.annotation.Value;
@@ -35,8 +37,14 @@ import org.thingsboard.server.common.data.id.TenantId; @@ -35,8 +37,14 @@ import org.thingsboard.server.common.data.id.TenantId;
35 import org.thingsboard.server.common.data.id.UUIDBased; 37 import org.thingsboard.server.common.data.id.UUIDBased;
36 import org.thingsboard.server.common.data.rpc.RpcError; 38 import org.thingsboard.server.common.data.rpc.RpcError;
37 import org.thingsboard.server.common.data.rpc.ToDeviceRpcRequestBody; 39 import org.thingsboard.server.common.data.rpc.ToDeviceRpcRequestBody;
  40 +import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants;
  41 +import org.thingsboard.server.common.data.yunteng.constant.ModelConstants;
  42 +import org.thingsboard.server.common.data.yunteng.dto.DeviceDTO;
  43 +import org.thingsboard.server.common.data.yunteng.enums.CmdTypeEnum;
  44 +import org.thingsboard.server.common.data.yunteng.enums.DeviceTypeEnum;
38 import org.thingsboard.server.common.msg.rpc.FromDeviceRpcResponse; 45 import org.thingsboard.server.common.msg.rpc.FromDeviceRpcResponse;
39 import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest; 46 import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest;
  47 +import org.thingsboard.server.dao.yunteng.service.TkDeviceService;
40 import org.thingsboard.server.queue.util.TbCoreComponent; 48 import org.thingsboard.server.queue.util.TbCoreComponent;
41 import org.thingsboard.server.service.rpc.LocalRequestMetaData; 49 import org.thingsboard.server.service.rpc.LocalRequestMetaData;
42 import org.thingsboard.server.service.rpc.TbCoreDeviceRpcService; 50 import org.thingsboard.server.service.rpc.TbCoreDeviceRpcService;
@@ -62,6 +70,10 @@ public abstract class AbstractRpcController extends BaseController { @@ -62,6 +70,10 @@ public abstract class AbstractRpcController extends BaseController {
62 @Autowired 70 @Autowired
63 protected AccessValidator accessValidator; 71 protected AccessValidator accessValidator;
64 72
  73 +
  74 + @Autowired
  75 + protected TkDeviceService tkDeviceService;
  76 +
65 @Value("${server.rest.server_side_rpc.min_timeout:5000}") 77 @Value("${server.rest.server_side_rpc.min_timeout:5000}")
66 protected long minTimeout; 78 protected long minTimeout;
67 79
@@ -79,14 +91,28 @@ public abstract class AbstractRpcController extends BaseController { @@ -79,14 +91,28 @@ public abstract class AbstractRpcController extends BaseController {
79 long expTime = rpcRequestBody.has(DataConstants.EXPIRATION_TIME) ? rpcRequestBody.get(DataConstants.EXPIRATION_TIME).asLong() : System.currentTimeMillis() + Math.max(minTimeout, timeout); 91 long expTime = rpcRequestBody.has(DataConstants.EXPIRATION_TIME) ? rpcRequestBody.get(DataConstants.EXPIRATION_TIME).asLong() : System.currentTimeMillis() + Math.max(minTimeout, timeout);
80 UUID rpcRequestUUID = rpcRequestBody.has("requestUUID") ? UUID.fromString(rpcRequestBody.get("requestUUID").asText()) : UUID.randomUUID(); 92 UUID rpcRequestUUID = rpcRequestBody.has("requestUUID") ? UUID.fromString(rpcRequestBody.get("requestUUID").asText()) : UUID.randomUUID();
81 boolean persisted = rpcRequestBody.has(DataConstants.PERSISTENT) && rpcRequestBody.get(DataConstants.PERSISTENT).asBoolean(); 93 boolean persisted = rpcRequestBody.has(DataConstants.PERSISTENT) && rpcRequestBody.get(DataConstants.PERSISTENT).asBoolean();
82 - String additionalInfo = JacksonUtil.toString(rpcRequestBody.get(DataConstants.ADDITIONAL_INFO)); 94 +
  95 +
  96 + //Thingskit function
  97 + DeviceDTO tkDevice = tkDeviceService.findDeviceInfoByTbDeviceId(currentUser.getCurrentTenantId(), deviceId.getId().toString());
  98 + ObjectNode additional = (ObjectNode) rpcRequestBody.get(DataConstants.ADDITIONAL_INFO);
  99 + if(additional == null){
  100 + additional = JacksonUtil.newObjectNode();
  101 + }
  102 + if(!additional.has(FastIotConstants.Rpc.TARGET_ID)){
  103 + additional.put(FastIotConstants.Rpc.TARGET_ID, deviceId.getId().toString());
  104 + }
  105 + DeviceId realDevice = DeviceTypeEnum.SENSOR == tkDevice.getDeviceType()?new DeviceId(UUID.fromString(tkDevice.getGatewayId())):deviceId;
  106 + String additionalInfo = JacksonUtil.toString(additional);
  107 +
83 Integer retries = rpcRequestBody.has(DataConstants.RETRIES) ? rpcRequestBody.get(DataConstants.RETRIES).asInt() : null; 108 Integer retries = rpcRequestBody.has(DataConstants.RETRIES) ? rpcRequestBody.get(DataConstants.RETRIES).asInt() : null;
84 - accessValidator.validate(currentUser, Operation.RPC_CALL, deviceId, new HttpValidationCallback(response, new FutureCallback<>() { 109 + accessValidator.validate(currentUser, Operation.RPC_CALL, realDevice, new HttpValidationCallback(response, new FutureCallback<>() {
85 @Override 110 @Override
86 public void onSuccess(@Nullable DeferredResult<ResponseEntity> result) { 111 public void onSuccess(@Nullable DeferredResult<ResponseEntity> result) {
  112 +
87 ToDeviceRpcRequest rpcRequest = new ToDeviceRpcRequest(rpcRequestUUID, 113 ToDeviceRpcRequest rpcRequest = new ToDeviceRpcRequest(rpcRequestUUID,
88 tenantId, 114 tenantId,
89 - deviceId, 115 + realDevice,
90 oneWay, 116 oneWay,
91 expTime, 117 expTime,
92 body, 118 body,
@@ -95,16 +95,11 @@ public class TkDeviceScriptController extends BaseController { @@ -95,16 +95,11 @@ public class TkDeviceScriptController extends BaseController {
95 return ResponseEntity.ok(false); 95 return ResponseEntity.ok(false);
96 } 96 }
97 97
98 - /**脚本引擎启用/禁用时,刷新规则引擎中缓存的脚本ID对应的脚本内容,禁用时为默认脚本*/  
99 -// List<DeviceProfileDTO> usedProfiles = ytDeviceProfileService.findDeviceProfile(tenantId, id,null);  
100 -// for (DeviceProfileDTO profile : usedProfiles) {  
101 -// DeviceProfile tbDeviceProfile =  
102 -// buildTbDeviceProfileFromDeviceProfileDTO(  
103 -// profile, id,scriptDTO.getScriptType());  
104 -// updateTbDeviceProfile(tbDeviceProfile);  
105 -// }  
106 - 98 + /**脚本引擎启用/禁用时,刷新设备接入服务中的脚本,禁用时使用默认脚本*/
107 scriptService.updateScriptStatus(tenantId, id, status); 99 scriptService.updateScriptStatus(tenantId, id, status);
  100 + scriptService.getDeviceScript(tenantId, id).ifPresent(i->{
  101 + tbClusterService.onJsScriptChange(i,null);
  102 + });
108 return ResponseEntity.ok(true); 103 return ResponseEntity.ok(true);
109 } 104 }
110 105
@@ -27,6 +27,8 @@ import org.thingsboard.server.cluster.TbClusterService; @@ -27,6 +27,8 @@ import org.thingsboard.server.cluster.TbClusterService;
27 import org.thingsboard.server.common.data.EdgeUtils; 27 import org.thingsboard.server.common.data.EdgeUtils;
28 import org.thingsboard.server.common.data.edge.EdgeEventActionType; 28 import org.thingsboard.server.common.data.edge.EdgeEventActionType;
29 import org.thingsboard.server.common.data.edge.EdgeEventType; 29 import org.thingsboard.server.common.data.edge.EdgeEventType;
  30 +import org.thingsboard.server.common.data.yunteng.dto.TkDeviceScriptDTO;
  31 +import org.thingsboard.server.common.data.yunteng.id.ScriptId;
30 import org.thingsboard.server.common.msg.ToDeviceActorNotificationMsg; 32 import org.thingsboard.server.common.msg.ToDeviceActorNotificationMsg;
31 import org.thingsboard.server.common.data.ApiUsageState; 33 import org.thingsboard.server.common.data.ApiUsageState;
32 import org.thingsboard.server.common.data.Device; 34 import org.thingsboard.server.common.data.Device;
@@ -473,4 +475,12 @@ public class DefaultTbClusterService implements TbClusterService { @@ -473,4 +475,12 @@ public class DefaultTbClusterService implements TbClusterService {
473 break; 475 break;
474 } 476 }
475 } 477 }
  478 +
  479 +
  480 + //Thingskit function
  481 + @Override
  482 + public void onJsScriptChange(TkDeviceScriptDTO script, TbQueueCallback callback) {
  483 + broadcastEntityChangeToTransport(
  484 + new TenantId(UUID.fromString(script.getTenantId())), new ScriptId(UUID.fromString(script.getId())), script, callback);
  485 + }
476 } 486 }
@@ -679,30 +679,22 @@ public class DefaultTransportApiService implements TransportApiService { @@ -679,30 +679,22 @@ public class DefaultTransportApiService implements TransportApiService {
679 679
680 //Thingskit function 680 //Thingskit function
681 private ListenableFuture<TransportApiResponseMsg> handle(TransportProtos.ScriptProto requestMsg) { 681 private ListenableFuture<TransportApiResponseMsg> handle(TransportProtos.ScriptProto requestMsg) {
682 -  
683 - int type = requestMsg.getFunctionType();  
684 - UUID scriptId = getUUID(requestMsg.getScriptIdLSB(),requestMsg.getScriptIdMSB());  
685 -  
686 - List<TkDeviceScriptDTO> allScriptes = scriptService.getScriptes(Arrays.stream(TkScriptFunctionType.values()).filter(f->f.ordinal()==type).findFirst().get(),null,null,scriptId); 682 + List<TkDeviceScriptDTO> allScriptes = scriptService.getScriptes();
687 TransportApiResponseMsg.Builder responseBuilder = TransportApiResponseMsg.newBuilder(); 683 TransportApiResponseMsg.Builder responseBuilder = TransportApiResponseMsg.newBuilder();
688 - allScriptes.forEach(item->{  
689 - UUID tenantId = UUID.fromString(item.getTenantId());  
690 - UUID id = UUID.fromString(item.getId());  
691 - responseBuilder.addScriptsResponseMsg(TransportProtos.ScriptProto.newBuilder()  
692 - .setConvertJs(item.getConvertJs())  
693 - .setTenantIdLSB(tenantId.getLeastSignificantBits())  
694 - .setTenantIdMSB(tenantId.getMostSignificantBits())  
695 - .setScriptIdLSB(id.getLeastSignificantBits())  
696 - .setScriptIdMSB(id.getMostSignificantBits())  
697 - .setFunctionType(item.getScriptType().ordinal())  
698 - ); 684 + allScriptes.forEach(
  685 + item -> {
  686 + UUID tenantId = UUID.fromString(item.getTenantId());
  687 + UUID id = UUID.fromString(item.getId());
  688 + responseBuilder.addScriptsResponseMsg(
  689 + TransportProtos.ScriptProto.newBuilder()
  690 + .setConvertJs(item.getConvertJs())
  691 + .setTenantIdLSB(tenantId.getLeastSignificantBits())
  692 + .setTenantIdMSB(tenantId.getMostSignificantBits())
  693 + .setScriptIdLSB(id.getLeastSignificantBits())
  694 + .setScriptIdMSB(id.getMostSignificantBits())
  695 + .setFunctionType(item.getScriptType().name())
  696 + .setStatus(item.getStatus()));
699 }); 697 });
700 return Futures.immediateFuture(responseBuilder.build()); 698 return Futures.immediateFuture(responseBuilder.build());
701 } 699 }
702 - private UUID getUUID(long lsb,long msb){  
703 - if(lsb==0 && msb==0){  
704 - return null;  
705 - }  
706 - return new UUID(msb,lsb);  
707 - }  
708 } 700 }
@@ -17,6 +17,7 @@ package org.thingsboard.server.cluster; @@ -17,6 +17,7 @@ package org.thingsboard.server.cluster;
17 17
18 import org.thingsboard.server.common.data.edge.EdgeEventActionType; 18 import org.thingsboard.server.common.data.edge.EdgeEventActionType;
19 import org.thingsboard.server.common.data.edge.EdgeEventType; 19 import org.thingsboard.server.common.data.edge.EdgeEventType;
  20 +import org.thingsboard.server.common.data.yunteng.dto.TkDeviceScriptDTO;
20 import org.thingsboard.server.common.msg.ToDeviceActorNotificationMsg; 21 import org.thingsboard.server.common.msg.ToDeviceActorNotificationMsg;
21 import org.thingsboard.server.common.data.ApiUsageState; 22 import org.thingsboard.server.common.data.ApiUsageState;
22 import org.thingsboard.server.common.data.Device; 23 import org.thingsboard.server.common.data.Device;
@@ -86,4 +87,8 @@ public interface TbClusterService { @@ -86,4 +87,8 @@ public interface TbClusterService {
86 void onEdgeEventUpdate(TenantId tenantId, EdgeId edgeId); 87 void onEdgeEventUpdate(TenantId tenantId, EdgeId edgeId);
87 88
88 void sendNotificationMsgToEdgeService(TenantId tenantId, EdgeId edgeId, EntityId entityId, String body, EdgeEventType type, EdgeEventActionType action); 89 void sendNotificationMsgToEdgeService(TenantId tenantId, EdgeId edgeId, EntityId entityId, String body, EdgeEventType type, EdgeEventActionType action);
  90 +
  91 +
  92 + //Thingskit function
  93 + void onJsScriptChange(TkDeviceScriptDTO script, TbQueueCallback callback);
89 } 94 }
@@ -789,8 +789,9 @@ message ScriptProto{ @@ -789,8 +789,9 @@ message ScriptProto{
789 int64 tenantIdLSB = 2; 789 int64 tenantIdLSB = 2;
790 // int64 projectIdMSB = 3; 790 // int64 projectIdMSB = 3;
791 // int64 projectIdLSB = 4; 791 // int64 projectIdLSB = 4;
792 - int64 scriptIdMSB = 5;  
793 - int64 scriptIdLSB = 6;  
794 - int32 functionType = 7;  
795 - string convertJs = 8; 792 + int64 scriptIdMSB = 3;
  793 + int64 scriptIdLSB = 4;
  794 + string functionType = 5;
  795 + string convertJs = 6;
  796 + int32 status = 7;
796 } 797 }
@@ -21,5 +21,5 @@ package org.thingsboard.server.common.data; @@ -21,5 +21,5 @@ package org.thingsboard.server.common.data;
21 public enum EntityType { 21 public enum EntityType {
22 TENANT, CUSTOMER, USER, DASHBOARD, ASSET, DEVICE, ALARM, RULE_CHAIN, RULE_NODE, ENTITY_VIEW, WIDGETS_BUNDLE, WIDGET_TYPE, TENANT_PROFILE, DEVICE_PROFILE, API_USAGE_STATE, TB_RESOURCE, OTA_PACKAGE, EDGE, RPC 22 TENANT, CUSTOMER, USER, DASHBOARD, ASSET, DEVICE, ALARM, RULE_CHAIN, RULE_NODE, ENTITY_VIEW, WIDGETS_BUNDLE, WIDGET_TYPE, TENANT_PROFILE, DEVICE_PROFILE, API_USAGE_STATE, TB_RESOURCE, OTA_PACKAGE, EDGE, RPC
23 //Thingskit function 23 //Thingskit function
24 - , RUNNING_EXCEPTION,SCENE_ACT; 24 + , RUNNING_EXCEPTION,SCENE_ACT,JS_SCRIPT;
25 } 25 }
@@ -167,5 +167,7 @@ public interface FastIotConstants { @@ -167,5 +167,7 @@ public interface FastIotConstants {
167 public static String METHOD_NAME = "method"; 167 public static String METHOD_NAME = "method";
168 /**RPC参数*/ 168 /**RPC参数*/
169 public static String PARAMS_NAME = "params"; 169 public static String PARAMS_NAME = "params";
  170 + /**实控设备*/
  171 + public static String TARGET_ID = "target";
170 } 172 }
171 } 173 }
  1 +/**
  2 + * Copyright © 2016-2022 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.data.yunteng.id;
  17 +
  18 +import com.fasterxml.jackson.annotation.JsonCreator;
  19 +import com.fasterxml.jackson.annotation.JsonProperty;
  20 +import io.swagger.annotations.ApiModel;
  21 +import io.swagger.annotations.ApiModelProperty;
  22 +import java.util.UUID;
  23 +import org.thingsboard.server.common.data.EntityType;
  24 +import org.thingsboard.server.common.data.id.EntityId;
  25 +import org.thingsboard.server.common.data.id.UUIDBased;
  26 +
  27 +@ApiModel
  28 +public class ScriptId extends UUIDBased implements EntityId {
  29 +
  30 + private static final long serialVersionUID = 1L;
  31 +
  32 + @JsonCreator
  33 + public ScriptId(@JsonProperty("id") UUID id) {
  34 + super(id);
  35 + }
  36 +
  37 + public static ScriptId fromString(String sceneId) {
  38 + return new ScriptId(UUID.fromString(sceneId));
  39 + }
  40 +
  41 + @Override
  42 + @ApiModelProperty(position = 2, required = true, value = "string", example = "JS_SCRIPT", allowableValues = "JS_SCRIPT")
  43 + public EntityType getEntityType() {
  44 + return EntityType.JS_SCRIPT;
  45 + }
  46 +}
@@ -22,13 +22,25 @@ import lombok.extern.slf4j.Slf4j; @@ -22,13 +22,25 @@ import lombok.extern.slf4j.Slf4j;
22 import org.springframework.beans.factory.annotation.Autowired; 22 import org.springframework.beans.factory.annotation.Autowired;
23 import org.springframework.beans.factory.annotation.Value; 23 import org.springframework.beans.factory.annotation.Value;
24 import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; 24 import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
  25 +import org.springframework.boot.context.event.ApplicationReadyEvent;
  26 +import org.springframework.context.event.EventListener;
  27 +import org.springframework.core.annotation.Order;
25 import org.springframework.stereotype.Component; 28 import org.springframework.stereotype.Component;
  29 +import org.thingsboard.common.util.ThingsBoardThreadFactory;
  30 +import org.thingsboard.server.common.data.yunteng.enums.StatusEnum;
  31 +import org.thingsboard.server.common.data.yunteng.enums.TkScriptFunctionType;
26 import org.thingsboard.server.common.transport.TransportContext; 32 import org.thingsboard.server.common.transport.TransportContext;
  33 +import org.thingsboard.server.gen.transport.TransportProtos;
27 import org.thingsboard.server.transport.tcp.adaptors.JsonTcpAdaptor; 34 import org.thingsboard.server.transport.tcp.adaptors.JsonTcpAdaptor;
28 import org.thingsboard.server.transport.tcp.script.TkScriptInvokeService; 35 import org.thingsboard.server.transport.tcp.script.TkScriptInvokeService;
29 36
30 import javax.annotation.PostConstruct; 37 import javax.annotation.PostConstruct;
31 import java.net.InetSocketAddress; 38 import java.net.InetSocketAddress;
  39 +import java.util.List;
  40 +import java.util.UUID;
  41 +import java.util.concurrent.Executors;
  42 +import java.util.concurrent.ScheduledExecutorService;
  43 +import java.util.concurrent.TimeUnit;
32 import java.util.concurrent.atomic.AtomicInteger; 44 import java.util.concurrent.atomic.AtomicInteger;
33 45
34 /** 46 /**
@@ -77,11 +89,14 @@ public class TcpTransportContext extends TransportContext { @@ -77,11 +89,14 @@ public class TcpTransportContext extends TransportContext {
77 private boolean proxyEnabled; 89 private boolean proxyEnabled;
78 90
79 private final AtomicInteger connectionsCounter = new AtomicInteger(); 91 private final AtomicInteger connectionsCounter = new AtomicInteger();
80 - 92 + protected ScheduledExecutorService schedulerExecutor;
  93 + @Getter
  94 + private boolean ready=false;
81 @PostConstruct 95 @PostConstruct
82 public void init() { 96 public void init() {
83 super.init(); 97 super.init();
84 transportService.createGaugeStats("openConnections", connectionsCounter); 98 transportService.createGaugeStats("openConnections", connectionsCounter);
  99 + schedulerExecutor = Executors.newSingleThreadScheduledExecutor(ThingsBoardThreadFactory.forName("tcp-init"));
85 } 100 }
86 101
87 public void channelRegistered() { 102 public void channelRegistered() {
@@ -104,4 +119,19 @@ public class TcpTransportContext extends TransportContext { @@ -104,4 +119,19 @@ public class TcpTransportContext extends TransportContext {
104 rateLimitService.onAuthFailure(address); 119 rateLimitService.onAuthFailure(address);
105 } 120 }
106 121
  122 +
  123 + @EventListener(ApplicationReadyEvent.class)
  124 + @Order(value = 2)
  125 + public void onApplicationEvent(ApplicationReadyEvent event) {
  126 + List<TransportProtos.ScriptProto> all =transportService.getScripts(TransportProtos.ScriptProto.newBuilder().setStatus(StatusEnum.ENABLE.getIndex()).build());
  127 + if(all ==null){
  128 + return;
  129 + }
  130 + all.forEach(i->{
  131 + UUID scriptId = new UUID(i.getScriptIdMSB(), i.getScriptIdLSB());
  132 + TkScriptFunctionType scriptType = TkScriptFunctionType.valueOf(i.getFunctionType());
  133 + jsEngine.cacheScript(scriptId, scriptType, i.getConvertJs(), StatusEnum.ENABLE.getIndex());
  134 + });
  135 + schedulerExecutor.schedule(()->ready=true,timeout, TimeUnit.MILLISECONDS);
  136 + }
107 } 137 }
@@ -15,6 +15,13 @@ @@ -15,6 +15,13 @@
15 */ 15 */
16 package org.thingsboard.server.transport.tcp; 16 package org.thingsboard.server.transport.tcp;
17 17
  18 +import static io.netty.handler.codec.mqtt.MqttConnectReturnCode.CONNECTION_ACCEPTED;
  19 +import static io.netty.handler.codec.mqtt.MqttMessageType.PUBACK;
  20 +import static io.netty.handler.codec.mqtt.MqttMessageType.SUBACK;
  21 +import static io.netty.handler.codec.mqtt.MqttQoS.AT_MOST_ONCE;
  22 +import static org.thingsboard.server.common.transport.service.DefaultTransportService.SESSION_EVENT_MSG_CLOSED;
  23 +import static org.thingsboard.server.common.transport.service.DefaultTransportService.SESSION_EVENT_MSG_OPEN;
  24 +
18 import com.fasterxml.jackson.databind.JsonNode; 25 import com.fasterxml.jackson.databind.JsonNode;
19 import com.google.common.util.concurrent.FutureCallback; 26 import com.google.common.util.concurrent.FutureCallback;
20 import com.google.common.util.concurrent.Futures; 27 import com.google.common.util.concurrent.Futures;
@@ -30,18 +37,28 @@ import io.netty.handler.ssl.SslHandler; @@ -30,18 +37,28 @@ import io.netty.handler.ssl.SslHandler;
30 import io.netty.util.ReferenceCountUtil; 37 import io.netty.util.ReferenceCountUtil;
31 import io.netty.util.concurrent.Future; 38 import io.netty.util.concurrent.Future;
32 import io.netty.util.concurrent.GenericFutureListener; 39 import io.netty.util.concurrent.GenericFutureListener;
  40 +import java.io.IOException;
  41 +import java.net.InetSocketAddress;
  42 +import java.util.List;
  43 +import java.util.Map;
  44 +import java.util.Optional;
  45 +import java.util.UUID;
  46 +import java.util.concurrent.atomic.AtomicInteger;
  47 +import java.util.regex.Pattern;
33 import lombok.extern.slf4j.Slf4j; 48 import lombok.extern.slf4j.Slf4j;
34 import org.apache.commons.lang3.StringUtils; 49 import org.apache.commons.lang3.StringUtils;
35 import org.checkerframework.checker.nullness.qual.Nullable; 50 import org.checkerframework.checker.nullness.qual.Nullable;
  51 +import org.springframework.boot.context.event.ApplicationReadyEvent;
  52 +import org.springframework.context.event.EventListener;
36 import org.thingsboard.common.util.JacksonUtil; 53 import org.thingsboard.common.util.JacksonUtil;
37 import org.thingsboard.server.common.data.DataConstants; 54 import org.thingsboard.server.common.data.DataConstants;
38 import org.thingsboard.server.common.data.Device; 55 import org.thingsboard.server.common.data.Device;
39 import org.thingsboard.server.common.data.DeviceProfile; 56 import org.thingsboard.server.common.data.DeviceProfile;
40 import org.thingsboard.server.common.data.DeviceTransportType; 57 import org.thingsboard.server.common.data.DeviceTransportType;
41 -import org.thingsboard.server.common.data.device.profile.MqttTopics;  
42 import org.thingsboard.server.common.data.device.profile.TkTcpDeviceProfileTransportConfiguration; 58 import org.thingsboard.server.common.data.device.profile.TkTcpDeviceProfileTransportConfiguration;
43 import org.thingsboard.server.common.data.id.DeviceId; 59 import org.thingsboard.server.common.data.id.DeviceId;
44 import org.thingsboard.server.common.data.rpc.RpcStatus; 60 import org.thingsboard.server.common.data.rpc.RpcStatus;
  61 +import org.thingsboard.server.common.data.yunteng.enums.StatusEnum;
45 import org.thingsboard.server.common.data.yunteng.enums.TkScriptFunctionType; 62 import org.thingsboard.server.common.data.yunteng.enums.TkScriptFunctionType;
46 import org.thingsboard.server.common.data.yunteng.utils.ByteUtils; 63 import org.thingsboard.server.common.data.yunteng.utils.ByteUtils;
47 import org.thingsboard.server.common.msg.tools.TbRateLimitsException; 64 import org.thingsboard.server.common.msg.tools.TbRateLimitsException;
@@ -55,35 +72,15 @@ import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsRes @@ -55,35 +72,15 @@ import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsRes
55 import org.thingsboard.server.common.transport.service.DefaultTransportService; 72 import org.thingsboard.server.common.transport.service.DefaultTransportService;
56 import org.thingsboard.server.common.transport.service.SessionMetaData; 73 import org.thingsboard.server.common.transport.service.SessionMetaData;
57 import org.thingsboard.server.gen.transport.TransportProtos; 74 import org.thingsboard.server.gen.transport.TransportProtos;
58 -import org.thingsboard.server.gen.transport.TransportProtos.ScriptProto;  
59 import org.thingsboard.server.transport.tcp.adaptors.TcpAuthEntry; 75 import org.thingsboard.server.transport.tcp.adaptors.TcpAuthEntry;
60 -import org.thingsboard.server.transport.tcp.adaptors.TcpDownEntry;  
61 import org.thingsboard.server.transport.tcp.adaptors.TcpTransportAdaptor; 76 import org.thingsboard.server.transport.tcp.adaptors.TcpTransportAdaptor;
62 import org.thingsboard.server.transport.tcp.adaptors.TcpUpEntry; 77 import org.thingsboard.server.transport.tcp.adaptors.TcpUpEntry;
63 import org.thingsboard.server.transport.tcp.script.TkScriptFactory; 78 import org.thingsboard.server.transport.tcp.script.TkScriptFactory;
  79 +import org.thingsboard.server.transport.tcp.script.TkScriptInvokeService;
64 import org.thingsboard.server.transport.tcp.session.TcpDeviceSessionCtx; 80 import org.thingsboard.server.transport.tcp.session.TcpDeviceSessionCtx;
65 import org.thingsboard.server.transport.tcp.session.TcpGatewaySessionHandler; 81 import org.thingsboard.server.transport.tcp.session.TcpGatewaySessionHandler;
66 import org.thingsboard.server.transport.tcp.util.ByteBufUtils; 82 import org.thingsboard.server.transport.tcp.util.ByteBufUtils;
67 83
68 -import java.io.IOException;  
69 -import java.net.InetSocketAddress;  
70 -import java.util.List;  
71 -import java.util.Map;  
72 -import java.util.Optional;  
73 -import java.util.UUID;  
74 -import java.util.concurrent.ConcurrentHashMap;  
75 -import java.util.concurrent.ConcurrentMap;  
76 -import java.util.concurrent.TimeUnit;  
77 -import java.util.concurrent.atomic.AtomicInteger;  
78 -import java.util.regex.Pattern;  
79 -  
80 -import static io.netty.handler.codec.mqtt.MqttConnectReturnCode.CONNECTION_ACCEPTED;  
81 -import static io.netty.handler.codec.mqtt.MqttMessageType.PUBACK;  
82 -import static io.netty.handler.codec.mqtt.MqttMessageType.SUBACK;  
83 -import static io.netty.handler.codec.mqtt.MqttQoS.AT_MOST_ONCE;  
84 -import static org.thingsboard.server.common.transport.service.DefaultTransportService.SESSION_EVENT_MSG_CLOSED;  
85 -import static org.thingsboard.server.common.transport.service.DefaultTransportService.SESSION_EVENT_MSG_OPEN;  
86 -  
87 /** 84 /**
88 * @author Andrew Shvayka 85 * @author Andrew Shvayka
89 */ 86 */
@@ -104,9 +101,6 @@ public class TcpTransportHandler extends ChannelInboundHandlerAdapter implements @@ -104,9 +101,6 @@ public class TcpTransportHandler extends ChannelInboundHandlerAdapter implements
104 volatile InetSocketAddress address; 101 volatile InetSocketAddress address;
105 102
106 volatile TcpGatewaySessionHandler gatewaySessionHandler; 103 volatile TcpGatewaySessionHandler gatewaySessionHandler;
107 -  
108 -  
109 - private final ConcurrentMap<UUID, String> authScripts;  
110 private final AtomicInteger authedCounter = new AtomicInteger(); 104 private final AtomicInteger authedCounter = new AtomicInteger();
111 105
112 106
@@ -116,22 +110,6 @@ public class TcpTransportHandler extends ChannelInboundHandlerAdapter implements @@ -116,22 +110,6 @@ public class TcpTransportHandler extends ChannelInboundHandlerAdapter implements
116 this.transportService = context.getTransportService(); 110 this.transportService = context.getTransportService();
117 this.sslHandler = sslHandler; 111 this.sslHandler = sslHandler;
118 this.deviceSessionCtx = new TcpDeviceSessionCtx(sessionId, context); 112 this.deviceSessionCtx = new TcpDeviceSessionCtx(sessionId, context);
119 - this.authScripts = new ConcurrentHashMap<>();  
120 - List<ScriptProto> authScripts = this.transportService.getScripts(ScriptProto.newBuilder().setFunctionType(TkScriptFunctionType.TRANSPORT_TCP_AUTH.ordinal()).build());  
121 - authScripts.stream().forEach(i -> {  
122 - UUID scriptId = new UUID(i.getScriptIdMSB(), i.getScriptIdLSB());  
123 - deviceSessionCtx.cacheScript(scriptId, TkScriptFunctionType.TRANSPORT_TCP_AUTH, i.getConvertJs(), new FutureCallback<UUID>() {  
124 - @Override  
125 - public void onSuccess(@Nullable UUID result) {  
126 - TcpTransportHandler.this.authScripts.put(scriptId, result.toString());  
127 - }  
128 -  
129 - @Override  
130 - public void onFailure(Throwable t) {  
131 - }  
132 - });  
133 -  
134 - });  
135 } 113 }
136 114
137 @Override 115 @Override
@@ -149,10 +127,14 @@ public class TcpTransportHandler extends ChannelInboundHandlerAdapter implements @@ -149,10 +127,14 @@ public class TcpTransportHandler extends ChannelInboundHandlerAdapter implements
149 @Override 127 @Override
150 public void channelRead(ChannelHandlerContext ctx, Object msg) { 128 public void channelRead(ChannelHandlerContext ctx, Object msg) {
151 log.trace("【{}】 Processing msg: 【{}】", sessionId, msg); 129 log.trace("【{}】 Processing msg: 【{}】", sessionId, msg);
152 - if (address == null) {  
153 - address = getAddress(ctx);  
154 - }  
155 try { 130 try {
  131 + if(!context.isReady()){
  132 + ctx.close();
  133 + return;
  134 + }
  135 + if (address == null) {
  136 + address = getAddress(ctx);
  137 + }
156 if (msg instanceof ByteBuf) { 138 if (msg instanceof ByteBuf) {
157 ByteBuf message = (ByteBuf) msg; 139 ByteBuf message = (ByteBuf) msg;
158 byte[] byteMsg = ByteBufUtils.buf2Bytes(message); 140 byte[] byteMsg = ByteBufUtils.buf2Bytes(message);
@@ -316,7 +298,7 @@ public class TcpTransportHandler extends ChannelInboundHandlerAdapter implements @@ -316,7 +298,7 @@ public class TcpTransportHandler extends ChannelInboundHandlerAdapter implements
316 deviceSessionCtx.setProvisionOnly(true); 298 deviceSessionCtx.setProvisionOnly(true);
317 ctx.writeAndFlush(createTcpConnAckMsg(CONNECTION_ACCEPTED.name())); 299 ctx.writeAndFlush(createTcpConnAckMsg(CONNECTION_ACCEPTED.name()));
318 } else { 300 } else {
319 - authScripts.forEach((id, idStr) -> { 301 + TkScriptInvokeService.authScripts.forEach(id -> {
320 ListenableFuture item = context.getJsEngine().invokeFunction(id, accessToken); 302 ListenableFuture item = context.getJsEngine().invokeFunction(id, accessToken);
321 Futures.addCallback(item, new FutureCallback<String>() { 303 Futures.addCallback(item, new FutureCallback<String>() {
322 @Override 304 @Override
@@ -494,7 +476,7 @@ public class TcpTransportHandler extends ChannelInboundHandlerAdapter implements @@ -494,7 +476,7 @@ public class TcpTransportHandler extends ChannelInboundHandlerAdapter implements
494 476
495 private void onValidateFailed(ChannelHandlerContext ctx, MqttConnectReturnCode msg) { 477 private void onValidateFailed(ChannelHandlerContext ctx, MqttConnectReturnCode msg) {
496 authedCounter.incrementAndGet(); 478 authedCounter.incrementAndGet();
497 - if (authScripts.size() == authedCounter.incrementAndGet()) { 479 + if (TkScriptInvokeService.authScripts.size() == authedCounter.incrementAndGet()) {
498 ctx.writeAndFlush(createTcpConnAckMsg(msg.name())); 480 ctx.writeAndFlush(createTcpConnAckMsg(msg.name()));
499 ctx.close(); 481 ctx.close();
500 } 482 }
@@ -15,15 +15,29 @@ @@ -15,15 +15,29 @@
15 */ 15 */
16 package org.thingsboard.server.transport.tcp.script; 16 package org.thingsboard.server.transport.tcp.script;
17 17
  18 +import com.google.common.util.concurrent.FutureCallback;
18 import com.google.common.util.concurrent.Futures; 19 import com.google.common.util.concurrent.Futures;
19 import com.google.common.util.concurrent.ListenableFuture; 20 import com.google.common.util.concurrent.ListenableFuture;
  21 +import com.google.common.util.concurrent.MoreExecutors;
  22 +import lombok.Getter;
20 import lombok.extern.slf4j.Slf4j; 23 import lombok.extern.slf4j.Slf4j;
  24 +import org.jetbrains.annotations.NotNull;
  25 +import org.jetbrains.annotations.Nullable;
  26 +import org.springframework.boot.context.event.ApplicationReadyEvent;
  27 +import org.springframework.context.event.EventListener;
  28 +import org.springframework.core.annotation.Order;
21 import org.thingsboard.common.util.ThingsBoardThreadFactory; 29 import org.thingsboard.common.util.ThingsBoardThreadFactory;
  30 +import org.thingsboard.server.common.data.yunteng.dto.TkDeviceScriptDTO;
  31 +import org.thingsboard.server.common.data.yunteng.enums.StatusEnum;
22 import org.thingsboard.server.common.data.yunteng.enums.TkScriptFunctionType; 32 import org.thingsboard.server.common.data.yunteng.enums.TkScriptFunctionType;
  33 +import org.thingsboard.server.common.transport.DeviceUpdatedEvent;
  34 +import org.thingsboard.server.common.transport.yunteng.ScriptUpdatedEvent;
  35 +import org.thingsboard.server.gen.transport.TransportProtos;
23 36
24 import java.util.Map; 37 import java.util.Map;
25 import java.util.UUID; 38 import java.util.UUID;
26 import java.util.concurrent.ConcurrentHashMap; 39 import java.util.concurrent.ConcurrentHashMap;
  40 +import java.util.concurrent.ConcurrentSkipListSet;
27 import java.util.concurrent.Executors; 41 import java.util.concurrent.Executors;
28 import java.util.concurrent.ScheduledExecutorService; 42 import java.util.concurrent.ScheduledExecutorService;
29 import java.util.concurrent.atomic.AtomicInteger; 43 import java.util.concurrent.atomic.AtomicInteger;
@@ -57,11 +71,20 @@ public abstract class AbstractTkScriptInvokeService implements TkScriptInvokeSer @@ -57,11 +71,20 @@ public abstract class AbstractTkScriptInvokeService implements TkScriptInvokeSer
57 @Override 71 @Override
58 public ListenableFuture<UUID> eval(UUID id,TkScriptFunctionType scriptType, String scriptBody) { 72 public ListenableFuture<UUID> eval(UUID id,TkScriptFunctionType scriptType, String scriptBody) {
59 UUID scriptId = id == null?UUID.randomUUID():id; 73 UUID scriptId = id == null?UUID.randomUUID():id;
60 - String functionName = "invokeInternal_" + scriptId.toString().replace('-', '_');  
61 - String jsScript = generateJsScript(scriptType, functionName, scriptBody); 74 + String functionName = getFunctionName(scriptId);
  75 + String jsScript = generateJsScript(scriptType, functionName, scriptBody);
62 return doEval(scriptId, functionName, jsScript); 76 return doEval(scriptId, functionName, jsScript);
63 } 77 }
64 78
  79 + @NotNull
  80 + /**
  81 + * 构建脚本函数名称
  82 + */
  83 + private static String getFunctionName(UUID scriptId) {
  84 + String functionName = "invokeInternal_" + scriptId.toString().replace('-', '_');
  85 + return functionName;
  86 + }
  87 +
65 @Override 88 @Override
66 public ListenableFuture<Object> invokeFunction(UUID scriptId, Object... args) { 89 public ListenableFuture<Object> invokeFunction(UUID scriptId, Object... args) {
67 String functionName = scriptIdToNameMap.get(scriptId); 90 String functionName = scriptIdToNameMap.get(scriptId);
@@ -153,4 +176,46 @@ public abstract class AbstractTkScriptInvokeService implements TkScriptInvokeSer @@ -153,4 +176,46 @@ public abstract class AbstractTkScriptInvokeService implements TkScriptInvokeSer
153 return expirationTime; 176 return expirationTime;
154 } 177 }
155 } 178 }
  179 +
  180 + @EventListener(ScriptUpdatedEvent.class)
  181 + public void onDeviceUpdatedOrCreated(ScriptUpdatedEvent scriptUpdatedEvent) throws Exception {
  182 + TkDeviceScriptDTO scriptDTO = scriptUpdatedEvent.getScript();
  183 + UUID scriptId = UUID.fromString(scriptDTO.getId());
  184 + cacheScript(scriptId,scriptDTO.getScriptType(),scriptDTO.getConvertJs(), scriptDTO.getStatus());
  185 + }
  186 +
  187 + /**
  188 + * 编译并缓存脚本引擎
  189 + *
  190 + * @param scriptId 脚本引擎ID
  191 + * @param scriptType 脚本类型
  192 + * @param convertStr 脚本内容
  193 + * @param stats 脚本状态
  194 + */
  195 + public void cacheScript(UUID scriptId, TkScriptFunctionType scriptType, String convertStr, Integer stats) {
  196 + if(stats == StatusEnum.DISABLE.getIndex()){
  197 + authScripts.remove(scriptId);
  198 + try {
  199 + doRelease(scriptId,getFunctionName(scriptId));
  200 + } catch (Exception e) {
  201 + log.error(String.format("脚本【%s】内存释放失败:【%s】", convertStr, e));
  202 + }
  203 + } else if (stats == StatusEnum.ENABLE.getIndex()) {
  204 + ListenableFuture<UUID> result = eval(scriptId, scriptType, convertStr);
  205 +
  206 + Futures.addCallback(result, new FutureCallback() {
  207 + @Override
  208 + public void onSuccess(@Nullable Object result) {
  209 + if(TkScriptFunctionType.TRANSPORT_TCP_AUTH == scriptType){
  210 + authScripts.add(scriptId);
  211 + }
  212 + }
  213 +
  214 + @Override
  215 + public void onFailure(Throwable t) {
  216 + log.error(String.format("脚本【%s】解析时出现异常:【%s】", convertStr, t));
  217 + }
  218 + }, MoreExecutors.directExecutor());
  219 + }
  220 + }
156 } 221 }
@@ -16,9 +16,11 @@ @@ -16,9 +16,11 @@
16 package org.thingsboard.server.transport.tcp.script; 16 package org.thingsboard.server.transport.tcp.script;
17 17
18 import com.google.common.util.concurrent.ListenableFuture; 18 import com.google.common.util.concurrent.ListenableFuture;
  19 +import lombok.Getter;
19 import org.thingsboard.server.common.data.yunteng.enums.TkScriptFunctionType; 20 import org.thingsboard.server.common.data.yunteng.enums.TkScriptFunctionType;
20 21
21 import java.util.UUID; 22 import java.util.UUID;
  23 +import java.util.concurrent.ConcurrentSkipListSet;
22 24
23 public interface TkScriptInvokeService { 25 public interface TkScriptInvokeService {
24 26
@@ -46,4 +48,16 @@ public interface TkScriptInvokeService { @@ -46,4 +48,16 @@ public interface TkScriptInvokeService {
46 */ 48 */
47 ListenableFuture<Void> release(UUID scriptId); 49 ListenableFuture<Void> release(UUID scriptId);
48 50
  51 +
  52 + /**TCP协议的鉴权脚本*/
  53 + ConcurrentSkipListSet<UUID> authScripts = new ConcurrentSkipListSet<>();
  54 + /**
  55 + * 编译并缓存脚本引擎
  56 + *
  57 + * @param scriptId 脚本引擎ID
  58 + * @param scriptType 脚本类型
  59 + * @param convertStr 脚本内容
  60 + * @param stats 脚本状态
  61 + */
  62 + public void cacheScript(UUID scriptId, TkScriptFunctionType scriptType, String convertStr, Integer stats);
49 } 63 }
@@ -87,36 +87,10 @@ public abstract class TcpDeviceWareSessionContext extends DeviceAwareSessionCont @@ -87,36 +87,10 @@ public abstract class TcpDeviceWareSessionContext extends DeviceAwareSessionCont
87 this.authScriptId = UUID.fromString(tcpConfiguration.getAuthScriptId()); 87 this.authScriptId = UUID.fromString(tcpConfiguration.getAuthScriptId());
88 } 88 }
89 this.telemetryScriptId = UUID.fromString(tcpConfiguration.getUpScriptId()); 89 this.telemetryScriptId = UUID.fromString(tcpConfiguration.getUpScriptId());
90 - TransportProtos.ScriptProto upScript = context.getTransportService().getScripts(TransportProtos.ScriptProto.newBuilder().setScriptIdLSB(telemetryScriptId.getLeastSignificantBits()).setScriptIdMSB(telemetryScriptId.getMostSignificantBits()).build()).get(0);  
91 - cacheScript(telemetryScriptId, TkScriptFunctionType.TRANSPORT_TCP_UP, upScript.getConvertJs(), null);  
92 90
93 } 91 }
94 92
95 - /**  
96 - * 编译并缓存脚本引擎  
97 - *  
98 - * @param scriptId 脚本引擎ID  
99 - * @param scriptType 脚本类型  
100 - * @param convertStr 脚本内容  
101 - * @param callback 脚本引擎执行成功的回调函数  
102 - */  
103 - public void cacheScript(UUID scriptId, TkScriptFunctionType scriptType, String convertStr, FutureCallback callback) {  
104 - ListenableFuture<UUID> result = context.getJsEngine().eval(scriptId, scriptType, convertStr);  
105 - if (callback == null) {  
106 - callback = new FutureCallback() {  
107 - @Override  
108 - public void onSuccess(@Nullable Object result) {  
109 -  
110 - }  
111 93
112 - @Override  
113 - public void onFailure(Throwable t) {  
114 - log.error(String.format("脚本【%s】解析时出现异常:【%s】", convertStr, t));  
115 - }  
116 - };  
117 - }  
118 - Futures.addCallback(result, callback, MoreExecutors.directExecutor());  
119 - }  
120 94
121 /** 95 /**
122 * 执行上行数据的解析脚本 96 * 执行上行数据的解析脚本
@@ -21,6 +21,7 @@ import com.google.common.util.concurrent.MoreExecutors; @@ -21,6 +21,7 @@ import com.google.common.util.concurrent.MoreExecutors;
21 import com.google.gson.Gson; 21 import com.google.gson.Gson;
22 import com.google.gson.JsonObject; 22 import com.google.gson.JsonObject;
23 import com.google.protobuf.ByteString; 23 import com.google.protobuf.ByteString;
  24 +import lombok.Getter;
24 import lombok.extern.slf4j.Slf4j; 25 import lombok.extern.slf4j.Slf4j;
25 import org.springframework.beans.factory.annotation.Value; 26 import org.springframework.beans.factory.annotation.Value;
26 import org.springframework.context.ApplicationEventPublisher; 27 import org.springframework.context.ApplicationEventPublisher;
@@ -49,6 +50,7 @@ import org.thingsboard.server.common.data.id.TenantProfileId; @@ -49,6 +50,7 @@ import org.thingsboard.server.common.data.id.TenantProfileId;
49 import org.thingsboard.server.common.data.rpc.RpcStatus; 50 import org.thingsboard.server.common.data.rpc.RpcStatus;
50 import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidationException; 51 import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidationException;
51 import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage; 52 import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage;
  53 +import org.thingsboard.server.common.data.yunteng.dto.TkDeviceScriptDTO;
52 import org.thingsboard.server.common.msg.TbMsg; 54 import org.thingsboard.server.common.msg.TbMsg;
53 import org.thingsboard.server.common.msg.TbMsgMetaData; 55 import org.thingsboard.server.common.msg.TbMsgMetaData;
54 import org.thingsboard.server.common.msg.queue.ServiceQueue; 56 import org.thingsboard.server.common.msg.queue.ServiceQueue;
@@ -72,6 +74,7 @@ import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsRes @@ -72,6 +74,7 @@ import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsRes
72 import org.thingsboard.server.common.transport.limits.TransportRateLimitService; 74 import org.thingsboard.server.common.transport.limits.TransportRateLimitService;
73 import org.thingsboard.server.common.transport.util.DataDecodingEncodingService; 75 import org.thingsboard.server.common.transport.util.DataDecodingEncodingService;
74 import org.thingsboard.server.common.transport.util.JsonUtils; 76 import org.thingsboard.server.common.transport.util.JsonUtils;
  77 +import org.thingsboard.server.common.transport.yunteng.ScriptUpdatedEvent;
75 import org.thingsboard.server.gen.transport.TransportProtos; 78 import org.thingsboard.server.gen.transport.TransportProtos;
76 import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceRequestMsg; 79 import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceRequestMsg;
77 import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceResponseMsg; 80 import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceResponseMsg;
@@ -109,13 +112,7 @@ import java.util.Optional; @@ -109,13 +112,7 @@ import java.util.Optional;
109 import java.util.Random; 112 import java.util.Random;
110 import java.util.Set; 113 import java.util.Set;
111 import java.util.UUID; 114 import java.util.UUID;
112 -import java.util.concurrent.ConcurrentHashMap;  
113 -import java.util.concurrent.ConcurrentMap;  
114 -import java.util.concurrent.ExecutionException;  
115 -import java.util.concurrent.ExecutorService;  
116 -import java.util.concurrent.Executors;  
117 -import java.util.concurrent.ScheduledFuture;  
118 -import java.util.concurrent.TimeUnit; 115 +import java.util.concurrent.*;
119 import java.util.concurrent.atomic.AtomicInteger; 116 import java.util.concurrent.atomic.AtomicInteger;
120 import java.util.stream.Collectors; 117 import java.util.stream.Collectors;
121 118
@@ -188,6 +185,9 @@ public class DefaultTransportService implements TransportService { @@ -188,6 +185,9 @@ public class DefaultTransportService implements TransportService {
188 private final ConcurrentMap<UUID, SessionActivityData> sessionsActivity = new ConcurrentHashMap<>(); 185 private final ConcurrentMap<UUID, SessionActivityData> sessionsActivity = new ConcurrentHashMap<>();
189 private final Map<String, RpcRequestMetadata> toServerRpcPendingMap = new ConcurrentHashMap<>(); 186 private final Map<String, RpcRequestMetadata> toServerRpcPendingMap = new ConcurrentHashMap<>();
190 187
  188 + @Getter
  189 + /**TCP协议的鉴权脚本*/
  190 + private final ConcurrentSkipListSet<UUID> authScripts = new ConcurrentSkipListSet<>();
191 private volatile boolean stopped = false; 191 private volatile boolean stopped = false;
192 192
193 public DefaultTransportService(TbServiceInfoProvider serviceInfoProvider, 193 public DefaultTransportService(TbServiceInfoProvider serviceInfoProvider,
@@ -939,6 +939,13 @@ public class DefaultTransportService implements TransportService { @@ -939,6 +939,13 @@ public class DefaultTransportService implements TransportService {
939 onDeviceUpdate(device); 939 onDeviceUpdate(device);
940 eventPublisher.publishEvent(new DeviceUpdatedEvent(device)); 940 eventPublisher.publishEvent(new DeviceUpdatedEvent(device));
941 }); 941 });
  942 +
  943 + //Thingskit function
  944 + } else if (EntityType.JS_SCRIPT.equals(entityType)) {
  945 + Optional<TkDeviceScriptDTO> deviceOpt = dataDecodingEncodingService.decode(msg.getData().toByteArray());
  946 + deviceOpt.ifPresent(device -> {
  947 + eventPublisher.publishEvent(new ScriptUpdatedEvent(device));
  948 + });
942 } 949 }
943 } else if (toSessionMsg.hasEntityDeleteMsg()) { 950 } else if (toSessionMsg.hasEntityDeleteMsg()) {
944 TransportProtos.EntityDeleteMsg msg = toSessionMsg.getEntityDeleteMsg(); 951 TransportProtos.EntityDeleteMsg msg = toSessionMsg.getEntityDeleteMsg();
  1 +/**
  2 + * Copyright © 2016-2022 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.transport.yunteng;
  17 +
  18 +import lombok.Getter;
  19 +import org.thingsboard.server.common.data.Device;
  20 +import org.thingsboard.server.common.data.yunteng.dto.TkDeviceScriptDTO;
  21 +
  22 +@Getter
  23 +public class ScriptUpdatedEvent {
  24 + private final TkDeviceScriptDTO script;
  25 +
  26 + public ScriptUpdatedEvent(TkDeviceScriptDTO script) {
  27 + this.script = script;
  28 + }
  29 +}
@@ -16,6 +16,7 @@ import org.thingsboard.server.common.data.yunteng.constant.QueryConstant; @@ -16,6 +16,7 @@ import org.thingsboard.server.common.data.yunteng.constant.QueryConstant;
16 import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidationException; 16 import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidationException;
17 import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage; 17 import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage;
18 import org.thingsboard.server.common.data.yunteng.dto.*; 18 import org.thingsboard.server.common.data.yunteng.dto.*;
  19 +import org.thingsboard.server.common.data.yunteng.enums.StatusEnum;
19 import org.thingsboard.server.common.data.yunteng.enums.TkScriptFunctionType; 20 import org.thingsboard.server.common.data.yunteng.enums.TkScriptFunctionType;
20 import org.thingsboard.server.common.data.yunteng.enums.TransportTypeEnum; 21 import org.thingsboard.server.common.data.yunteng.enums.TransportTypeEnum;
21 import org.thingsboard.server.common.data.yunteng.utils.ByteUtils; 22 import org.thingsboard.server.common.data.yunteng.utils.ByteUtils;
@@ -101,17 +102,10 @@ public class TkDeviceScriptServiceImpl @@ -101,17 +102,10 @@ public class TkDeviceScriptServiceImpl
101 } 102 }
102 103
103 @Override 104 @Override
104 - public List<TkDeviceScriptDTO> getScriptes(TkScriptFunctionType type, UUID tenantId, UUID projectId, UUID scriptId){ 105 + public List<TkDeviceScriptDTO> getScriptes(){
105 LambdaQueryWrapper<TkDeviceScriptEntity> queryWrapper = 106 LambdaQueryWrapper<TkDeviceScriptEntity> queryWrapper =
106 new QueryWrapper<TkDeviceScriptEntity>().lambda(); 107 new QueryWrapper<TkDeviceScriptEntity>().lambda();
107 - if(scriptId == null){  
108 - queryWrapper.eq(TkDeviceScriptEntity::getScriptType, type);  
109 - }else{  
110 - queryWrapper.eq(TkDeviceScriptEntity::getId, scriptId.toString());  
111 - }  
112 - if(tenantId != null){  
113 - queryWrapper.eq(TkDeviceScriptEntity::getTenantId, tenantId.toString());  
114 - } 108 + queryWrapper.eq(TkDeviceScriptEntity::getStatus, StatusEnum.ENABLE.getIndex());
115 List<TkDeviceScriptEntity> result = baseMapper.selectList(queryWrapper); 109 List<TkDeviceScriptEntity> result = baseMapper.selectList(queryWrapper);
116 return result.stream() 110 return result.stream()
117 .map(item -> item.getDTO(TkDeviceScriptDTO.class)) 111 .map(item -> item.getDTO(TkDeviceScriptDTO.class))
@@ -250,7 +244,7 @@ public class TkDeviceScriptServiceImpl @@ -250,7 +244,7 @@ public class TkDeviceScriptServiceImpl
250 LambdaQueryWrapper<TkDeviceScriptEntity> queryWrapper = 244 LambdaQueryWrapper<TkDeviceScriptEntity> queryWrapper =
251 new QueryWrapper<TkDeviceScriptEntity>() 245 new QueryWrapper<TkDeviceScriptEntity>()
252 .lambda() 246 .lambda()
253 - .eq(TkDeviceScriptEntity::getStatus,1) 247 + .eq(TkDeviceScriptEntity::getStatus,StatusEnum.ENABLE.getIndex())
254 .eq(scriptType!=null,TkDeviceScriptEntity::getScriptType, scriptType) 248 .eq(scriptType!=null,TkDeviceScriptEntity::getScriptType, scriptType)
255 .and(s->s.eq(TkDeviceScriptEntity::getTenantId, tenantId).or(r->r.eq(TkDeviceScriptEntity::getTenantId, EntityId.NULL_UUID.toString()))); 249 .and(s->s.eq(TkDeviceScriptEntity::getTenantId, tenantId).or(r->r.eq(TkDeviceScriptEntity::getTenantId, EntityId.NULL_UUID.toString())));
256 return baseMapper.selectList(queryWrapper).stream() 250 return baseMapper.selectList(queryWrapper).stream()
@@ -13,11 +13,9 @@ public interface TkDeviceScriptService extends BaseService<TkDeviceScriptEntity> @@ -13,11 +13,9 @@ public interface TkDeviceScriptService extends BaseService<TkDeviceScriptEntity>
13 13
14 /** 14 /**
15 * 查找脚本解析的脚本内容 15 * 查找脚本解析的脚本内容
16 - * @param tenantId  
17 - * @param scriptId  
18 * @return 16 * @return
19 */ 17 */
20 - List<TkDeviceScriptDTO> getScriptes(TkScriptFunctionType type, UUID tenantId, UUID projectId, UUID scriptId); 18 + List<TkDeviceScriptDTO> getScriptes();
21 19
22 TkDeviceScriptDTO insertOrUpdate(TkDeviceScriptDTO deviceDTO); 20 TkDeviceScriptDTO insertOrUpdate(TkDeviceScriptDTO deviceDTO);
23 21
@@ -68,14 +68,14 @@ @@ -68,14 +68,14 @@
68 </resultMap> 68 </resultMap>
69 69
70 <sql id="basicColumns"> 70 <sql id="basicColumns">
71 - ifd.id 71 + ifd.id,ifd.gateway_id
72 ,ifd.sn,ifd.brand,ifd.name,ifd.alias,ifd.device_info,ifd.profile_id,ifd.device_profile_id,ifd.active_time,ifd.tenant_id,ifd.description 72 ,ifd.sn,ifd.brand,ifd.name,ifd.alias,ifd.device_info,ifd.profile_id,ifd.device_profile_id,ifd.active_time,ifd.tenant_id,ifd.description
73 ,ifd.tb_device_id,ifd.label,ifd.last_connect_time,ifd.device_type,ifd.device_state,ifd.create_time,ifd.update_time,ifd.creator, 73 ,ifd.tb_device_id,ifd.label,ifd.last_connect_time,ifd.device_type,ifd.device_state,ifd.create_time,ifd.update_time,ifd.creator,
74 ifd.updater,ifd.organization_id,ifd.alarm_status 74 ifd.updater,ifd.organization_id,ifd.alarm_status
75 </sql> 75 </sql>
76 <sql id="detailColumns"> 76 <sql id="detailColumns">
77 <include refid="pageColumns"/> 77 <include refid="pageColumns"/>
78 - ,ifd.gateway_id,idg.name gateway_name,idg.alias gateway_alias 78 + ,idg.name gateway_name,idg.alias gateway_alias
79 </sql> 79 </sql>
80 <sql id="pageColumns"> 80 <sql id="pageColumns">
81 <include refid="basicColumns"/> 81 <include refid="basicColumns"/>