Commit 3612fa7ab90c0d6dfffc320a12571183b11b85cd
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"/> |