Showing
15 changed files
with
371 additions
and
70 deletions
@@ -518,4 +518,13 @@ public class TkDeviceController extends BaseController { | @@ -518,4 +518,13 @@ public class TkDeviceController extends BaseController { | ||
518 | return ResponseEntity.ok( | 518 | return ResponseEntity.ok( |
519 | tkdeviceService.getDeviceAttributes(deviceProfileId, tenantId, dataType)); | 519 | tkdeviceService.getDeviceAttributes(deviceProfileId, tenantId, dataType)); |
520 | } | 520 | } |
521 | + | ||
522 | + @PostMapping("get/devices") | ||
523 | + @ApiOperation("通过设备ID列表获取设备信息") | ||
524 | + public ResponseResult<List<DeviceDTO>> findDeviceInfoByTbDeviceIds( | ||
525 | + @RequestBody List<String> tbDeviceIds) throws ThingsboardException { | ||
526 | + return ResponseResult.success( | ||
527 | + tkdeviceService.findDeviceInfoByTbDeviceIds( | ||
528 | + tbDeviceIds, getCurrentUser().getCurrentTenantId())); | ||
529 | + } | ||
521 | } | 530 | } |
@@ -14,6 +14,7 @@ import org.thingsboard.server.common.data.yunteng.common.UpdateGroup; | @@ -14,6 +14,7 @@ import org.thingsboard.server.common.data.yunteng.common.UpdateGroup; | ||
14 | import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidationException; | 14 | import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidationException; |
15 | import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage; | 15 | import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage; |
16 | import org.thingsboard.server.common.data.yunteng.dto.DeleteDTO; | 16 | import org.thingsboard.server.common.data.yunteng.dto.DeleteDTO; |
17 | +import org.thingsboard.server.common.data.yunteng.dto.task.TaskImmediateExecuteDTO; | ||
17 | import org.thingsboard.server.common.data.yunteng.dto.task.TkTaskCenterDTO; | 18 | import org.thingsboard.server.common.data.yunteng.dto.task.TkTaskCenterDTO; |
18 | import org.thingsboard.server.common.data.yunteng.enums.OrderTypeEnum; | 19 | import org.thingsboard.server.common.data.yunteng.enums.OrderTypeEnum; |
19 | import org.thingsboard.server.common.data.yunteng.enums.TargetTypeEnum; | 20 | import org.thingsboard.server.common.data.yunteng.enums.TargetTypeEnum; |
@@ -126,6 +127,18 @@ public class TkTaskCenterController extends BaseController { | @@ -126,6 +127,18 @@ public class TkTaskCenterController extends BaseController { | ||
126 | taskId, tbDeviceId, getCurrentUser().getCurrentTenantId(), allow)); | 127 | taskId, tbDeviceId, getCurrentUser().getCurrentTenantId(), allow)); |
127 | } | 128 | } |
128 | 129 | ||
130 | + @PostMapping("/immediate/execute") | ||
131 | + @PreAuthorize( | ||
132 | + "@check.checkPermissions({'TENANT_ADMIN','CUSTOMER_USER'},{'api:yt:task_center:immediate:execute'})") | ||
133 | + @ApiOperation(value = "立即执行任务中心任务") | ||
134 | + public ResponseResult<Boolean> immediateExecute( | ||
135 | + @Validated @RequestBody TaskImmediateExecuteDTO immediateExecuteDTO) | ||
136 | + throws SchedulerException, ThingsboardException { | ||
137 | + return ResponseResult.success( | ||
138 | + tkTaskCenterService.immediateExecute( | ||
139 | + immediateExecuteDTO, getCurrentUser().getCurrentTenantId())); | ||
140 | + } | ||
141 | + | ||
129 | private TkTaskCenterDTO saveOrUpdate(TkTaskCenterDTO tkTaskCenterDTO) | 142 | private TkTaskCenterDTO saveOrUpdate(TkTaskCenterDTO tkTaskCenterDTO) |
130 | throws ThingsboardException, SchedulerException { | 143 | throws ThingsboardException, SchedulerException { |
131 | tkTaskCenterDTO.setTenantId(getCurrentUser().getCurrentTenantId()); | 144 | tkTaskCenterDTO.setTenantId(getCurrentUser().getCurrentTenantId()); |
1 | package org.thingsboard.server.utils.yunteng; | 1 | package org.thingsboard.server.utils.yunteng; |
2 | 2 | ||
3 | import com.fasterxml.jackson.databind.JsonNode; | 3 | import com.fasterxml.jackson.databind.JsonNode; |
4 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
4 | import com.google.common.util.concurrent.FutureCallback; | 5 | import com.google.common.util.concurrent.FutureCallback; |
5 | import com.google.common.util.concurrent.Futures; | 6 | import com.google.common.util.concurrent.Futures; |
6 | import com.google.common.util.concurrent.ListenableFuture; | 7 | import com.google.common.util.concurrent.ListenableFuture; |
@@ -16,13 +17,18 @@ import org.thingsboard.server.common.data.id.DeviceId; | @@ -16,13 +17,18 @@ import org.thingsboard.server.common.data.id.DeviceId; | ||
16 | import org.thingsboard.server.common.data.id.TenantId; | 17 | import org.thingsboard.server.common.data.id.TenantId; |
17 | import org.thingsboard.server.common.data.rpc.ToDeviceRpcRequestBody; | 18 | import org.thingsboard.server.common.data.rpc.ToDeviceRpcRequestBody; |
18 | import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants; | 19 | import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants; |
20 | +import org.thingsboard.server.common.data.yunteng.constant.ModelConstants; | ||
19 | import org.thingsboard.server.common.data.yunteng.core.cache.CacheUtils; | 21 | import org.thingsboard.server.common.data.yunteng.core.cache.CacheUtils; |
20 | import org.thingsboard.server.common.data.yunteng.dto.DeviceDTO; | 22 | import org.thingsboard.server.common.data.yunteng.dto.DeviceDTO; |
21 | import org.thingsboard.server.common.data.yunteng.dto.task.TargetContentDTO; | 23 | import org.thingsboard.server.common.data.yunteng.dto.task.TargetContentDTO; |
24 | +import org.thingsboard.server.common.data.yunteng.dto.task.TaskImmediateExecuteDTO; | ||
25 | +import org.thingsboard.server.common.data.yunteng.dto.task.TkDeviceTaskCenterDTO; | ||
22 | import org.thingsboard.server.common.data.yunteng.dto.task.TkTaskCenterDTO; | 26 | import org.thingsboard.server.common.data.yunteng.dto.task.TkTaskCenterDTO; |
27 | +import org.thingsboard.server.common.data.yunteng.enums.CmdTypeEnum; | ||
23 | import org.thingsboard.server.common.data.yunteng.enums.TargetTypeEnum; | 28 | import org.thingsboard.server.common.data.yunteng.enums.TargetTypeEnum; |
24 | import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest; | 29 | import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest; |
25 | import org.thingsboard.server.dao.yunteng.service.TkDeviceService; | 30 | import org.thingsboard.server.dao.yunteng.service.TkDeviceService; |
31 | +import org.thingsboard.server.dao.yunteng.service.TkDeviceTaskCenterService; | ||
26 | import org.thingsboard.server.dao.yunteng.service.TkTaskCenterService; | 32 | import org.thingsboard.server.dao.yunteng.service.TkTaskCenterService; |
27 | import org.thingsboard.server.service.rpc.TbCoreDeviceRpcService; | 33 | import org.thingsboard.server.service.rpc.TbCoreDeviceRpcService; |
28 | import org.thingsboard.server.service.security.model.SecurityUser; | 34 | import org.thingsboard.server.service.security.model.SecurityUser; |
@@ -44,6 +50,8 @@ public class RpcCommandTask { | @@ -44,6 +50,8 @@ public class RpcCommandTask { | ||
44 | private final TbCoreDeviceRpcService tbCoreDeviceRpcService; | 50 | private final TbCoreDeviceRpcService tbCoreDeviceRpcService; |
45 | private final TkDeviceService tkDeviceService; | 51 | private final TkDeviceService tkDeviceService; |
46 | private final CacheUtils cacheUtils; | 52 | private final CacheUtils cacheUtils; |
53 | + private final TkDeviceTaskCenterService tkDeviceTaskCenterService; | ||
54 | + private static final String cacheName = FastIotConstants.CacheConfigKey.TASK_CENTER_INFOS; | ||
47 | 55 | ||
48 | public void process(String taskCenterId) { | 56 | public void process(String taskCenterId) { |
49 | // 通过任务中心ID查询执行命令及执行对象 | 57 | // 通过任务中心ID查询执行命令及执行对象 |
@@ -59,24 +67,34 @@ public class RpcCommandTask { | @@ -59,24 +67,34 @@ public class RpcCommandTask { | ||
59 | TargetContentDTO targetContent = tkTaskCenterDTO.getExecuteTarget(); | 67 | TargetContentDTO targetContent = tkTaskCenterDTO.getExecuteTarget(); |
60 | JsonNode cmdJsonNode = tkTaskCenterDTO.getExecuteContent().getPushContent(); | 68 | JsonNode cmdJsonNode = tkTaskCenterDTO.getExecuteContent().getPushContent(); |
61 | SecurityUser securityUser = new SecurityUser(); | 69 | SecurityUser securityUser = new SecurityUser(); |
70 | + String taskCenterId = tkTaskCenterDTO.getId(); | ||
71 | + | ||
72 | + String immediateExecuteKey = FastIotConstants.CacheConfigKey.TASK_IMMEDIATE_EXECUTE + "_" + taskCenterId; | ||
73 | + Optional<TaskImmediateExecuteDTO> immediateExecuteDTO = cacheUtils.get(cacheName,immediateExecuteKey); | ||
74 | + List<String> data = targetContent.getData(); | ||
75 | + //如果从缓存里面获取了任务的立即执行,则以缓存里面的数据作为执行依据 | ||
76 | + if(immediateExecuteDTO.isPresent()){ | ||
77 | + TaskImmediateExecuteDTO immediateExecute = immediateExecuteDTO.get(); | ||
78 | + data = immediateExecute.getTargetIds(); | ||
79 | + targetType = immediateExecute.getExecuteTarget(); | ||
80 | + } | ||
81 | + | ||
62 | // send cmd | 82 | // send cmd |
63 | - if (targetContent.getData() != null && null != cmdJsonNode) { | 83 | + if (data != null && null != cmdJsonNode) { |
64 | String tenantId = tkTaskCenterDTO.getTenantId(); | 84 | String tenantId = tkTaskCenterDTO.getTenantId(); |
65 | - String cacheName = FastIotConstants.CacheConfigKey.TASK_CENTER_INFOS; | ||
66 | String key = | 85 | String key = |
67 | - FastIotConstants.CacheConfigKey.TASK_CENTER_EXECUTE_TIME | ||
68 | - + "_" | ||
69 | - + tkTaskCenterDTO.getId(); | 86 | + FastIotConstants.CacheConfigKey.TASK_CENTER_EXECUTE_TIME + "_" + taskCenterId; |
70 | cacheUtils.put( | 87 | cacheUtils.put( |
71 | cacheName, | 88 | cacheName, |
72 | key, | 89 | key, |
73 | LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli()); | 90 | LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli()); |
74 | if (targetType.equals(TargetTypeEnum.DEVICES)) { | 91 | if (targetType.equals(TargetTypeEnum.DEVICES)) { |
75 | - for (String deviceId : targetContent.getData()) { | ||
76 | - sendRpcCommand(cmdJsonNode, tenantId, deviceId, securityUser); | 92 | + for (String deviceId : data) { |
93 | + sendRpcCommand(cmdJsonNode, tenantId, deviceId, securityUser, taskCenterId); | ||
77 | } | 94 | } |
78 | } else { | 95 | } else { |
79 | - sendRpcCommandByProducts(targetContent, cmdJsonNode, tenantId, securityUser); | 96 | + sendRpcCommandByProducts( |
97 | + targetContent, cmdJsonNode, tenantId, securityUser, taskCenterId); | ||
80 | } | 98 | } |
81 | } | 99 | } |
82 | } | 100 | } |
@@ -92,7 +110,8 @@ public class RpcCommandTask { | @@ -92,7 +110,8 @@ public class RpcCommandTask { | ||
92 | TargetContentDTO targetContent, | 110 | TargetContentDTO targetContent, |
93 | JsonNode cmdJsonNode, | 111 | JsonNode cmdJsonNode, |
94 | String tenantId, | 112 | String tenantId, |
95 | - SecurityUser securityUser) { | 113 | + SecurityUser securityUser, |
114 | + String taskCenterId) { | ||
96 | for (String deviceProfileId : targetContent.getData()) { | 115 | for (String deviceProfileId : targetContent.getData()) { |
97 | Futures.addCallback( | 116 | Futures.addCallback( |
98 | tkDeviceService.findDeviceListByDeviceProfileId(deviceProfileId, tenantId), | 117 | tkDeviceService.findDeviceListByDeviceProfileId(deviceProfileId, tenantId), |
@@ -112,7 +131,8 @@ public class RpcCommandTask { | @@ -112,7 +131,8 @@ public class RpcCommandTask { | ||
112 | } | 131 | } |
113 | } | 132 | } |
114 | if (needSendCommand) { | 133 | if (needSendCommand) { |
115 | - sendRpcCommand(cmdJsonNode, tenantId, dto.getTbDeviceId(), securityUser); | 134 | + sendRpcCommand( |
135 | + cmdJsonNode, tenantId, dto.getTbDeviceId(), securityUser, taskCenterId); | ||
116 | } | 136 | } |
117 | } | 137 | } |
118 | } | 138 | } |
@@ -126,11 +146,18 @@ public class RpcCommandTask { | @@ -126,11 +146,18 @@ public class RpcCommandTask { | ||
126 | } | 146 | } |
127 | 147 | ||
128 | private void sendRpcCommand( | 148 | private void sendRpcCommand( |
129 | - JsonNode cmdJsonNode, String tenantId, String originateId, SecurityUser securityUser) { | 149 | + JsonNode cmdJsonNode, |
150 | + String tenantId, | ||
151 | + String originateId, | ||
152 | + SecurityUser securityUser, | ||
153 | + String taskCenterId) { | ||
130 | JsonNode rpcCommand = cmdJsonNode.get(FastIotConstants.RPC_COMMAND); | 154 | JsonNode rpcCommand = cmdJsonNode.get(FastIotConstants.RPC_COMMAND); |
131 | ToDeviceRpcRequestBody body = | 155 | ToDeviceRpcRequestBody body = |
132 | new ToDeviceRpcRequestBody("methodThingskit", JacksonUtil.toString(rpcCommand)); | 156 | new ToDeviceRpcRequestBody("methodThingskit", JacksonUtil.toString(rpcCommand)); |
133 | DeviceId deviceId = new DeviceId(UUID.fromString(originateId)); | 157 | DeviceId deviceId = new DeviceId(UUID.fromString(originateId)); |
158 | + ObjectNode objectNode = JacksonUtil.newObjectNode(); | ||
159 | + objectNode.put( | ||
160 | + ModelConstants.TablePropertyMapping.COMMAND_TYPE, CmdTypeEnum.TASK_CENTER.ordinal()); | ||
134 | ToDeviceRpcRequest request = | 161 | ToDeviceRpcRequest request = |
135 | new ToDeviceRpcRequest( | 162 | new ToDeviceRpcRequest( |
136 | UUID.randomUUID(), | 163 | UUID.randomUUID(), |
@@ -141,12 +168,26 @@ public class RpcCommandTask { | @@ -141,12 +168,26 @@ public class RpcCommandTask { | ||
141 | body, | 168 | body, |
142 | true, | 169 | true, |
143 | null, | 170 | null, |
144 | - null); | 171 | + JacksonUtil.toString(objectNode)); |
145 | tbCoreDeviceRpcService.processRestApiRpcRequest( | 172 | tbCoreDeviceRpcService.processRestApiRpcRequest( |
146 | request, | 173 | request, |
147 | fromDeviceRpcResponse -> { | 174 | fromDeviceRpcResponse -> { |
148 | log.trace("Device renamed RPC with id: [{}] ", request.getId()); | 175 | log.trace("Device renamed RPC with id: [{}] ", request.getId()); |
149 | }, | 176 | }, |
150 | securityUser); | 177 | securityUser); |
178 | + // 更新设备与任务中心的执行时间 | ||
179 | + TkDeviceTaskCenterDTO tkDeviceTaskCenterDTO = | ||
180 | + tkDeviceTaskCenterService.findInfoByDeviceIdAndTaskCenterId( | ||
181 | + tenantId, originateId, taskCenterId); | ||
182 | + if (null != tkDeviceTaskCenterDTO) { | ||
183 | + LocalDateTime localDateTime = LocalDateTime.now(); | ||
184 | + Long executeTime = localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli(); | ||
185 | + tkDeviceTaskCenterDTO.setLastExecuteTime(localDateTime); | ||
186 | + tkDeviceTaskCenterService.saveOrUpdate(tkDeviceTaskCenterDTO); | ||
187 | + // 将设备执行时间存入缓存 | ||
188 | + String key = | ||
189 | + FastIotConstants.CacheConfigKey.TASK_CENTER_DEVICE_EXECUTE_TIME + "_" + originateId; | ||
190 | + cacheUtils.put(cacheName, key, executeTime); | ||
191 | + } | ||
151 | } | 192 | } |
152 | } | 193 | } |
@@ -20,7 +20,6 @@ public interface FastIotConstants { | @@ -20,7 +20,6 @@ public interface FastIotConstants { | ||
20 | Pattern CHINA_MOBILE_PATTERN = Pattern.compile(MOBILE); | 20 | Pattern CHINA_MOBILE_PATTERN = Pattern.compile(MOBILE); |
21 | String DEFAULT_DELIMITER = "#"; | 21 | String DEFAULT_DELIMITER = "#"; |
22 | String RPC_COMMAND = "rpcCommand"; | 22 | String RPC_COMMAND = "rpcCommand"; |
23 | - | ||
24 | interface CacheConfigKey { | 23 | interface CacheConfigKey { |
25 | String CACHE_CONFIG_KEY = "yunTengIotCache"; | 24 | String CACHE_CONFIG_KEY = "yunTengIotCache"; |
26 | String USER_PERMISSION_PREFIX = "userPermissionFor_"; | 25 | String USER_PERMISSION_PREFIX = "userPermissionFor_"; |
@@ -29,6 +28,8 @@ public interface FastIotConstants { | @@ -29,6 +28,8 @@ public interface FastIotConstants { | ||
29 | String PUBLIC_ID = "publicId_"; | 28 | String PUBLIC_ID = "publicId_"; |
30 | String TASK_CENTER_INFOS = "taskCenterInfos"; | 29 | String TASK_CENTER_INFOS = "taskCenterInfos"; |
31 | String TASK_CENTER_EXECUTE_TIME = "taskCenterExecuteTime"; | 30 | String TASK_CENTER_EXECUTE_TIME = "taskCenterExecuteTime"; |
31 | + String TASK_CENTER_DEVICE_EXECUTE_TIME = "taskCenterDeviceExecuteTime"; | ||
32 | + String TASK_IMMEDIATE_EXECUTE = "taskImmediateExecute"; | ||
32 | } | 33 | } |
33 | 34 | ||
34 | interface TBCacheConfig { | 35 | interface TBCacheConfig { |
1 | +package org.thingsboard.server.common.data.yunteng.dto.task; | ||
2 | + | ||
3 | +import io.swagger.annotations.ApiModelProperty; | ||
4 | +import lombok.Data; | ||
5 | +import org.thingsboard.server.common.data.yunteng.enums.TargetTypeEnum; | ||
6 | + | ||
7 | +import javax.validation.constraints.NotEmpty; | ||
8 | +import javax.validation.constraints.NotNull; | ||
9 | +import java.io.Serializable; | ||
10 | +import java.util.List; | ||
11 | + | ||
12 | +@Data | ||
13 | +public class TaskImmediateExecuteDTO implements Serializable { | ||
14 | + | ||
15 | + private static final long serialVersionUID = -6249425147049039746L; | ||
16 | + | ||
17 | + @NotEmpty(message = "任务中心ID不能为空或空字符串") | ||
18 | + @ApiModelProperty(value = "任务中心任务ID") | ||
19 | + private String id; | ||
20 | + | ||
21 | + @ApiModelProperty(value = "执行类型:设备/产品") | ||
22 | + private TargetTypeEnum executeTarget = TargetTypeEnum.DEVICES; | ||
23 | + | ||
24 | + @NotEmpty(message = "任务中心ID不能为空或空字符串") | ||
25 | + @ApiModelProperty(value = "corn表达式") | ||
26 | + private String cronExpression; | ||
27 | + | ||
28 | + @NotEmpty(message = "任务中心名称不能为空或空字符串") | ||
29 | + @ApiModelProperty(value = "任务中心名称") | ||
30 | + private String name; | ||
31 | + | ||
32 | + @NotNull(message = "执行列表不能为空") | ||
33 | + @ApiModelProperty(value = "执行列表") | ||
34 | + private List<String> targetIds; | ||
35 | +} |
@@ -2,8 +2,12 @@ package org.thingsboard.server.common.data.yunteng.dto.task; | @@ -2,8 +2,12 @@ package org.thingsboard.server.common.data.yunteng.dto.task; | ||
2 | 2 | ||
3 | import io.swagger.annotations.ApiModelProperty; | 3 | import io.swagger.annotations.ApiModelProperty; |
4 | import lombok.Data; | 4 | import lombok.Data; |
5 | +import lombok.EqualsAndHashCode; | ||
5 | import org.thingsboard.server.common.data.yunteng.dto.BaseDTO; | 6 | import org.thingsboard.server.common.data.yunteng.dto.BaseDTO; |
6 | 7 | ||
8 | +import java.time.LocalDateTime; | ||
9 | + | ||
10 | +@EqualsAndHashCode(callSuper = true) | ||
7 | @Data | 11 | @Data |
8 | public class TkDeviceTaskCenterDTO extends BaseDTO { | 12 | public class TkDeviceTaskCenterDTO extends BaseDTO { |
9 | @ApiModelProperty(value = "设备ID") | 13 | @ApiModelProperty(value = "设备ID") |
@@ -15,6 +19,9 @@ public class TkDeviceTaskCenterDTO extends BaseDTO { | @@ -15,6 +19,9 @@ public class TkDeviceTaskCenterDTO extends BaseDTO { | ||
15 | @ApiModelProperty(value = "是否允许执行:0不执行 1允许执行") | 19 | @ApiModelProperty(value = "是否允许执行:0不执行 1允许执行") |
16 | private Integer allowState; | 20 | private Integer allowState; |
17 | 21 | ||
22 | + @ApiModelProperty(value = "最新执行时间") | ||
23 | + private LocalDateTime lastExecuteTime; | ||
24 | + | ||
18 | @ApiModelProperty(value = "租户ID") | 25 | @ApiModelProperty(value = "租户ID") |
19 | private String tenantId; | 26 | private String tenantId; |
20 | } | 27 | } |
@@ -5,15 +5,14 @@ import lombok.Data; | @@ -5,15 +5,14 @@ import lombok.Data; | ||
5 | import lombok.EqualsAndHashCode; | 5 | import lombok.EqualsAndHashCode; |
6 | import org.thingsboard.server.common.data.yunteng.constant.ModelConstants; | 6 | import org.thingsboard.server.common.data.yunteng.constant.ModelConstants; |
7 | 7 | ||
8 | +import java.time.LocalDateTime; | ||
9 | + | ||
8 | @EqualsAndHashCode(callSuper = true) | 10 | @EqualsAndHashCode(callSuper = true) |
9 | @Data | 11 | @Data |
10 | @TableName(value = ModelConstants.Table.TK_DEVICE_TASK_CENTER_NAME) | 12 | @TableName(value = ModelConstants.Table.TK_DEVICE_TASK_CENTER_NAME) |
11 | public class TkDeviceTaskCenterEntity extends TenantBaseEntity { | 13 | public class TkDeviceTaskCenterEntity extends TenantBaseEntity { |
12 | - | ||
13 | - private static final long serialVersionUID = -5425391296429906856L; | ||
14 | private String tbDeviceId; | 14 | private String tbDeviceId; |
15 | - | ||
16 | private String taskCenterId; | 15 | private String taskCenterId; |
17 | - | 16 | + private LocalDateTime lastExecuteTime; |
18 | private Integer allowState; | 17 | private Integer allowState; |
19 | } | 18 | } |
@@ -18,6 +18,7 @@ import org.thingsboard.server.common.data.yunteng.core.cache.CacheUtils; | @@ -18,6 +18,7 @@ import org.thingsboard.server.common.data.yunteng.core.cache.CacheUtils; | ||
18 | import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidationException; | 18 | import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidationException; |
19 | import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage; | 19 | import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage; |
20 | import org.thingsboard.server.common.data.yunteng.dto.*; | 20 | import org.thingsboard.server.common.data.yunteng.dto.*; |
21 | +import org.thingsboard.server.common.data.yunteng.dto.task.TkDeviceTaskCenterDTO; | ||
21 | import org.thingsboard.server.common.data.yunteng.enums.JobGroupEnum; | 22 | import org.thingsboard.server.common.data.yunteng.enums.JobGroupEnum; |
22 | import org.thingsboard.server.common.data.yunteng.enums.StatusEnum; | 23 | import org.thingsboard.server.common.data.yunteng.enums.StatusEnum; |
23 | import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData; | 24 | import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData; |
@@ -29,6 +30,7 @@ import org.thingsboard.server.dao.yunteng.mapper.SysJobMapper; | @@ -29,6 +30,7 @@ import org.thingsboard.server.dao.yunteng.mapper.SysJobMapper; | ||
29 | import org.thingsboard.server.dao.yunteng.service.*; | 30 | import org.thingsboard.server.dao.yunteng.service.*; |
30 | 31 | ||
31 | import javax.annotation.PostConstruct; | 32 | import javax.annotation.PostConstruct; |
33 | +import java.time.ZoneOffset; | ||
32 | import java.util.*; | 34 | import java.util.*; |
33 | import java.util.stream.Collectors; | 35 | import java.util.stream.Collectors; |
34 | 36 | ||
@@ -40,6 +42,8 @@ public class SysJobServiceImpl extends AbstractBaseService<SysJobMapper, SysJobE | @@ -40,6 +42,8 @@ public class SysJobServiceImpl extends AbstractBaseService<SysJobMapper, SysJobE | ||
40 | private final Scheduler scheduler; | 42 | private final Scheduler scheduler; |
41 | private final SysJobLogServiceImpl sysJobLogService; | 43 | private final SysJobLogServiceImpl sysJobLogService; |
42 | private final CacheUtils cacheUtils; | 44 | private final CacheUtils cacheUtils; |
45 | + private final TkDeviceTaskCenterService tkDeviceTaskCenterService; | ||
46 | + private static final String cacheName = FastIotConstants.CacheConfigKey.TASK_CENTER_INFOS; | ||
43 | /** 项目启动时,初始化定时器 主要是防止手动修改数据库导致未同步到定时任务处理(注:不能手动修改数据库ID和任务组名,否则会导致脏数据) */ | 47 | /** 项目启动时,初始化定时器 主要是防止手动修改数据库导致未同步到定时任务处理(注:不能手动修改数据库ID和任务组名,否则会导致脏数据) */ |
44 | @PostConstruct | 48 | @PostConstruct |
45 | public void init() throws SchedulerException { | 49 | public void init() throws SchedulerException { |
@@ -49,12 +53,13 @@ public class SysJobServiceImpl extends AbstractBaseService<SysJobMapper, SysJobE | @@ -49,12 +53,13 @@ public class SysJobServiceImpl extends AbstractBaseService<SysJobMapper, SysJobE | ||
49 | new ArrayList<>(baseMapper.selectList(new LambdaQueryWrapper<>())); | 53 | new ArrayList<>(baseMapper.selectList(new LambdaQueryWrapper<>())); |
50 | List<SysJobEntity> enableJobs = new ArrayList<>(); | 54 | List<SysJobEntity> enableJobs = new ArrayList<>(); |
51 | for (SysJobEntity job : jobList) { | 55 | for (SysJobEntity job : jobList) { |
52 | - if (Objects.equals(job.getStatus(),StatusEnum.ENABLE.getIndex())) { | 56 | + if (Objects.equals(job.getStatus(), StatusEnum.ENABLE.getIndex())) { |
53 | enableJobs.add(job); | 57 | enableJobs.add(job); |
54 | } | 58 | } |
55 | if (Objects.equals(job.getJobGroup(), JobGroupEnum.TASK_CENTER.name())) { | 59 | if (Objects.equals(job.getJobGroup(), JobGroupEnum.TASK_CENTER.name())) { |
56 | - // 查询任务中心的最新执行时间放在缓存里面 | ||
57 | - queryJobLastExecuteTime(job.getSourceId(), job.getId(), job.getJobGroup()); | 60 | + // 查询设备任务中心映射表的最新执行时间放入缓存 |
61 | + queryDeviceTaskCenterLastExecuteTime( | ||
62 | + job.getTenantId(), job.getSourceId(), job.getId(), job.getJobGroup()); | ||
58 | } | 63 | } |
59 | } | 64 | } |
60 | for (SysJobEntity job : enableJobs) { | 65 | for (SysJobEntity job : enableJobs) { |
@@ -261,6 +266,7 @@ public class SysJobServiceImpl extends AbstractBaseService<SysJobMapper, SysJobE | @@ -261,6 +266,7 @@ public class SysJobServiceImpl extends AbstractBaseService<SysJobMapper, SysJobE | ||
261 | SysJobEntity job = jobDTO.getEntity(SysJobEntity.class); | 266 | SysJobEntity job = jobDTO.getEntity(SysJobEntity.class); |
262 | baseMapper.insert(job); | 267 | baseMapper.insert(job); |
263 | ScheduleUtils.createScheduleJob(scheduler, job); | 268 | ScheduleUtils.createScheduleJob(scheduler, job); |
269 | + jobDTO.setId(job.getId()); | ||
264 | } else { | 270 | } else { |
265 | SysJobEntity job = baseMapper.selectById(jobDTO.getId()); | 271 | SysJobEntity job = baseMapper.selectById(jobDTO.getId()); |
266 | SysJobEntity newJob = jobDTO.getEntity(SysJobEntity.class); | 272 | SysJobEntity newJob = jobDTO.getEntity(SysJobEntity.class); |
@@ -318,7 +324,6 @@ public class SysJobServiceImpl extends AbstractBaseService<SysJobMapper, SysJobE | @@ -318,7 +324,6 @@ public class SysJobServiceImpl extends AbstractBaseService<SysJobMapper, SysJobE | ||
318 | new FutureCallback<>() { | 324 | new FutureCallback<>() { |
319 | @Override | 325 | @Override |
320 | public void onSuccess(@Nullable Long executeTime) { | 326 | public void onSuccess(@Nullable Long executeTime) { |
321 | - String cacheName = FastIotConstants.CacheConfigKey.TASK_CENTER_INFOS; | ||
322 | String key = FastIotConstants.CacheConfigKey.TASK_CENTER_EXECUTE_TIME + "_" + sourceId; | 327 | String key = FastIotConstants.CacheConfigKey.TASK_CENTER_EXECUTE_TIME + "_" + sourceId; |
323 | cacheUtils.put(cacheName, key, executeTime); | 328 | cacheUtils.put(cacheName, key, executeTime); |
324 | } | 329 | } |
@@ -328,4 +333,38 @@ public class SysJobServiceImpl extends AbstractBaseService<SysJobMapper, SysJobE | @@ -328,4 +333,38 @@ public class SysJobServiceImpl extends AbstractBaseService<SysJobMapper, SysJobE | ||
328 | }, | 333 | }, |
329 | MoreExecutors.directExecutor()); | 334 | MoreExecutors.directExecutor()); |
330 | } | 335 | } |
336 | + | ||
337 | + private void queryDeviceTaskCenterLastExecuteTime( | ||
338 | + String tenantId, String sourceId, String jobId, String JobGroup) { | ||
339 | + Futures.addCallback( | ||
340 | + tkDeviceTaskCenterService.findInfosByTaskCenterId(tenantId, sourceId), | ||
341 | + new FutureCallback<>() { | ||
342 | + @Override | ||
343 | + public void onSuccess(@Nullable List<TkDeviceTaskCenterDTO> tkDeviceTaskCenterDTOS) { | ||
344 | + if (null != tkDeviceTaskCenterDTOS && !tkDeviceTaskCenterDTOS.isEmpty()) { | ||
345 | + // 任务还存在,才查询任务中心的最新执行时间放入缓存 | ||
346 | + queryJobLastExecuteTime(sourceId, jobId, JobGroup); | ||
347 | + for (TkDeviceTaskCenterDTO tkDeviceTaskCenterDTO : tkDeviceTaskCenterDTOS) { | ||
348 | + String key = | ||
349 | + FastIotConstants.CacheConfigKey.TASK_CENTER_DEVICE_EXECUTE_TIME | ||
350 | + + "_" | ||
351 | + + tkDeviceTaskCenterDTO.getTbDeviceId(); | ||
352 | + if (null != tkDeviceTaskCenterDTO.getLastExecuteTime()) { | ||
353 | + cacheUtils.put( | ||
354 | + cacheName, | ||
355 | + key, | ||
356 | + tkDeviceTaskCenterDTO | ||
357 | + .getLastExecuteTime() | ||
358 | + .toInstant(ZoneOffset.of("+8")) | ||
359 | + .toEpochMilli()); | ||
360 | + } | ||
361 | + } | ||
362 | + } | ||
363 | + } | ||
364 | + | ||
365 | + @Override | ||
366 | + public void onFailure(@NotNull Throwable throwable) {} | ||
367 | + }, | ||
368 | + MoreExecutors.directExecutor()); | ||
369 | + } | ||
331 | } | 370 | } |
@@ -723,4 +723,19 @@ public class TkDeviceServiceImpl extends AbstractBaseService<DeviceMapper, TkDev | @@ -723,4 +723,19 @@ public class TkDeviceServiceImpl extends AbstractBaseService<DeviceMapper, TkDev | ||
723 | .map(list -> list.stream().map(TkDeviceEntity::getTbDeviceId).collect(Collectors.toList())) | 723 | .map(list -> list.stream().map(TkDeviceEntity::getTbDeviceId).collect(Collectors.toList())) |
724 | .orElse(null); | 724 | .orElse(null); |
725 | } | 725 | } |
726 | + | ||
727 | + @Override | ||
728 | + public List<DeviceDTO> findDeviceInfoByTbDeviceIds(List<String> tbDeviceIds, String tenantId) { | ||
729 | + if (StringUtils.isEmpty(tenantId) || null == tbDeviceIds || tbDeviceIds.isEmpty()) { | ||
730 | + throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage()); | ||
731 | + } | ||
732 | + return baseMapper | ||
733 | + .selectList( | ||
734 | + new LambdaQueryWrapper<TkDeviceEntity>() | ||
735 | + .eq(TkDeviceEntity::getTenantId, tenantId) | ||
736 | + .in(TkDeviceEntity::getTbDeviceId, tbDeviceIds)) | ||
737 | + .stream() | ||
738 | + .map(entity -> entity.getDTO(DeviceDTO.class)) | ||
739 | + .collect(Collectors.toList()); | ||
740 | + } | ||
726 | } | 741 | } |
1 | package org.thingsboard.server.dao.yunteng.impl; | 1 | package org.thingsboard.server.dao.yunteng.impl; |
2 | 2 | ||
3 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | 3 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
4 | +import com.google.common.util.concurrent.Futures; | ||
5 | +import com.google.common.util.concurrent.ListenableFuture; | ||
4 | import lombok.RequiredArgsConstructor; | 6 | import lombok.RequiredArgsConstructor; |
7 | +import lombok.extern.slf4j.Slf4j; | ||
5 | import org.springframework.stereotype.Service; | 8 | import org.springframework.stereotype.Service; |
6 | import org.springframework.transaction.annotation.Transactional; | 9 | import org.springframework.transaction.annotation.Transactional; |
7 | import org.thingsboard.server.common.data.StringUtils; | 10 | import org.thingsboard.server.common.data.StringUtils; |
8 | import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants; | 11 | import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants; |
9 | -import org.thingsboard.server.common.data.yunteng.dto.DeleteDTO; | 12 | +import org.thingsboard.server.common.data.yunteng.core.cache.CacheUtils; |
13 | +import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidationException; | ||
14 | +import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage; | ||
10 | import org.thingsboard.server.common.data.yunteng.dto.task.TkDeviceTaskCenterDTO; | 15 | import org.thingsboard.server.common.data.yunteng.dto.task.TkDeviceTaskCenterDTO; |
11 | import org.thingsboard.server.dao.yunteng.entities.TkDeviceTaskCenterEntity; | 16 | import org.thingsboard.server.dao.yunteng.entities.TkDeviceTaskCenterEntity; |
12 | import org.thingsboard.server.dao.yunteng.mapper.TkDeviceTaskCenterMapper; | 17 | import org.thingsboard.server.dao.yunteng.mapper.TkDeviceTaskCenterMapper; |
13 | import org.thingsboard.server.dao.yunteng.service.AbstractBaseService; | 18 | import org.thingsboard.server.dao.yunteng.service.AbstractBaseService; |
14 | import org.thingsboard.server.dao.yunteng.service.TkDeviceTaskCenterService; | 19 | import org.thingsboard.server.dao.yunteng.service.TkDeviceTaskCenterService; |
20 | + | ||
15 | import java.util.List; | 21 | import java.util.List; |
22 | +import java.util.Optional; | ||
23 | +import java.util.stream.Collectors; | ||
16 | 24 | ||
17 | @Service | 25 | @Service |
18 | @RequiredArgsConstructor | 26 | @RequiredArgsConstructor |
27 | +@Slf4j | ||
19 | public class TkDeviceTaskCenterServiceImpl | 28 | public class TkDeviceTaskCenterServiceImpl |
20 | extends AbstractBaseService<TkDeviceTaskCenterMapper, TkDeviceTaskCenterEntity> | 29 | extends AbstractBaseService<TkDeviceTaskCenterMapper, TkDeviceTaskCenterEntity> |
21 | implements TkDeviceTaskCenterService { | 30 | implements TkDeviceTaskCenterService { |
31 | + private final CacheUtils cacheUtils; | ||
32 | + | ||
22 | @Override | 33 | @Override |
23 | @Transactional | 34 | @Transactional |
24 | public TkDeviceTaskCenterDTO saveOrUpdate(TkDeviceTaskCenterDTO tkDeviceTaskCenterDTO) { | 35 | public TkDeviceTaskCenterDTO saveOrUpdate(TkDeviceTaskCenterDTO tkDeviceTaskCenterDTO) { |
@@ -34,11 +45,6 @@ public class TkDeviceTaskCenterServiceImpl | @@ -34,11 +45,6 @@ public class TkDeviceTaskCenterServiceImpl | ||
34 | 45 | ||
35 | @Override | 46 | @Override |
36 | @Transactional | 47 | @Transactional |
37 | - public boolean delete(DeleteDTO delete) { | ||
38 | - return baseMapper.deleteBatchIds(delete.getIds()) > FastIotConstants.MagicNumber.ZERO; | ||
39 | - } | ||
40 | - | ||
41 | - @Override | ||
42 | public boolean updateStateByTbDeviceIdAndTaskCenterId( | 48 | public boolean updateStateByTbDeviceIdAndTaskCenterId( |
43 | String tenantId, String taskCenterId, String tbDeviceId, Integer state) { | 49 | String tenantId, String taskCenterId, String tbDeviceId, Integer state) { |
44 | TkDeviceTaskCenterEntity entity = | 50 | TkDeviceTaskCenterEntity entity = |
@@ -55,7 +61,19 @@ public class TkDeviceTaskCenterServiceImpl | @@ -55,7 +61,19 @@ public class TkDeviceTaskCenterServiceImpl | ||
55 | } | 61 | } |
56 | 62 | ||
57 | @Override | 63 | @Override |
64 | + @Transactional | ||
58 | public boolean deleteByTaskCenterId(String tenantId, String taskCenterId) { | 65 | public boolean deleteByTaskCenterId(String tenantId, String taskCenterId) { |
66 | + List<TkDeviceTaskCenterDTO> list = getInfosByTaskCenterId(tenantId, taskCenterId); | ||
67 | + if (null != list && !list.isEmpty()) { | ||
68 | + for (TkDeviceTaskCenterDTO tkDeviceTaskCenterDTO : list) { | ||
69 | + String cacheName = FastIotConstants.CacheConfigKey.TASK_CENTER_INFOS; | ||
70 | + String key = | ||
71 | + FastIotConstants.CacheConfigKey.TASK_CENTER_DEVICE_EXECUTE_TIME | ||
72 | + + "_" | ||
73 | + + tkDeviceTaskCenterDTO.getTbDeviceId(); | ||
74 | + cacheUtils.invalidate(cacheName, key); | ||
75 | + } | ||
76 | + } | ||
59 | return baseMapper.delete( | 77 | return baseMapper.delete( |
60 | new LambdaQueryWrapper<TkDeviceTaskCenterEntity>() | 78 | new LambdaQueryWrapper<TkDeviceTaskCenterEntity>() |
61 | .eq(TkDeviceTaskCenterEntity::getTenantId, tenantId) | 79 | .eq(TkDeviceTaskCenterEntity::getTenantId, tenantId) |
@@ -68,4 +86,47 @@ public class TkDeviceTaskCenterServiceImpl | @@ -68,4 +86,47 @@ public class TkDeviceTaskCenterServiceImpl | ||
68 | public boolean insertBatch(List<TkDeviceTaskCenterEntity> list) { | 86 | public boolean insertBatch(List<TkDeviceTaskCenterEntity> list) { |
69 | return insertBatch(list, list.size()); | 87 | return insertBatch(list, list.size()); |
70 | } | 88 | } |
89 | + | ||
90 | + @Override | ||
91 | + public TkDeviceTaskCenterDTO findInfoByDeviceIdAndTaskCenterId( | ||
92 | + String tenantId, String tbDeviceId, String taskCenterId) { | ||
93 | + if (StringUtils.isEmpty(taskCenterId) | ||
94 | + || StringUtils.isEmpty(tbDeviceId) | ||
95 | + || StringUtils.isEmpty(tenantId)) { | ||
96 | + throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage()); | ||
97 | + } | ||
98 | + TkDeviceTaskCenterEntity entity = | ||
99 | + baseMapper.selectOne( | ||
100 | + new LambdaQueryWrapper<TkDeviceTaskCenterEntity>() | ||
101 | + .eq(TkDeviceTaskCenterEntity::getTenantId, tenantId) | ||
102 | + .eq(TkDeviceTaskCenterEntity::getTbDeviceId, tbDeviceId) | ||
103 | + .eq(TkDeviceTaskCenterEntity::getTaskCenterId, taskCenterId)); | ||
104 | + return Optional.ofNullable(entity) | ||
105 | + .map(obj -> obj.getDTO(TkDeviceTaskCenterDTO.class)) | ||
106 | + .orElse(null); | ||
107 | + } | ||
108 | + | ||
109 | + @Override | ||
110 | + public ListenableFuture<List<TkDeviceTaskCenterDTO>> findInfosByTaskCenterId( | ||
111 | + String tenantId, String taskCenterId) { | ||
112 | + return Futures.immediateFuture(getInfosByTaskCenterId(tenantId, taskCenterId)); | ||
113 | + } | ||
114 | + | ||
115 | + @Override | ||
116 | + public List<TkDeviceTaskCenterDTO> getInfosByTaskCenterId(String tenantId, String taskCenterId) { | ||
117 | + if (StringUtils.isEmpty(taskCenterId) || StringUtils.isEmpty(tenantId)) { | ||
118 | + throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage()); | ||
119 | + } | ||
120 | + List<TkDeviceTaskCenterEntity> entityList = | ||
121 | + baseMapper.selectList( | ||
122 | + new LambdaQueryWrapper<TkDeviceTaskCenterEntity>() | ||
123 | + .eq(TkDeviceTaskCenterEntity::getTenantId, tenantId) | ||
124 | + .eq(TkDeviceTaskCenterEntity::getTaskCenterId, taskCenterId)); | ||
125 | + if (null != entityList && !entityList.isEmpty()) { | ||
126 | + return entityList.stream() | ||
127 | + .map(entity -> entity.getDTO(TkDeviceTaskCenterDTO.class)) | ||
128 | + .collect(Collectors.toList()); | ||
129 | + } | ||
130 | + return null; | ||
131 | + } | ||
71 | } | 132 | } |
@@ -42,6 +42,7 @@ public class TkTaskCenterServiceImpl | @@ -42,6 +42,7 @@ public class TkTaskCenterServiceImpl | ||
42 | private final TkDeviceService tkDeviceService; | 42 | private final TkDeviceService tkDeviceService; |
43 | private final CacheUtils cacheUtils; | 43 | private final CacheUtils cacheUtils; |
44 | private final TkDeviceTaskCenterService tkDeviceTaskCenterService; | 44 | private final TkDeviceTaskCenterService tkDeviceTaskCenterService; |
45 | + private static final String cacheName = FastIotConstants.CacheConfigKey.TASK_CENTER_INFOS; | ||
45 | 46 | ||
46 | @Override | 47 | @Override |
47 | public TkPageData<TkTaskCenterDTO> taskCenterPage(Map<String, Object> queryMap, String tenantId) { | 48 | public TkPageData<TkTaskCenterDTO> taskCenterPage(Map<String, Object> queryMap, String tenantId) { |
@@ -50,17 +51,29 @@ public class TkTaskCenterServiceImpl | @@ -50,17 +51,29 @@ public class TkTaskCenterServiceImpl | ||
50 | getPage(queryMap, FastIotConstants.DefaultOrder.CREATE_TIME, false); | 51 | getPage(queryMap, FastIotConstants.DefaultOrder.CREATE_TIME, false); |
51 | IPage<TkTaskCenterDTO> iPage = baseMapper.getPageData(page, queryMap); | 52 | IPage<TkTaskCenterDTO> iPage = baseMapper.getPageData(page, queryMap); |
52 | if (!iPage.getRecords().isEmpty()) { | 53 | if (!iPage.getRecords().isEmpty()) { |
53 | - iPage.setRecords(iPage.getRecords().stream() | ||
54 | - .map( | ||
55 | - obj -> { | ||
56 | - String cacheName = FastIotConstants.CacheConfigKey.TASK_CENTER_INFOS; | ||
57 | - String key = | ||
58 | - FastIotConstants.CacheConfigKey.TASK_CENTER_EXECUTE_TIME + "_" + obj.getId(); | ||
59 | - Optional<Long> lastExecuteTime = cacheUtils.get(cacheName, key); | ||
60 | - lastExecuteTime.ifPresent(obj::setLastExecuteTime); | ||
61 | - return obj; | ||
62 | - }) | ||
63 | - .collect(Collectors.toList())); | 54 | + iPage.setRecords( |
55 | + iPage.getRecords().stream() | ||
56 | + .map( | ||
57 | + obj -> { | ||
58 | + // 任务执行时间 | ||
59 | + String key = | ||
60 | + FastIotConstants.CacheConfigKey.TASK_CENTER_EXECUTE_TIME | ||
61 | + + "_" | ||
62 | + + obj.getId(); | ||
63 | + | ||
64 | + // 如果通过设备查询分页,以设备执行时间为准 | ||
65 | + String tbDeviceId = (String) queryMap.get("tbDeviceId"); | ||
66 | + if (null != tbDeviceId) { | ||
67 | + key = | ||
68 | + FastIotConstants.CacheConfigKey.TASK_CENTER_DEVICE_EXECUTE_TIME | ||
69 | + + "_" | ||
70 | + + tbDeviceId; | ||
71 | + } | ||
72 | + Optional<Long> lastExecuteTime = cacheUtils.get(cacheName, key); | ||
73 | + lastExecuteTime.ifPresent(obj::setLastExecuteTime); | ||
74 | + return obj; | ||
75 | + }) | ||
76 | + .collect(Collectors.toList())); | ||
64 | } | 77 | } |
65 | return new TkPageData<>(iPage.getRecords(), iPage.getTotal()); | 78 | return new TkPageData<>(iPage.getRecords(), iPage.getTotal()); |
66 | } | 79 | } |
@@ -85,7 +98,8 @@ public class TkTaskCenterServiceImpl | @@ -85,7 +98,8 @@ public class TkTaskCenterServiceImpl | ||
85 | JacksonUtil.convertValue(tkTaskCenterDTO.getExecuteTarget(), JsonNode.class)); | 98 | JacksonUtil.convertValue(tkTaskCenterDTO.getExecuteTarget(), JsonNode.class)); |
86 | entity.setExecuteTime( | 99 | entity.setExecuteTime( |
87 | JacksonUtil.convertValue(tkTaskCenterDTO.getExecuteTime(), JsonNode.class)); | 100 | JacksonUtil.convertValue(tkTaskCenterDTO.getExecuteTime(), JsonNode.class)); |
88 | - if (StringUtils.isEmpty(tkTaskCenterDTO.getId())) { | 101 | + boolean isUpdate = !StringUtils.isEmpty(tkTaskCenterDTO.getId()); |
102 | + if (!isUpdate) { | ||
89 | entity.setState(FastIotConstants.StateValue.DISABLE); | 103 | entity.setState(FastIotConstants.StateValue.DISABLE); |
90 | baseMapper.insert(entity); | 104 | baseMapper.insert(entity); |
91 | } else { | 105 | } else { |
@@ -99,7 +113,7 @@ public class TkTaskCenterServiceImpl | @@ -99,7 +113,7 @@ public class TkTaskCenterServiceImpl | ||
99 | baseMapper.updateById(entity); | 113 | baseMapper.updateById(entity); |
100 | updateTaskCenterCache(entity); | 114 | updateTaskCenterCache(entity); |
101 | } | 115 | } |
102 | - saveOrUpdateDeviceTaskCenter(tkTaskCenterDTO); | 116 | + saveOrUpdateDeviceTaskCenter(entity, isUpdate); |
103 | return tkTaskCenterDTO; | 117 | return tkTaskCenterDTO; |
104 | } | 118 | } |
105 | 119 | ||
@@ -125,18 +139,20 @@ public class TkTaskCenterServiceImpl | @@ -125,18 +139,20 @@ public class TkTaskCenterServiceImpl | ||
125 | } | 139 | } |
126 | sourceIds.add(entity.getId()); | 140 | sourceIds.add(entity.getId()); |
127 | } | 141 | } |
142 | + for (String taskCenterId : sourceIds) { | ||
143 | + tkDeviceTaskCenterService.deleteByTaskCenterId(tenantId, taskCenterId); | ||
144 | + } | ||
128 | int result = baseMapper.deleteBatchIds(sourceIds); | 145 | int result = baseMapper.deleteBatchIds(sourceIds); |
129 | if (result > FastIotConstants.MagicNumber.ZERO) { | 146 | if (result > FastIotConstants.MagicNumber.ZERO) { |
147 | + // 移除任务中心缓存 | ||
130 | for (String taskCenterId : sourceIds) { | 148 | for (String taskCenterId : sourceIds) { |
131 | - tkDeviceTaskCenterService.deleteByTaskCenterId(tenantId, taskCenterId); | 149 | + String cacheName = FastIotConstants.CacheConfigKey.TASK_CENTER_INFOS; |
150 | + cacheUtils.invalidate( | ||
151 | + cacheName, | ||
152 | + FastIotConstants.CacheConfigKey.TASK_CENTER_EXECUTE_TIME + "_" + taskCenterId); | ||
132 | } | 153 | } |
133 | return tkSysJobService.deleteJobs(sourceIds, JobGroupEnum.TASK_CENTER.name(), tenantId); | 154 | return tkSysJobService.deleteJobs(sourceIds, JobGroupEnum.TASK_CENTER.name(), tenantId); |
134 | } | 155 | } |
135 | - // 移除任务中心缓存 | ||
136 | - for (String taskCenterId : sourceIds) { | ||
137 | - String cacheName = FastIotConstants.CacheConfigKey.TASK_CENTER_INFOS; | ||
138 | - cacheUtils.invalidate(cacheName, taskCenterId); | ||
139 | - } | ||
140 | return false; | 156 | return false; |
141 | } | 157 | } |
142 | 158 | ||
@@ -211,7 +227,7 @@ public class TkTaskCenterServiceImpl | @@ -211,7 +227,7 @@ public class TkTaskCenterServiceImpl | ||
211 | String sourceId = entity.getId(); | 227 | String sourceId = entity.getId(); |
212 | SysJobDTO queryJob = tkSysJobService.findSysJobBySourceId(sourceId); | 228 | SysJobDTO queryJob = tkSysJobService.findSysJobBySourceId(sourceId); |
213 | TaskExecuteTimeDTO executeTime = | 229 | TaskExecuteTimeDTO executeTime = |
214 | - JacksonUtil.convertValue(entity.getExecuteTime(), TaskExecuteTimeDTO.class); | 230 | + JacksonUtil.convertValue(entity.getExecuteTime(), TaskExecuteTimeDTO.class); |
215 | if (null == executeTime || StringUtils.isEmpty(executeTime.getCron())) { | 231 | if (null == executeTime || StringUtils.isEmpty(executeTime.getCron())) { |
216 | throw new TkDataValidationException(ErrorMessage.CRON_INVALID.getMessage()); | 232 | throw new TkDataValidationException(ErrorMessage.CRON_INVALID.getMessage()); |
217 | } | 233 | } |
@@ -276,6 +292,29 @@ public class TkTaskCenterServiceImpl | @@ -276,6 +292,29 @@ public class TkTaskCenterServiceImpl | ||
276 | return result; | 292 | return result; |
277 | } | 293 | } |
278 | 294 | ||
295 | + @Override | ||
296 | + public boolean immediateExecute(TaskImmediateExecuteDTO immediateExecuteDTO, String tenantId) | ||
297 | + throws SchedulerException { | ||
298 | + // 放入缓存 | ||
299 | + String taskCenterId = immediateExecuteDTO.getId(); | ||
300 | + String key = FastIotConstants.CacheConfigKey.TASK_IMMEDIATE_EXECUTE + "_" + taskCenterId; | ||
301 | + cacheUtils.put(cacheName, key, immediateExecuteDTO); | ||
302 | + // 直接调用任务中心任务执行 | ||
303 | + SysJobDTO sysJobDTO = tkSysJobService.findSysJobBySourceId(taskCenterId); | ||
304 | + if (null == sysJobDTO) { | ||
305 | + sysJobDTO = new SysJobDTO(); | ||
306 | + sysJobDTO.setSourceId(taskCenterId); | ||
307 | + sysJobDTO.setInvokeTarget("rpcCommandTask.process('" + taskCenterId + "')"); | ||
308 | + sysJobDTO.setJobGroup(JobGroupEnum.TASK_CENTER.name()); | ||
309 | + sysJobDTO.setTenantId(tenantId); | ||
310 | + sysJobDTO.setCronExpression(immediateExecuteDTO.getCronExpression()); | ||
311 | + sysJobDTO.setJobName(immediateExecuteDTO.getName()); | ||
312 | + sysJobDTO.setStatus(StatusEnum.DISABLE.getIndex()); | ||
313 | + tkSysJobService.saveOrUpdateJob(sysJobDTO); | ||
314 | + } | ||
315 | + return tkSysJobService.run(sysJobDTO); | ||
316 | + } | ||
317 | + | ||
279 | private void updateTaskCenterCache(TkTaskCenterEntity entity) { | 318 | private void updateTaskCenterCache(TkTaskCenterEntity entity) { |
280 | String cacheName = FastIotConstants.CacheConfigKey.TASK_CENTER_INFOS; | 319 | String cacheName = FastIotConstants.CacheConfigKey.TASK_CENTER_INFOS; |
281 | Optional<TkTaskCenterEntity> entityCache = cacheUtils.get(cacheName, entity.getId()); | 320 | Optional<TkTaskCenterEntity> entityCache = cacheUtils.get(cacheName, entity.getId()); |
@@ -284,13 +323,15 @@ public class TkTaskCenterServiceImpl | @@ -284,13 +323,15 @@ public class TkTaskCenterServiceImpl | ||
284 | } | 323 | } |
285 | } | 324 | } |
286 | 325 | ||
287 | - private void saveOrUpdateDeviceTaskCenter(TkTaskCenterDTO tkTaskCenter) { | ||
288 | - String taskCenterId = tkTaskCenter.getId(); | ||
289 | - String tenantId = tkTaskCenter.getTenantId(); | 326 | + private void saveOrUpdateDeviceTaskCenter(TkTaskCenterEntity entity, boolean isUpdate) { |
327 | + String taskCenterId = entity.getId(); | ||
328 | + String tenantId = entity.getTenantId(); | ||
290 | // 判断是按产品执行还是按设备执行 | 329 | // 判断是按产品执行还是按设备执行 |
291 | - List<String> data = tkTaskCenter.getExecuteTarget().getData(); | ||
292 | - boolean isUpdate = !StringUtils.isEmpty(taskCenterId); | ||
293 | - if (Objects.equals(tkTaskCenter.getTargetType(), TargetTypeEnum.DEVICES)) { | 330 | + List<String> data = |
331 | + Objects.requireNonNull( | ||
332 | + JacksonUtil.convertValue(entity.getExecuteTarget(), TargetContentDTO.class)) | ||
333 | + .getData(); | ||
334 | + if (Objects.equals(entity.getTargetType(), TargetTypeEnum.DEVICES)) { | ||
294 | processDeviceTaskCenterMapping(isUpdate, tenantId, taskCenterId, data); | 335 | processDeviceTaskCenterMapping(isUpdate, tenantId, taskCenterId, data); |
295 | } else { | 336 | } else { |
296 | for (String key : data) { | 337 | for (String key : data) { |
@@ -88,13 +88,14 @@ public interface TkDeviceService extends BaseService<TkDeviceEntity> { | @@ -88,13 +88,14 @@ public interface TkDeviceService extends BaseService<TkDeviceEntity> { | ||
88 | * | 88 | * |
89 | * @param tbDeviceId TB设备主键 | 89 | * @param tbDeviceId TB设备主键 |
90 | * @param created 告警状态:0正常,1告警 | 90 | * @param created 告警状态:0正常,1告警 |
91 | + * @return true成功 false失败 | ||
91 | */ | 92 | */ |
92 | boolean freshAlarmStatus(EntityId tbDeviceId, Integer created); | 93 | boolean freshAlarmStatus(EntityId tbDeviceId, Integer created); |
93 | 94 | ||
94 | /** | 95 | /** |
95 | * 自动生成设备SN | 96 | * 自动生成设备SN |
96 | * | 97 | * |
97 | - * @return | 98 | + * @return 设备SN |
98 | */ | 99 | */ |
99 | String generateSn(); | 100 | String generateSn(); |
100 | 101 | ||
@@ -103,7 +104,7 @@ public interface TkDeviceService extends BaseService<TkDeviceEntity> { | @@ -103,7 +104,7 @@ public interface TkDeviceService extends BaseService<TkDeviceEntity> { | ||
103 | * | 104 | * |
104 | * @param deviceId 平台设备ID | 105 | * @param deviceId 平台设备ID |
105 | * @param tenantId 租户ID | 106 | * @param tenantId 租户ID |
106 | - * @return | 107 | + * @return 场景联动ID |
107 | */ | 108 | */ |
108 | String otherUsing(String deviceId, String tenantId); | 109 | String otherUsing(String deviceId, String tenantId); |
109 | 110 | ||
@@ -134,7 +135,7 @@ public interface TkDeviceService extends BaseService<TkDeviceEntity> { | @@ -134,7 +135,7 @@ public interface TkDeviceService extends BaseService<TkDeviceEntity> { | ||
134 | * @param tenantId 租户ID | 135 | * @param tenantId 租户ID |
135 | * @param masterId 网关设备的TB_ID | 136 | * @param masterId 网关设备的TB_ID |
136 | * @param deviceCode 网关子设备的标识符,例如:485协议的从设备地址码 | 137 | * @param deviceCode 网关子设备的标识符,例如:485协议的从设备地址码 |
137 | - * @return | 138 | + * @return 从设备信息 |
138 | */ | 139 | */ |
139 | DeviceDTO findSlaveDevice(String tenantId, String masterId, String deviceCode); | 140 | DeviceDTO findSlaveDevice(String tenantId, String masterId, String deviceCode); |
140 | 141 | ||
@@ -145,7 +146,7 @@ public interface TkDeviceService extends BaseService<TkDeviceEntity> { | @@ -145,7 +146,7 @@ public interface TkDeviceService extends BaseService<TkDeviceEntity> { | ||
145 | * @param customerId 客户ID | 146 | * @param customerId 客户ID |
146 | * @param organizationId 组织ID | 147 | * @param organizationId 组织ID |
147 | * @param deviceIds 设备ID | 148 | * @param deviceIds 设备ID |
148 | - * @return | 149 | + * @return 遥测属性列表 |
149 | */ | 150 | */ |
150 | List<String> findDeviceKeys( | 151 | List<String> findDeviceKeys( |
151 | String tenantId, String customerId, String organizationId, List<String> deviceIds); | 152 | String tenantId, String customerId, String organizationId, List<String> deviceIds); |
@@ -156,7 +157,7 @@ public interface TkDeviceService extends BaseService<TkDeviceEntity> { | @@ -156,7 +157,7 @@ public interface TkDeviceService extends BaseService<TkDeviceEntity> { | ||
156 | * @param slaveId 网关子设备TB平台的ID | 157 | * @param slaveId 网关子设备TB平台的ID |
157 | * @param slaveName 网关子设备TB平台的名称 | 158 | * @param slaveName 网关子设备TB平台的名称 |
158 | * @param gatewayId 网关设备TB平台的ID | 159 | * @param gatewayId 网关设备TB平台的ID |
159 | - * @return | 160 | + * @return true成功 false失败 |
160 | */ | 161 | */ |
161 | boolean saveSlaveDevice( | 162 | boolean saveSlaveDevice( |
162 | String slaveId, String slaveName, String tbProfileId, String gatewayId, Long createTime); | 163 | String slaveId, String slaveName, String tbProfileId, String gatewayId, Long createTime); |
@@ -212,4 +213,12 @@ public interface TkDeviceService extends BaseService<TkDeviceEntity> { | @@ -212,4 +213,12 @@ public interface TkDeviceService extends BaseService<TkDeviceEntity> { | ||
212 | * @return id集合 | 213 | * @return id集合 |
213 | */ | 214 | */ |
214 | List<String> findTbDeviceIdsByDeviceProfileId(String deviceProfileId,String tenantId); | 215 | List<String> findTbDeviceIdsByDeviceProfileId(String deviceProfileId,String tenantId); |
216 | + | ||
217 | + /** | ||
218 | + * 根据TB设备ID列表获取设备信息 | ||
219 | + * @param tbDeviceIds id列表 | ||
220 | + * @param tenantId 租户ID | ||
221 | + * @return 设备列表 | ||
222 | + */ | ||
223 | + List<DeviceDTO> findDeviceInfoByTbDeviceIds(List<String> tbDeviceIds,String tenantId); | ||
215 | } | 224 | } |
1 | package org.thingsboard.server.dao.yunteng.service; | 1 | package org.thingsboard.server.dao.yunteng.service; |
2 | 2 | ||
3 | -import org.thingsboard.server.common.data.yunteng.dto.DeleteDTO; | 3 | +import com.google.common.util.concurrent.ListenableFuture; |
4 | import org.thingsboard.server.common.data.yunteng.dto.task.TkDeviceTaskCenterDTO; | 4 | import org.thingsboard.server.common.data.yunteng.dto.task.TkDeviceTaskCenterDTO; |
5 | import org.thingsboard.server.dao.yunteng.entities.TkDeviceTaskCenterEntity; | 5 | import org.thingsboard.server.dao.yunteng.entities.TkDeviceTaskCenterEntity; |
6 | import java.util.List; | 6 | import java.util.List; |
@@ -15,30 +15,25 @@ public interface TkDeviceTaskCenterService { | @@ -15,30 +15,25 @@ public interface TkDeviceTaskCenterService { | ||
15 | TkDeviceTaskCenterDTO saveOrUpdate(TkDeviceTaskCenterDTO tkDeviceTaskCenterDTO); | 15 | TkDeviceTaskCenterDTO saveOrUpdate(TkDeviceTaskCenterDTO tkDeviceTaskCenterDTO); |
16 | 16 | ||
17 | /** | 17 | /** |
18 | - * 删除设备与任务中心的映射关系 | ||
19 | - * | ||
20 | - * @param delete 删除参数 | ||
21 | - * @return true成功 false失败 | ||
22 | - */ | ||
23 | - boolean delete(DeleteDTO delete); | ||
24 | - | ||
25 | - /** | ||
26 | * 根据任务中心ID和设备ID更新状态 | 18 | * 根据任务中心ID和设备ID更新状态 |
19 | + * | ||
27 | * @param tenantId 租户ID | 20 | * @param tenantId 租户ID |
28 | * @param taskCenterId 任务重ID | 21 | * @param taskCenterId 任务重ID |
29 | * @param tbDeviceId 设备ID | 22 | * @param tbDeviceId 设备ID |
30 | * @param state 状态 | 23 | * @param state 状态 |
31 | * @return true成功 false失败 | 24 | * @return true成功 false失败 |
32 | */ | 25 | */ |
33 | - boolean updateStateByTbDeviceIdAndTaskCenterId(String tenantId,String taskCenterId,String tbDeviceId,Integer state); | 26 | + boolean updateStateByTbDeviceIdAndTaskCenterId( |
27 | + String tenantId, String taskCenterId, String tbDeviceId, Integer state); | ||
34 | 28 | ||
35 | /** | 29 | /** |
36 | * 通过任务ID删除所有的映射关系 | 30 | * 通过任务ID删除所有的映射关系 |
31 | + * | ||
37 | * @param tenantId 租户ID | 32 | * @param tenantId 租户ID |
38 | * @param taskCenterId 任务ID | 33 | * @param taskCenterId 任务ID |
39 | * @return true成功 false失败 | 34 | * @return true成功 false失败 |
40 | */ | 35 | */ |
41 | - boolean deleteByTaskCenterId(String tenantId,String taskCenterId); | 36 | + boolean deleteByTaskCenterId(String tenantId, String taskCenterId); |
42 | 37 | ||
43 | /** | 38 | /** |
44 | * 批量插入 | 39 | * 批量插入 |
@@ -47,4 +42,27 @@ public interface TkDeviceTaskCenterService { | @@ -47,4 +42,27 @@ public interface TkDeviceTaskCenterService { | ||
47 | * @return true成功 false失败 | 42 | * @return true成功 false失败 |
48 | */ | 43 | */ |
49 | boolean insertBatch(List<TkDeviceTaskCenterEntity> list); | 44 | boolean insertBatch(List<TkDeviceTaskCenterEntity> list); |
45 | + | ||
46 | + /** | ||
47 | + * 根据任务中心ID和设备ID查询设备与任务中心映射关系 | ||
48 | + * | ||
49 | + * @param tenantId 租户ID | ||
50 | + * @param tbDeviceId 设备ID | ||
51 | + * @param taskCenterId 任务中心ID | ||
52 | + * @return 设备与任务中心映射关系 | ||
53 | + */ | ||
54 | + TkDeviceTaskCenterDTO findInfoByDeviceIdAndTaskCenterId( | ||
55 | + String tenantId, String tbDeviceId, String taskCenterId); | ||
56 | + | ||
57 | + /** | ||
58 | + * 根据任务中心的ID查询设备与任务中心的映射列表 | ||
59 | + * | ||
60 | + * @param tenantId 租户ID | ||
61 | + * @param taskCenterId 任务中心ID | ||
62 | + * @return 设备与任务中心映射关系列表 | ||
63 | + */ | ||
64 | + ListenableFuture<List<TkDeviceTaskCenterDTO>> findInfosByTaskCenterId( | ||
65 | + String tenantId, String taskCenterId); | ||
66 | + | ||
67 | + List<TkDeviceTaskCenterDTO> getInfosByTaskCenterId(String tenantId,String taskCenterId); | ||
50 | } | 68 | } |
@@ -3,6 +3,7 @@ package org.thingsboard.server.dao.yunteng.service; | @@ -3,6 +3,7 @@ package org.thingsboard.server.dao.yunteng.service; | ||
3 | import com.google.common.util.concurrent.ListenableFuture; | 3 | import com.google.common.util.concurrent.ListenableFuture; |
4 | import org.quartz.SchedulerException; | 4 | import org.quartz.SchedulerException; |
5 | import org.thingsboard.server.common.data.yunteng.dto.DeleteDTO; | 5 | import org.thingsboard.server.common.data.yunteng.dto.DeleteDTO; |
6 | +import org.thingsboard.server.common.data.yunteng.dto.task.TaskImmediateExecuteDTO; | ||
6 | import org.thingsboard.server.common.data.yunteng.dto.task.TkTaskCenterDTO; | 7 | import org.thingsboard.server.common.data.yunteng.dto.task.TkTaskCenterDTO; |
7 | import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData; | 8 | import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData; |
8 | import java.util.Map; | 9 | import java.util.Map; |
@@ -67,4 +68,14 @@ public interface TkTaskCenterService { | @@ -67,4 +68,14 @@ public interface TkTaskCenterService { | ||
67 | * @return true成功 false失败 | 68 | * @return true成功 false失败 |
68 | */ | 69 | */ |
69 | boolean cancelOrAllowExecute(String id, String tbDeviceId, String tenantId, boolean isAllow); | 70 | boolean cancelOrAllowExecute(String id, String tbDeviceId, String tenantId, boolean isAllow); |
71 | + | ||
72 | + /** | ||
73 | + * 立即执行任务 | ||
74 | + * | ||
75 | + * @param immediateExecuteDTO 执行信息 | ||
76 | + * @param tenantId 租户ID | ||
77 | + * @return ture成功 false失败 | ||
78 | + */ | ||
79 | + boolean immediateExecute(TaskImmediateExecuteDTO immediateExecuteDTO, String tenantId) | ||
80 | + throws SchedulerException; | ||
70 | } | 81 | } |