Browse Source

Merge branch 'v1.5.0'

What's new?
1. Add new model: DJI Matrices 350 RTK.
2. Update file hms.json.
3. Fixed some issues.
pull/35/head
sean.zhou 2 years ago
parent
commit
642dac3e70
  1. 2
      pom.xml
  2. 3
      sql/cloud_sample.sql
  3. 6
      src/main/java/com/dji/sample/component/redis/RedisConst.java
  4. 2
      src/main/java/com/dji/sample/component/websocket/service/impl/WebSocketManageServiceImpl.java
  5. 32
      src/main/java/com/dji/sample/manage/service/impl/DeviceServiceImpl.java
  6. 6
      src/main/java/com/dji/sample/wayline/model/dto/WaylineJobDTO.java
  7. 17
      src/main/java/com/dji/sample/wayline/model/dto/WaylineJobKey.java
  8. 6
      src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskCreateDTO.java
  9. 36
      src/main/java/com/dji/sample/wayline/service/IWaylineRedisService.java
  10. 249
      src/main/java/com/dji/sample/wayline/service/impl/FlightTaskServiceImpl.java
  11. 112
      src/main/java/com/dji/sample/wayline/service/impl/WaylineJobServiceImpl.java
  12. 27
      src/main/java/com/dji/sample/wayline/service/impl/WaylineRedisServiceImpl.java
  13. 20089
      src/main/resources/hms.json

2
pom.xml

@ -11,7 +11,7 @@
<groupId>com.dji</groupId> <groupId>com.dji</groupId>
<artifactId>cloud-api-sample</artifactId> <artifactId>cloud-api-sample</artifactId>
<version>1.4.0</version> <version>1.5.0</version>
<name>cloud-api-sample</name> <name>cloud-api-sample</name>
<properties> <properties>

3
sql/cloud_sample.sql

@ -134,7 +134,8 @@ VALUES
(22,1,67,0,'Mavic 3T Camera',NULL), (22,1,67,0,'Mavic 3T Camera',NULL),
(23,2,144,0,'DJI RC Pro','Remote control for Mavic 3E/T and Mavic 3M'), (23,2,144,0,'DJI RC Pro','Remote control for Mavic 3E/T and Mavic 3M'),
(24,0,77,2,'Mavic 3M',NULL), (24,0,77,2,'Mavic 3M',NULL),
(25,1,68,0,'Mavic 3M Camera',NULL); (25,1,68,0,'Mavic 3M Camera',NULL),
(26,0,89,0,'Matrice 350 RTK',NULL);
/*!40000 ALTER TABLE `manage_device_dictionary` ENABLE KEYS */; /*!40000 ALTER TABLE `manage_device_dictionary` ENABLE KEYS */;
UNLOCK TABLES; UNLOCK TABLES;

6
src/main/java/com/dji/sample/component/redis/RedisConst.java

@ -37,11 +37,9 @@ public final class RedisConst {
public static final String LOGS_FILE_PREFIX = "logs_file" + DELIMITER; public static final String LOGS_FILE_PREFIX = "logs_file" + DELIMITER;
public static final String WAYLINE_JOB_TIMED_EXECUTE = "wayline_job_timed_execute"; public static final String WAYLINE_JOB_PREPARED = "wayline_job_prepared";
public static final String WAYLINE_JOB_CONDITION_PREPARE = "wayline_job_condition_prepare"; public static final String WAYLINE_JOB_CONDITION_PREFIX = "wayline_job_condition" + DELIMITER;
public static final String WAYLINE_JOB_CONDITION_PREFIX = WAYLINE_JOB_CONDITION_PREPARE + DELIMITER;
public static final String WAYLINE_JOB_BLOCK_PREFIX = "wayline_job_block" + DELIMITER; public static final String WAYLINE_JOB_BLOCK_PREFIX = "wayline_job_block" + DELIMITER;

2
src/main/java/com/dji/sample/component/websocket/service/impl/WebSocketManageServiceImpl.java

@ -75,7 +75,7 @@ public class WebSocketManageServiceImpl implements IWebSocketManageService {
return RedisOpsUtils.hashKeys(key) return RedisOpsUtils.hashKeys(key)
.stream() .stream()
.map(SESSIONS::get) .map(SESSIONS::get)
.filter(Objects::nonNull) .filter(this.getValueWithWorkspace(workspaceId)::contains)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
} }

32
src/main/java/com/dji/sample/manage/service/impl/DeviceServiceImpl.java

@ -518,11 +518,39 @@ public class DeviceServiceImpl implements IDeviceService {
} }
entity.setId(deviceEntity.getId()); entity.setId(deviceEntity.getId());
mapper.updateById(entity); mapper.updateById(entity);
return Optional.of(deviceEntity); fillNullField(entity, deviceEntity);
return Optional.of(entity);
} }
return mapper.insert(entity) > 0 ? Optional.of(entity) : Optional.empty(); return mapper.insert(entity) > 0 ? Optional.of(entity) : Optional.empty();
} }
private void fillNullField(DeviceEntity entity, DeviceEntity oldEntity) {
if (Objects.isNull(entity) || Objects.isNull(oldEntity)) {
return;
}
if (Objects.isNull(entity.getWorkspaceId())) {
entity.setWorkspaceId(oldEntity.getWorkspaceId());
}
if (Objects.isNull(entity.getUserId())) {
entity.setUserId(oldEntity.getUserId());
}
if (Objects.isNull(entity.getChildSn())) {
entity.setChildSn(oldEntity.getChildSn());
}
if (Objects.isNull(entity.getBoundStatus())) {
entity.setBoundStatus(oldEntity.getBoundStatus());
}
if (Objects.isNull(entity.getBoundTime())) {
entity.setBoundTime(oldEntity.getBoundTime());
}
if (Objects.isNull(entity.getFirmwareVersion())) {
entity.setFirmwareVersion(oldEntity.getFirmwareVersion());
}
if (Objects.isNull(entity.getDeviceIndex())) {
entity.setDeviceIndex(oldEntity.getDeviceIndex());
}
}
/** /**
* Convert the received gateway device object into a database entity object. * Convert the received gateway device object into a database entity object.
* @param gateway * @param gateway
@ -650,7 +678,7 @@ public class DeviceServiceImpl implements IDeviceService {
return; return;
} }
if (entity.getFirmwareVersion().equals(firmwareReleaseNoteOpt.get().getProductVersion())) { if (entity.getFirmwareVersion().equals(firmwareReleaseNoteOpt.get().getProductVersion())) {
deviceDTO.setFirmwareStatus(entity.getCompatibleStatus() ? deviceDTO.setFirmwareStatus(Objects.requireNonNullElse(entity.getCompatibleStatus(), true) ?
DeviceFirmwareStatusEnum.NOT_UPGRADE.getVal() : DeviceFirmwareStatusEnum.NOT_UPGRADE.getVal() :
DeviceFirmwareStatusEnum.CONSISTENT_UPGRADE.getVal()); DeviceFirmwareStatusEnum.CONSISTENT_UPGRADE.getVal());
return; return;

6
src/main/java/com/dji/sample/wayline/model/dto/WaylineJobDTO.java

@ -1,5 +1,7 @@
package com.dji.sample.wayline.model.dto; package com.dji.sample.wayline.model.dto;
import com.dji.sample.wayline.model.enums.WaylineTaskTypeEnum;
import com.dji.sample.wayline.model.enums.WaylineTemplateTypeEnum;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
@ -32,9 +34,9 @@ public class WaylineJobDTO {
private String workspaceId; private String workspaceId;
private Integer waylineType; private WaylineTemplateTypeEnum waylineType;
private Integer taskType; private WaylineTaskTypeEnum taskType;
private LocalDateTime executeTime; private LocalDateTime executeTime;

17
src/main/java/com/dji/sample/wayline/model/dto/ConditionalWaylineJobKey.java → src/main/java/com/dji/sample/wayline/model/dto/WaylineJobKey.java

@ -3,15 +3,13 @@ package com.dji.sample.wayline.model.dto;
import com.dji.sample.component.redis.RedisConst; import com.dji.sample.component.redis.RedisConst;
import lombok.Data; import lombok.Data;
import java.util.Objects;
/** /**
* @author sean * @author sean
* @version 1.4 * @version 1.4
* @date 2023/3/28 * @date 2023/3/28
*/ */
@Data @Data
public class ConditionalWaylineJobKey { public class WaylineJobKey {
private String workspaceId; private String workspaceId;
@ -19,18 +17,17 @@ public class ConditionalWaylineJobKey {
private String jobId; private String jobId;
public ConditionalWaylineJobKey(String workspaceId, String dockSn, String jobId) { public WaylineJobKey(String workspaceId, String dockSn, String jobId) {
this.workspaceId = workspaceId; this.workspaceId = workspaceId;
this.dockSn = dockSn; this.dockSn = dockSn;
this.jobId = jobId; this.jobId = jobId;
} }
private WaylineJobKey(String[] keyArr) {
this(keyArr[0], keyArr[1], keyArr[2]);
}
public ConditionalWaylineJobKey(String key) { public WaylineJobKey(String key) {
if (Objects.isNull(key)) { this(key.split(RedisConst.DELIMITER));
return;
}
String[] keyArr = key.split(RedisConst.DELIMITER);
new ConditionalWaylineJobKey(keyArr[0], keyArr[1], keyArr[2]);
} }
public String getKey() { public String getKey() {

6
src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskCreateDTO.java

@ -1,5 +1,7 @@
package com.dji.sample.wayline.model.dto; package com.dji.sample.wayline.model.dto;
import com.dji.sample.wayline.model.enums.WaylineTaskTypeEnum;
import com.dji.sample.wayline.model.enums.WaylineTemplateTypeEnum;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
@ -18,9 +20,9 @@ public class WaylineTaskCreateDTO {
private String flightId; private String flightId;
private Integer taskType; private WaylineTaskTypeEnum taskType;
private Integer waylineType; private WaylineTemplateTypeEnum waylineType;
private Long executeTime; private Long executeTime;

36
src/main/java/com/dji/sample/wayline/service/IWaylineRedisService.java

@ -1,8 +1,8 @@
package com.dji.sample.wayline.service; package com.dji.sample.wayline.service;
import com.dji.sample.component.mqtt.model.EventsReceiver; import com.dji.sample.component.mqtt.model.EventsReceiver;
import com.dji.sample.wayline.model.dto.ConditionalWaylineJobKey;
import com.dji.sample.wayline.model.dto.WaylineJobDTO; import com.dji.sample.wayline.model.dto.WaylineJobDTO;
import com.dji.sample.wayline.model.dto.WaylineJobKey;
import com.dji.sample.wayline.model.dto.WaylineTaskProgressReceiver; import com.dji.sample.wayline.model.dto.WaylineTaskProgressReceiver;
import java.util.Optional; import java.util.Optional;
@ -70,6 +70,13 @@ public interface IWaylineRedisService {
*/ */
String getBlockedWaylineJobId(String dockSn); String getBlockedWaylineJobId(String dockSn);
/**
* Delete the wayline job id blocked by the dock in redis.
* @param dockSn
* @return
*/
Boolean delBlockedWaylineJobId(String dockSn);
/** /**
* Save the conditional wayline job by the dock to redis. * Save the conditional wayline job by the dock to redis.
* @param waylineJob * @param waylineJob
@ -90,11 +97,30 @@ public interface IWaylineRedisService {
*/ */
Boolean delConditionalWaylineJob(String jobId); Boolean delConditionalWaylineJob(String jobId);
Boolean addPrepareConditionalWaylineJob(WaylineJobDTO waylineJob); /**
* Add the wayline job that needs to be issued.
* @param waylineJob
* @return
*/
Boolean addPreparedWaylineJob(WaylineJobDTO waylineJob);
Optional<ConditionalWaylineJobKey> getNearestConditionalWaylineJob(); /**
* Get the latest wayline job that needs to be issued.
* @return
*/
Optional<WaylineJobKey> getNearestPreparedWaylineJob();
Double getConditionalWaylineJobTime(ConditionalWaylineJobKey jobKey); /**
* Get the time when the wayline job is issued.
* @param jobKey
* @return
*/
Double getPreparedWaylineJobTime(WaylineJobKey jobKey);
Boolean removePrepareConditionalWaylineJob(ConditionalWaylineJobKey jobKey); /**
* Delete the wayline job that needs to be issued in redis.
* @param jobKey
* @return
*/
Boolean removePreparedWaylineJob(WaylineJobKey jobKey);
} }

249
src/main/java/com/dji/sample/wayline/service/impl/FlightTaskServiceImpl.java

@ -12,10 +12,11 @@ import com.dji.sample.manage.model.dto.DeviceDTO;
import com.dji.sample.manage.model.enums.UserTypeEnum; import com.dji.sample.manage.model.enums.UserTypeEnum;
import com.dji.sample.manage.service.IDeviceRedisService; import com.dji.sample.manage.service.IDeviceRedisService;
import com.dji.sample.media.model.MediaFileCountDTO; import com.dji.sample.media.model.MediaFileCountDTO;
import com.dji.sample.wayline.model.dto.ConditionalWaylineJobKey;
import com.dji.sample.wayline.model.dto.WaylineJobDTO; import com.dji.sample.wayline.model.dto.WaylineJobDTO;
import com.dji.sample.wayline.model.dto.WaylineJobKey;
import com.dji.sample.wayline.model.dto.WaylineTaskProgressReceiver; import com.dji.sample.wayline.model.dto.WaylineTaskProgressReceiver;
import com.dji.sample.wayline.model.enums.WaylineJobStatusEnum; import com.dji.sample.wayline.model.enums.WaylineJobStatusEnum;
import com.dji.sample.wayline.model.enums.WaylineTaskTypeEnum;
import com.dji.sample.wayline.service.IFlightTaskService; import com.dji.sample.wayline.service.IFlightTaskService;
import com.dji.sample.wayline.service.IWaylineJobService; import com.dji.sample.wayline.service.IWaylineJobService;
import com.dji.sample.wayline.service.IWaylineRedisService; import com.dji.sample.wayline.service.IWaylineRedisService;
@ -25,7 +26,6 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpStatus; import org.apache.http.HttpStatus;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.annotation.ServiceActivator; import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.mqtt.support.MqttHeaders;
import org.springframework.messaging.MessageHeaders; import org.springframework.messaging.MessageHeaders;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -70,9 +70,6 @@ public class FlightTaskServiceImpl implements IFlightTaskService {
*/ */
@ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_FLIGHT_TASK_PROGRESS, outputChannel = ChannelName.OUTBOUND_EVENTS) @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_FLIGHT_TASK_PROGRESS, outputChannel = ChannelName.OUTBOUND_EVENTS)
public CommonTopicReceiver handleProgress(CommonTopicReceiver receiver, MessageHeaders headers) { public CommonTopicReceiver handleProgress(CommonTopicReceiver receiver, MessageHeaders headers) {
String receivedTopic = String.valueOf(headers.get(MqttHeaders.RECEIVED_TOPIC));
String dockSn = receivedTopic.substring((TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT).length(),
receivedTopic.indexOf(TopicConst.EVENTS_SUF));
EventsReceiver<WaylineTaskProgressReceiver> eventsReceiver = mapper.convertValue(receiver.getData(), EventsReceiver<WaylineTaskProgressReceiver> eventsReceiver = mapper.convertValue(receiver.getData(),
new TypeReference<EventsReceiver<WaylineTaskProgressReceiver>>(){}); new TypeReference<EventsReceiver<WaylineTaskProgressReceiver>>(){});
eventsReceiver.setBid(receiver.getBid()); eventsReceiver.setBid(receiver.getBid());
@ -87,42 +84,52 @@ public class FlightTaskServiceImpl implements IFlightTaskService {
} }
EventsResultStatusEnum statusEnum = EventsResultStatusEnum.find(output.getStatus()); EventsResultStatusEnum statusEnum = EventsResultStatusEnum.find(output.getStatus());
waylineRedisService.setRunningWaylineJob(dockSn, eventsReceiver); waylineRedisService.setRunningWaylineJob(receiver.getGateway(), eventsReceiver);
if (statusEnum.getEnd()) {
WaylineJobDTO job = WaylineJobDTO.builder()
.jobId(receiver.getBid())
.status(WaylineJobStatusEnum.SUCCESS.getVal())
.completedTime(LocalDateTime.now())
.mediaCount(output.getExt().getMediaCount())
.build();
// record the update of the media count.
if (Objects.nonNull(job.getMediaCount()) && job.getMediaCount() != 0) {
RedisOpsUtils.hashSet(RedisConst.MEDIA_FILE_PREFIX + receiver.getGateway(), job.getJobId(),
MediaFileCountDTO.builder().jobId(receiver.getBid()).mediaCount(job.getMediaCount()).uploadedCount(0).build());
}
if (EventsResultStatusEnum.OK != statusEnum) {
job.setCode(eventsReceiver.getResult());
job.setStatus(WaylineJobStatusEnum.FAILED.getVal());
}
waylineJobService.updateJob(job);
waylineRedisService.delRunningWaylineJob(dockSn);
waylineRedisService.delPausedWaylineJob(receiver.getBid());
}
Optional<DeviceDTO> deviceOpt = deviceRedisService.getDeviceOnline(receiver.getGateway()); Optional<DeviceDTO> deviceOpt = deviceRedisService.getDeviceOnline(receiver.getGateway());
if (deviceOpt.isEmpty()) { if (deviceOpt.isEmpty()) {
return null; return null;
} }
if (statusEnum.getEnd()) {
handleEndStatus(receiver, statusEnum, output.getExt().getMediaCount(), eventsReceiver.getResult(), deviceOpt.get());
}
websocketMessageService.sendBatch(deviceOpt.get().getWorkspaceId(), UserTypeEnum.WEB.getVal(), websocketMessageService.sendBatch(deviceOpt.get().getWorkspaceId(), UserTypeEnum.WEB.getVal(),
BizCodeEnum.FLIGHT_TASK_PROGRESS.getCode(), eventsReceiver); BizCodeEnum.FLIGHT_TASK_PROGRESS.getCode(), eventsReceiver);
return receiver; return receiver;
} }
private void handleEndStatus(CommonTopicReceiver receiver, EventsResultStatusEnum statusEnum, int mediaCount, int code, DeviceDTO dock) {
WaylineJobDTO job = WaylineJobDTO.builder()
.jobId(receiver.getBid())
.status(WaylineJobStatusEnum.SUCCESS.getVal())
.completedTime(LocalDateTime.now())
.mediaCount(mediaCount)
.build();
// record the update of the media count.
if (Objects.nonNull(job.getMediaCount()) && job.getMediaCount() != 0) {
RedisOpsUtils.hashSet(RedisConst.MEDIA_FILE_PREFIX + receiver.getGateway(), job.getJobId(),
MediaFileCountDTO.builder().jobId(receiver.getBid()).mediaCount(job.getMediaCount()).uploadedCount(0).build());
}
if (EventsResultStatusEnum.OK != statusEnum) {
job.setCode(code);
job.setStatus(WaylineJobStatusEnum.FAILED.getVal());
}
waylineRedisService.getConditionalWaylineJob(receiver.getBid()).ifPresent(waylineJob ->
retryPrepareConditionJob(new WaylineJobKey(dock.getWorkspaceId(), dock.getDeviceSn(), receiver.getBid()), waylineJob));
waylineJobService.updateJob(job);
waylineRedisService.delRunningWaylineJob(receiver.getGateway());
waylineRedisService.delPausedWaylineJob(receiver.getBid());
waylineRedisService.delBlockedWaylineJobId(receiver.getGateway());
}
/** /**
* Notifications will be received through this interface when tasks are ready on the device. * Notifications will be received through this interface when tasks are ready on the device.
* @param receiver * @param receiver
@ -130,106 +137,65 @@ public class FlightTaskServiceImpl implements IFlightTaskService {
*/ */
@ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_FLIGHT_TASK_READY, outputChannel = ChannelName.OUTBOUND_EVENTS) @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_FLIGHT_TASK_READY, outputChannel = ChannelName.OUTBOUND_EVENTS)
public CommonTopicReceiver handleTaskNotifications(CommonTopicReceiver receiver, MessageHeaders headers) { public CommonTopicReceiver handleTaskNotifications(CommonTopicReceiver receiver, MessageHeaders headers) {
String receivedTopic = String.valueOf(headers.get(MqttHeaders.RECEIVED_TOPIC)); String dockSn = receiver.getGateway();
String dockSn = receivedTopic.substring((TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT).length(), Set<String> flightIds = mapper.convertValue(receiver.getData(),
receivedTopic.indexOf(TopicConst.EVENTS_SUF)); new TypeReference<Map<String, Set<String>>>(){}).get(MapKeyConst.FLIGHT_IDS);
List<String> flightIds = mapper.convertValue(receiver.getData(),
new TypeReference<Map<String, List<String>>>(){}).get(MapKeyConst.FLIGHT_IDS);
log.info("ready task list:{}", Arrays.toString(flightIds.toArray()) ); log.info("ready task list:{}", Arrays.toString(flightIds.toArray()));
// Check conditional task blocking status. // Check conditional task blocking status.
String blockedId = waylineRedisService.getBlockedWaylineJobId(dockSn); String blockedId = waylineRedisService.getBlockedWaylineJobId(dockSn);
if (!StringUtils.hasText(blockedId)) { if (StringUtils.hasText(blockedId)) {
log.info("The dock is in a state of wayline congestion, and the task will not be executed.");
return null; return null;
} }
Optional<DeviceDTO> deviceOpt = deviceRedisService.getDeviceOnline(dockSn); Optional<DeviceDTO> deviceOpt = deviceRedisService.getDeviceOnline(dockSn);
if (deviceOpt.isEmpty()) { if (deviceOpt.isEmpty()) {
log.info("The dock is offline.");
return null; return null;
} }
DeviceDTO device = deviceOpt.get(); DeviceDTO device = deviceOpt.get();
Optional<WaylineJobDTO> jobOpt = waylineJobService.getJobsByConditions(device.getWorkspaceId(), flightIds, WaylineJobStatusEnum.PENDING)
try { .stream().filter(job -> flightIds.contains(job.getJobId()))
for (String jobId : flightIds) { .sorted(Comparator.comparingInt(a -> a.getTaskType().getVal()))
boolean isExecute = waylineJobService.executeFlightTask(device.getWorkspaceId(), jobId); .min(Comparator.comparing(WaylineJobDTO::getBeginTime));
if (!isExecute) { if (jobOpt.isEmpty()) {
return null; return receiver;
}
Optional<WaylineJobDTO> waylineJobOpt = waylineRedisService.getConditionalWaylineJob(jobId);
if (waylineJobOpt.isEmpty()) {
log.info("The conditional job has expired and will no longer be executed.");
return receiver;
}
WaylineJobDTO waylineJob = waylineJobOpt.get();
this.retryPrepareJob(new ConditionalWaylineJobKey(device.getWorkspaceId(), dockSn, jobId), waylineJob);
return receiver;
}
} catch (Exception e) {
log.error("Failed to execute conditional task.");
e.printStackTrace();
} }
executeReadyTask(jobOpt.get());
return receiver; return receiver;
} }
@Scheduled(initialDelay = 10, fixedRate = 5, timeUnit = TimeUnit.SECONDS) private void executeReadyTask(WaylineJobDTO waylineJob) {
private void checkScheduledJob() { try {
Object jobIdValue = RedisOpsUtils.zGetMin(RedisConst.WAYLINE_JOB_TIMED_EXECUTE); boolean isExecute = waylineJobService.executeFlightTask(waylineJob.getWorkspaceId(), waylineJob.getJobId());
if (Objects.isNull(jobIdValue)) { if (isExecute || WaylineTaskTypeEnum.CONDITION != waylineJob.getTaskType()) {
return; return;
} }
log.info("Check the timed tasks of the wayline. {}", jobIdValue); Optional<WaylineJobDTO> waylineJobOpt = waylineRedisService.getConditionalWaylineJob(waylineJob.getJobId());
// format: {workspace_id}:{dock_sn}:{job_id} if (waylineJobOpt.isEmpty()) {
String[] jobArr = String.valueOf(jobIdValue).split(RedisConst.DELIMITER); log.info("The conditional job has expired and will no longer be executed.");
double time = RedisOpsUtils.zScore(RedisConst.WAYLINE_JOB_TIMED_EXECUTE, jobIdValue); return;
long now = System.currentTimeMillis();
int offset = 30_000;
// Expired tasks are deleted directly.
if (time < now - offset) {
RedisOpsUtils.zRemove(RedisConst.WAYLINE_JOB_TIMED_EXECUTE, jobIdValue);
waylineJobService.updateJob(WaylineJobDTO.builder()
.jobId(jobArr[2])
.status(WaylineJobStatusEnum.FAILED.getVal())
.executeTime(LocalDateTime.now())
.completedTime(LocalDateTime.now())
.code(HttpStatus.SC_REQUEST_TIMEOUT).build());
return;
}
if (now <= time && time <= now + offset) {
try {
waylineJobService.executeFlightTask(jobArr[0], jobArr[2]);
} catch (Exception e) {
log.info("The scheduled task delivery failed.");
waylineJobService.updateJob(WaylineJobDTO.builder()
.jobId(jobArr[2])
.status(WaylineJobStatusEnum.FAILED.getVal())
.executeTime(LocalDateTime.now())
.completedTime(LocalDateTime.now())
.code(HttpStatus.SC_INTERNAL_SERVER_ERROR).build());
} finally {
RedisOpsUtils.zRemove(RedisConst.WAYLINE_JOB_TIMED_EXECUTE, jobIdValue);
} }
waylineJob = waylineJobOpt.get();
this.retryPrepareConditionJob(new WaylineJobKey(waylineJob.getWorkspaceId(), waylineJob.getDockSn(), waylineJob.getJobId()), waylineJob);
} catch (Exception e) {
log.error("Failed to execute task. ID: {}, Name:{}", waylineJob.getJobId(), waylineJob.getJobName());
this.retryPrepareConditionJob(new WaylineJobKey(waylineJob.getWorkspaceId(), waylineJob.getDockSn(), waylineJob.getJobId()), waylineJob);
e.printStackTrace();
} }
} }
@Scheduled(initialDelay = 10, fixedRate = 5, timeUnit = TimeUnit.SECONDS) @Scheduled(initialDelay = 10, fixedRate = 5, timeUnit = TimeUnit.SECONDS)
private void prepareConditionJob() { private void prepareWaylineJob() {
Optional<ConditionalWaylineJobKey> jobKeyOpt = waylineRedisService.getNearestConditionalWaylineJob(); Optional<WaylineJobKey> jobKeyOpt = waylineRedisService.getNearestPreparedWaylineJob();
if (jobKeyOpt.isEmpty()) { if (jobKeyOpt.isEmpty()) {
return; return;
} }
ConditionalWaylineJobKey jobKey = jobKeyOpt.get();
log.info("Check the conditional tasks of the wayline. {}", jobKey.toString());
// format: {workspace_id}:{dock_sn}:{job_id} // format: {workspace_id}:{dock_sn}:{job_id}
double time = waylineRedisService.getConditionalWaylineJobTime(jobKey); WaylineJobKey jobKey = jobKeyOpt.get();
long now = System.currentTimeMillis(); log.info("Check the prepared tasks of the wayline. {}", jobKey.toString());
// prepare the task one day in advance.
int offset = 86_400_000;
if (now + offset < time) {
return;
}
WaylineJobDTO job = WaylineJobDTO.builder() WaylineJobDTO job = WaylineJobDTO.builder()
.jobId(jobKey.getJobId()) .jobId(jobKey.getJobId())
@ -237,40 +203,65 @@ public class FlightTaskServiceImpl implements IFlightTaskService {
.executeTime(LocalDateTime.now()) .executeTime(LocalDateTime.now())
.completedTime(LocalDateTime.now()) .completedTime(LocalDateTime.now())
.code(HttpStatus.SC_INTERNAL_SERVER_ERROR).build(); .code(HttpStatus.SC_INTERNAL_SERVER_ERROR).build();
try { Optional<WaylineJobDTO> waylineJobOpt = getPreparedJob(jobKey, job);
Optional<WaylineJobDTO> waylineJobOpt = waylineRedisService.getConditionalWaylineJob(jobKey.getJobId()); if (waylineJobOpt.isEmpty()) {
if (waylineJobOpt.isEmpty()) { return;
job.setCode(CommonErrorEnum.REDIS_DATA_NOT_FOUND.getErrorCode()); }
waylineJobService.updateJob(job);
waylineRedisService.removePrepareConditionalWaylineJob(jobKey);
return;
}
WaylineJobDTO waylineJob = waylineJobOpt.get();
WaylineJobDTO waylineJob = waylineJobOpt.get();
try {
ResponseResult result = waylineJobService.publishOneFlightTask(waylineJob); ResponseResult result = waylineJobService.publishOneFlightTask(waylineJob);
waylineRedisService.removePrepareConditionalWaylineJob(jobKey);
if (ResponseResult.CODE_SUCCESS == result.getCode()) { if (ResponseResult.CODE_SUCCESS == result.getCode()) {
return; return;
} }
log.info("Failed to prepare the task. {}", result.getMessage());
// If the end time is exceeded, no more retries will be made. job.setCode(result.getCode());
waylineRedisService.delConditionalWaylineJob(jobKey.getJobId()); waylineJobService.updateJob(job);
if (waylineJob.getEndTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() - RedisConst.WAYLINE_JOB_BLOCK_TIME * 1000 < now) {
return;
}
// Retry if the end time has not been exceeded. // Retry if the end time has not been exceeded.
this.retryPrepareJob(jobKey, waylineJob); this.retryPrepareConditionJob(jobKey, waylineJob);
} catch (Exception e) { } catch (Exception e) {
log.info("Failed to prepare the conditional task."); log.info("Failed to prepare the task. {}", e.getLocalizedMessage());
waylineJobService.updateJob(job); waylineJobService.updateJob(job);
this.retryPrepareConditionJob(jobKey, waylineJob);
}
}
private boolean checkTime(long time) {
// prepare the task one day in advance.
int offset = 86_400_000;
return System.currentTimeMillis() + offset >= time;
}
private Optional<WaylineJobDTO> getPreparedJob(WaylineJobKey jobKey, WaylineJobDTO job) {
long time = waylineRedisService.getPreparedWaylineJobTime(jobKey).longValue();
if (!checkTime(time)) {
return Optional.empty();
} }
Optional<WaylineJobDTO> waylineJobOpt = waylineRedisService.getConditionalWaylineJob(jobKey.getJobId());
// Determine whether the conditional task or the scheduled task has expired.
if (waylineJobOpt.isEmpty()) {
waylineJobOpt = waylineJobService.getJobByJobId(jobKey.getWorkspaceId(), jobKey.getJobId());
if (waylineJobOpt.isEmpty() || waylineJobOpt.get().getEndTime().isBefore(LocalDateTime.now())) {
job.setCode(CommonErrorEnum.REDIS_DATA_NOT_FOUND.getErrorCode());
waylineJobService.updateJob(job);
return Optional.empty();
}
}
waylineRedisService.removePreparedWaylineJob(jobKey);
return waylineJobOpt;
} }
private void retryPrepareJob(ConditionalWaylineJobKey jobKey, WaylineJobDTO waylineJob) { private void retryPrepareConditionJob(WaylineJobKey jobKey, WaylineJobDTO waylineJob) {
if (WaylineTaskTypeEnum.CONDITION != waylineJob.getTaskType()) {
return;
}
// If the end time is exceeded, no more retries will be made.
waylineRedisService.delConditionalWaylineJob(jobKey.getJobId());
if (waylineJob.getEndTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() < System.currentTimeMillis()) {
return;
}
Optional<WaylineJobDTO> childJobOpt = waylineJobService.createWaylineJobByParent(jobKey.getWorkspaceId(), jobKey.getJobId()); Optional<WaylineJobDTO> childJobOpt = waylineJobService.createWaylineJobByParent(jobKey.getWorkspaceId(), jobKey.getJobId());
if (childJobOpt.isEmpty()) { if (childJobOpt.isEmpty()) {
log.error("Failed to create wayline job."); log.error("Failed to create wayline job.");
@ -279,7 +270,7 @@ public class FlightTaskServiceImpl implements IFlightTaskService {
WaylineJobDTO newJob = childJobOpt.get(); WaylineJobDTO newJob = childJobOpt.get();
newJob.setBeginTime(LocalDateTime.now().plusSeconds(RedisConst.WAYLINE_JOB_BLOCK_TIME)); newJob.setBeginTime(LocalDateTime.now().plusSeconds(RedisConst.WAYLINE_JOB_BLOCK_TIME));
boolean isAdd = waylineRedisService.addPrepareConditionalWaylineJob(newJob); boolean isAdd = waylineRedisService.addPreparedWaylineJob(newJob);
if (!isAdd) { if (!isAdd) {
log.error("Failed to create wayline job. {}", newJob.getJobId()); log.error("Failed to create wayline job. {}", newJob.getJobId());
return; return;

112
src/main/java/com/dji/sample/wayline/service/impl/WaylineJobServiceImpl.java

@ -27,10 +27,7 @@ import com.dji.sample.media.service.IFileService;
import com.dji.sample.wayline.dao.IWaylineJobMapper; import com.dji.sample.wayline.dao.IWaylineJobMapper;
import com.dji.sample.wayline.model.dto.*; import com.dji.sample.wayline.model.dto.*;
import com.dji.sample.wayline.model.entity.WaylineJobEntity; import com.dji.sample.wayline.model.entity.WaylineJobEntity;
import com.dji.sample.wayline.model.enums.WaylineErrorCodeEnum; import com.dji.sample.wayline.model.enums.*;
import com.dji.sample.wayline.model.enums.WaylineJobStatusEnum;
import com.dji.sample.wayline.model.enums.WaylineMethodEnum;
import com.dji.sample.wayline.model.enums.WaylineTaskTypeEnum;
import com.dji.sample.wayline.model.param.CreateJobParam; import com.dji.sample.wayline.model.param.CreateJobParam;
import com.dji.sample.wayline.model.param.UpdateJobParam; import com.dji.sample.wayline.model.param.UpdateJobParam;
import com.dji.sample.wayline.service.IWaylineFileService; import com.dji.sample.wayline.service.IWaylineFileService;
@ -152,98 +149,91 @@ public class WaylineJobServiceImpl implements IWaylineJobService {
return; return;
} }
long now = System.currentTimeMillis() / 1000; long now = System.currentTimeMillis() / 1000;
if (CollectionUtils.isEmpty(param.getTaskDays())) { param.setTaskDays(Collections.singletonList(now));
param.setTaskDays(List.of(now)); param.setTaskPeriods(Collections.singletonList(Collections.singletonList(now)));
}
if (CollectionUtils.isEmpty(param.getTaskPeriods())) {
param.setTaskPeriods(List.of(List.of(now)));
}
} }
@Override @Override
public ResponseResult publishFlightTask(CreateJobParam param, CustomClaim customClaim) throws SQLException { public ResponseResult publishFlightTask(CreateJobParam param, CustomClaim customClaim) throws SQLException {
fillImmediateTime(param); fillImmediateTime(param);
param.getTaskDays().sort((a, b) -> (int) (a - b));
param.getTaskPeriods().sort((a, b) -> (int) (a.get(0) - b.get(0)));
for (Long taskDay : param.getTaskDays()) { for (Long taskDay : param.getTaskDays()) {
LocalDate date = LocalDate.ofInstant(Instant.ofEpochSecond(taskDay), ZoneId.systemDefault()); LocalDate date = LocalDate.ofInstant(Instant.ofEpochSecond(taskDay), ZoneId.systemDefault());
for (List<Long> taskPeriod : param.getTaskPeriods()) { for (List<Long> taskPeriod : param.getTaskPeriods()) {
long beginTime = LocalDateTime.of(date, LocalTime.ofInstant(Instant.ofEpochSecond(taskPeriod.get(0)), ZoneId.systemDefault())) long beginTime = LocalDateTime.of(date, LocalTime.ofInstant(Instant.ofEpochSecond(taskPeriod.get(0)), ZoneId.systemDefault()))
.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
long endTime = taskPeriod.size() > 1 ? long endTime = taskPeriod.size() > 1 && Objects.nonNull(taskPeriod.get(1)) ?
LocalDateTime.of(date, LocalTime.ofInstant(Instant.ofEpochSecond(taskPeriod.get(1)), ZoneId.systemDefault())) LocalDateTime.of(date, LocalTime.ofInstant(Instant.ofEpochSecond(taskPeriod.get(1)), ZoneId.systemDefault()))
.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() : beginTime; .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() : beginTime;
if (WaylineTaskTypeEnum.IMMEDIATE != param.getTaskType() && endTime < System.currentTimeMillis()) {
return ResponseResult.error("The task has expired.");
}
Optional<WaylineJobDTO> waylineJobOpt = this.createWaylineJob(param, customClaim.getWorkspaceId(), customClaim.getUsername(), beginTime, endTime); Optional<WaylineJobDTO> waylineJobOpt = this.createWaylineJob(param, customClaim.getWorkspaceId(), customClaim.getUsername(), beginTime, endTime);
if (waylineJobOpt.isEmpty()) { if (waylineJobOpt.isEmpty()) {
throw new SQLException("Failed to create wayline job."); return ResponseResult.error("Failed to create wayline job.");
} }
WaylineJobDTO waylineJob = waylineJobOpt.get(); WaylineJobDTO waylineJob = waylineJobOpt.get();
// If it is a conditional task type, add conditions to the job parameters. if (WaylineTaskTypeEnum.IMMEDIATE == param.getTaskType()) {
addConditions(waylineJob, param, beginTime, endTime); return this.publishOneFlightTask(waylineJob);
}
return this.publishOneFlightTask(waylineJob); // If it is a conditional task type, add conditions to the job parameters.
addPreparedJob(waylineJob, param, beginTime, endTime);
} }
} }
return ResponseResult.error(); return ResponseResult.success();
} }
private void addConditions(WaylineJobDTO waylineJob, CreateJobParam param, Long beginTime, Long endTime) { private void addPreparedJob(WaylineJobDTO waylineJob, CreateJobParam param, Long beginTime, Long endTime) {
if (WaylineTaskTypeEnum.CONDITION != param.getTaskType()) { if (WaylineTaskTypeEnum.CONDITION == param.getTaskType()) {
return; waylineJob.setConditions(
} WaylineTaskConditionDTO.builder()
.executableConditions(Objects.nonNull(param.getMinStorageCapacity()) ?
waylineJob.setConditions( WaylineTaskExecutableConditionDTO.builder().storageCapacity(param.getMinStorageCapacity()).build() : null)
WaylineTaskConditionDTO.builder() .readyConditions(WaylineTaskReadyConditionDTO.builder()
.executableConditions(Objects.nonNull(param.getMinStorageCapacity()) ? .batteryCapacity(param.getMinBatteryCapacity())
WaylineTaskExecutableConditionDTO.builder().storageCapacity(param.getMinStorageCapacity()).build() : null) .beginTime(beginTime)
.readyConditions(WaylineTaskReadyConditionDTO.builder() .endTime(endTime)
.batteryCapacity(param.getMinBatteryCapacity()) .build())
.beginTime(beginTime) .build());
.endTime(endTime)
.build()) waylineRedisService.setConditionalWaylineJob(waylineJob);
.build()); }
// value: {workspace_id}:{dock_sn}:{job_id}
waylineRedisService.setConditionalWaylineJob(waylineJob); boolean isAdd = waylineRedisService.addPreparedWaylineJob(waylineJob);
// key: wayline_job_condition, value: {workspace_id}:{dock_sn}:{job_id}
boolean isAdd = waylineRedisService.addPrepareConditionalWaylineJob(waylineJob);
if (!isAdd) { if (!isAdd) {
throw new RuntimeException("Failed to create conditional job."); throw new RuntimeException("Failed to create prepare job.");
} }
} }
public ResponseResult publishOneFlightTask(WaylineJobDTO waylineJob) throws SQLException { public ResponseResult publishOneFlightTask(WaylineJobDTO waylineJob) throws SQLException {
boolean isOnline = deviceRedisService.checkDeviceOnline(waylineJob.getDockSn());
if (!isOnline) {
throw new RuntimeException("Dock is offline.");
}
boolean isSuccess = this.prepareFlightTask(waylineJob); boolean isSuccess = this.prepareFlightTask(waylineJob);
if (!isSuccess) { if (!isSuccess) {
return ResponseResult.error("Failed to prepare job."); return ResponseResult.error("Failed to prepare job.");
} }
// Issue an immediate task execution command. // Issue an immediate task execution command.
if (WaylineTaskTypeEnum.IMMEDIATE.getVal() == waylineJob.getTaskType()) { if (WaylineTaskTypeEnum.IMMEDIATE == waylineJob.getTaskType()) {
if (!executeFlightTask(waylineJob.getWorkspaceId(), waylineJob.getJobId())) { boolean isExecuted = executeFlightTask(waylineJob.getWorkspaceId(), waylineJob.getJobId());
if (!isExecuted) {
return ResponseResult.error("Failed to execute job."); return ResponseResult.error("Failed to execute job.");
} }
} }
if (WaylineTaskTypeEnum.TIMED.getVal() == waylineJob.getTaskType()) {
// key: wayline_job_timed, value: {workspace_id}:{dock_sn}:{job_id}
boolean isAdd = RedisOpsUtils.zAdd(RedisConst.WAYLINE_JOB_TIMED_EXECUTE,
waylineJob.getWorkspaceId() + RedisConst.DELIMITER + waylineJob.getDockSn() + RedisConst.DELIMITER + waylineJob.getJobId(),
waylineJob.getBeginTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
if (!isAdd) {
return ResponseResult.error("Failed to create scheduled job.");
}
}
return ResponseResult.success(); return ResponseResult.success();
} }
private Boolean prepareFlightTask(WaylineJobDTO waylineJob) throws SQLException { private Boolean prepareFlightTask(WaylineJobDTO waylineJob) throws SQLException {
boolean isOnline = deviceRedisService.checkDeviceOnline(waylineJob.getDockSn());
if (!isOnline) {
throw new RuntimeException("Dock is offline.");
}
// get wayline file // get wayline file
Optional<WaylineFileDTO> waylineFile = waylineFileService.getWaylineByWaylineId(waylineJob.getWorkspaceId(), waylineJob.getFileId()); Optional<WaylineFileDTO> waylineFile = waylineFileService.getWaylineByWaylineId(waylineJob.getWorkspaceId(), waylineJob.getFileId());
if (waylineFile.isEmpty()) { if (waylineFile.isEmpty()) {
@ -266,7 +256,7 @@ public class WaylineJobServiceImpl implements IWaylineJobService {
.build()) .build())
.build(); .build();
if (WaylineTaskTypeEnum.CONDITION.getVal() == waylineJob.getTaskType()) { if (WaylineTaskTypeEnum.CONDITION == waylineJob.getTaskType()) {
if (Objects.isNull(waylineJob.getConditions())) { if (Objects.isNull(waylineJob.getConditions())) {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
@ -317,7 +307,7 @@ public class WaylineJobServiceImpl implements IWaylineJobService {
.completedTime(LocalDateTime.now()) .completedTime(LocalDateTime.now())
.code(serviceReply.getResult()).build()); .code(serviceReply.getResult()).build());
// The conditional task fails and enters the blocking status. // The conditional task fails and enters the blocking status.
if (WaylineTaskTypeEnum.CONDITION.getVal() == job.getTaskType() if (WaylineTaskTypeEnum.CONDITION == job.getTaskType()
&& WaylineErrorCodeEnum.find(serviceReply.getResult()).isBlock()) { && WaylineErrorCodeEnum.find(serviceReply.getResult()).isBlock()) {
waylineRedisService.setBlockedWaylineJob(job.getDockSn(), jobId); waylineRedisService.setBlockedWaylineJob(job.getDockSn(), jobId);
} }
@ -372,7 +362,6 @@ public class WaylineJobServiceImpl implements IWaylineJobService {
.status(WaylineJobStatusEnum.CANCEL.getVal()) .status(WaylineJobStatusEnum.CANCEL.getVal())
.completedTime(LocalDateTime.now()) .completedTime(LocalDateTime.now())
.build()); .build());
RedisOpsUtils.zRemove(RedisConst.WAYLINE_JOB_TIMED_EXECUTE, workspaceId + RedisConst.DELIMITER + dockSn + RedisConst.DELIMITER + jobId);
} }
} }
@ -382,8 +371,7 @@ public class WaylineJobServiceImpl implements IWaylineJobService {
new LambdaQueryWrapper<WaylineJobEntity>() new LambdaQueryWrapper<WaylineJobEntity>()
.eq(WaylineJobEntity::getWorkspaceId, workspaceId) .eq(WaylineJobEntity::getWorkspaceId, workspaceId)
.eq(Objects.nonNull(status), WaylineJobEntity::getStatus, status.getVal()) .eq(Objects.nonNull(status), WaylineJobEntity::getStatus, status.getVal())
.and(!CollectionUtils.isEmpty(jobIds), .in(!CollectionUtils.isEmpty(jobIds), WaylineJobEntity::getJobId, jobIds))
wrapper -> jobIds.forEach(id -> wrapper.eq(WaylineJobEntity::getJobId, id).or())))
.stream() .stream()
.map(this::entity2Dto) .map(this::entity2Dto)
.collect(Collectors.toList()); .collect(Collectors.toList());
@ -524,8 +512,8 @@ public class WaylineJobServiceImpl implements IWaylineJobService {
.fileId(dto.getFileId()) .fileId(dto.getFileId())
.dockSn(dto.getDockSn()) .dockSn(dto.getDockSn())
.workspaceId(dto.getWorkspaceId()) .workspaceId(dto.getWorkspaceId())
.taskType(dto.getTaskType()) .taskType(Optional.ofNullable(dto.getTaskType()).map(WaylineTaskTypeEnum::getVal).orElse(null))
.waylineType(dto.getWaylineType()) .waylineType(Optional.ofNullable(dto.getWaylineType()).map(WaylineTemplateTypeEnum::getVal).orElse(null))
.username(dto.getUsername()) .username(dto.getUsername())
.rthAltitude(dto.getRthAltitude()) .rthAltitude(dto.getRthAltitude())
.outOfControlAction(dto.getOutOfControlAction()) .outOfControlAction(dto.getOutOfControlAction())
@ -645,8 +633,8 @@ public class WaylineJobServiceImpl implements IWaylineJobService {
LocalDateTime.ofInstant(Instant.ofEpochMilli(entity.getExecuteTime()), ZoneId.systemDefault()) : null) LocalDateTime.ofInstant(Instant.ofEpochMilli(entity.getExecuteTime()), ZoneId.systemDefault()) : null)
.completedTime(WaylineJobStatusEnum.find(entity.getStatus()).getEnd() ? .completedTime(WaylineJobStatusEnum.find(entity.getStatus()).getEnd() ?
LocalDateTime.ofInstant(Instant.ofEpochMilli(entity.getUpdateTime()), ZoneId.systemDefault()) : null) LocalDateTime.ofInstant(Instant.ofEpochMilli(entity.getUpdateTime()), ZoneId.systemDefault()) : null)
.taskType(entity.getTaskType()) .taskType(WaylineTaskTypeEnum.find(entity.getTaskType()))
.waylineType(entity.getWaylineType()) .waylineType(WaylineTemplateTypeEnum.find(entity.getWaylineType()))
.rthAltitude(entity.getRthAltitude()) .rthAltitude(entity.getRthAltitude())
.outOfControlAction(entity.getOutOfControlAction()) .outOfControlAction(entity.getOutOfControlAction())
.mediaCount(entity.getMediaCount()); .mediaCount(entity.getMediaCount());

27
src/main/java/com/dji/sample/wayline/service/impl/WaylineRedisServiceImpl.java

@ -3,8 +3,8 @@ package com.dji.sample.wayline.service.impl;
import com.dji.sample.component.mqtt.model.EventsReceiver; import com.dji.sample.component.mqtt.model.EventsReceiver;
import com.dji.sample.component.redis.RedisConst; import com.dji.sample.component.redis.RedisConst;
import com.dji.sample.component.redis.RedisOpsUtils; import com.dji.sample.component.redis.RedisOpsUtils;
import com.dji.sample.wayline.model.dto.ConditionalWaylineJobKey;
import com.dji.sample.wayline.model.dto.WaylineJobDTO; import com.dji.sample.wayline.model.dto.WaylineJobDTO;
import com.dji.sample.wayline.model.dto.WaylineJobKey;
import com.dji.sample.wayline.model.dto.WaylineTaskProgressReceiver; import com.dji.sample.wayline.model.dto.WaylineTaskProgressReceiver;
import com.dji.sample.wayline.service.IWaylineRedisService; import com.dji.sample.wayline.service.IWaylineRedisService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -64,13 +64,18 @@ public class WaylineRedisServiceImpl implements IWaylineRedisService {
return (String) RedisOpsUtils.get(RedisConst.WAYLINE_JOB_BLOCK_PREFIX + dockSn); return (String) RedisOpsUtils.get(RedisConst.WAYLINE_JOB_BLOCK_PREFIX + dockSn);
} }
@Override
public Boolean delBlockedWaylineJobId(String dockSn) {
return RedisOpsUtils.del(RedisConst.WAYLINE_JOB_BLOCK_PREFIX + dockSn);
}
@Override @Override
public void setConditionalWaylineJob(WaylineJobDTO waylineJob) { public void setConditionalWaylineJob(WaylineJobDTO waylineJob) {
if (!StringUtils.hasText(waylineJob.getJobId())) { if (!StringUtils.hasText(waylineJob.getJobId())) {
throw new RuntimeException("Job id can't be null."); throw new RuntimeException("Job id can't be null.");
} }
RedisOpsUtils.setWithExpire(RedisConst.WAYLINE_JOB_CONDITION_PREFIX + waylineJob.getJobId(), waylineJob, RedisOpsUtils.setWithExpire(RedisConst.WAYLINE_JOB_CONDITION_PREFIX + waylineJob.getJobId(), waylineJob,
(Duration.between(waylineJob.getEndTime(), LocalDateTime.now()).getSeconds())); Math.abs(Duration.between(waylineJob.getEndTime(), LocalDateTime.now()).getSeconds()));
} }
@Override @Override
@ -84,29 +89,29 @@ public class WaylineRedisServiceImpl implements IWaylineRedisService {
} }
@Override @Override
public Boolean addPrepareConditionalWaylineJob(WaylineJobDTO waylineJob) { public Boolean addPreparedWaylineJob(WaylineJobDTO waylineJob) {
if (Objects.isNull(waylineJob.getBeginTime())) { if (Objects.isNull(waylineJob.getBeginTime())) {
return false; return false;
} }
// value: {workspace_id}:{dock_sn}:{job_id} // value: {workspace_id}:{dock_sn}:{job_id}
return RedisOpsUtils.zAdd(RedisConst.WAYLINE_JOB_CONDITION_PREPARE, return RedisOpsUtils.zAdd(RedisConst.WAYLINE_JOB_PREPARED,
waylineJob.getWorkspaceId() + RedisConst.DELIMITER + waylineJob.getDockSn() + RedisConst.DELIMITER + waylineJob.getJobId(), waylineJob.getWorkspaceId() + RedisConst.DELIMITER + waylineJob.getDockSn() + RedisConst.DELIMITER + waylineJob.getJobId(),
waylineJob.getBeginTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()); waylineJob.getBeginTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
} }
@Override @Override
public Optional<ConditionalWaylineJobKey> getNearestConditionalWaylineJob() { public Optional<WaylineJobKey> getNearestPreparedWaylineJob() {
return Optional.ofNullable(RedisOpsUtils.zGetMin(RedisConst.WAYLINE_JOB_CONDITION_PREPARE)) return Optional.ofNullable(RedisOpsUtils.zGetMin(RedisConst.WAYLINE_JOB_PREPARED))
.map(Object::toString).map(ConditionalWaylineJobKey::new); .map(Object::toString).map(WaylineJobKey::new);
} }
@Override @Override
public Double getConditionalWaylineJobTime(ConditionalWaylineJobKey jobKey) { public Double getPreparedWaylineJobTime(WaylineJobKey jobKey) {
return RedisOpsUtils.zScore(RedisConst.WAYLINE_JOB_CONDITION_PREPARE, jobKey.getKey()); return RedisOpsUtils.zScore(RedisConst.WAYLINE_JOB_PREPARED, jobKey.getKey());
} }
@Override @Override
public Boolean removePrepareConditionalWaylineJob(ConditionalWaylineJobKey jobKey) { public Boolean removePreparedWaylineJob(WaylineJobKey jobKey) {
return RedisOpsUtils.zRemove(RedisConst.WAYLINE_JOB_CONDITION_PREPARE, jobKey.getKey()); return RedisOpsUtils.zRemove(RedisConst.WAYLINE_JOB_PREPARED, jobKey.getKey());
} }
} }

20089
src/main/resources/hms.json

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save