From a7aaeabc7873a0eafb4a7ecad7f65b018b7a9bc9 Mon Sep 17 00:00:00 2001
From: sean.zhou <sean.zhou@dji.com>
Date: Fri, 24 Feb 2023 19:31:23 +0800
Subject: [PATCH] What's new? 1. Add license for dock. 2. Modify the logic corresponding to the firmware file and device type. 3. Add multiple mqtt clients options. 4. Modify the structure of the interface for obtaining the device list. 5. Fixed some issues.
---
src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskCreateDTO.java | 5
src/main/java/com/dji/sample/manage/service/impl/GatewayOSDServiceImpl.java | 2
src/main/java/com/dji/sample/manage/service/impl/DeviceFirmwareServiceImpl.java | 85 ++-
sql/cloud_sample.sql | 30 +
src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskProgressExt.java | 6
src/main/java/com/dji/sample/manage/service/impl/DeviceServiceImpl.java | 137 +++--
src/main/java/com/dji/sample/manage/model/common/AppLicenseProperties.java | 32 +
src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskProgress.java | 2
src/main/java/com/dji/sample/component/mqtt/model/MqttProtocolEnum.java | 30 +
src/main/java/com/dji/sample/manage/service/IFirmwareModelService.java | 18
src/main/java/com/dji/sample/manage/model/dto/LogsUploadCredentialsDTO.java | 5
src/main/java/com/dji/sample/wayline/service/impl/WaylineJobServiceImpl.java | 203 +++++---
src/main/java/com/dji/sample/manage/controller/DeviceController.java | 2
src/main/java/com/dji/sample/manage/service/impl/FirmwareModelServiceImpl.java | 44 +
src/main/java/com/dji/sample/wayline/model/dto/WaylineJobDTO.java | 6
src/main/java/com/dji/sample/wayline/model/entity/WaylineJobEntity.java | 8
src/main/java/com/dji/sample/manage/model/dto/DeviceDTO.java | 4
src/main/java/com/dji/sample/manage/model/entity/FirmwareModelEntity.java | 37 +
src/main/java/com/dji/sample/wayline/service/impl/WaylineFileServiceImpl.java | 2
src/main/java/com/dji/sample/component/mqtt/model/MqttClientOptions.java | 31 +
src/main/java/com/dji/sample/manage/service/impl/DeviceOSDServiceImpl.java | 5
src/main/java/com/dji/sample/wayline/service/IWaylineJobService.java | 39 +
src/main/java/com/dji/sample/component/GlobalScheduleService.java | 4
src/main/java/com/dji/sample/control/service/impl/ControlServiceImpl.java | 3
src/main/java/com/dji/sample/component/redis/RedisConst.java | 16
src/main/java/com/dji/sample/manage/service/IDeviceFirmwareService.java | 11
src/main/java/com/dji/sample/manage/model/dto/FirmwareModelDTO.java | 24 +
src/main/java/com/dji/sample/common/error/CommonErrorEnum.java | 6
src/main/java/com/dji/sample/component/mqtt/config/MqttConfiguration.java | 75 ++-
src/main/java/com/dji/sample/component/mqtt/config/MqttInboundConfiguration.java | 9
src/main/java/com/dji/sample/manage/service/impl/DockOSDServiceImpl.java | 2
src/main/java/com/dji/sample/manage/model/entity/DeviceFirmwareEntity.java | 2
src/main/java/com/dji/sample/common/util/JwtUtil.java | 57 ++
src/main/java/com/dji/sample/component/mqtt/config/MqttOutboundConfiguration.java | 2
src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskProgressReceiver.java | 19
src/main/java/com/dji/sample/component/redis/RedisOpsUtils.java | 9
src/main/java/com/dji/sample/manage/service/impl/UserServiceImpl.java | 16
src/main/java/com/dji/sample/component/mqtt/service/impl/MessageSenderServiceImpl.java | 3
src/main/java/com/dji/sample/wayline/model/enums/WaylineJobStatusEnum.java | 4
src/main/java/com/dji/sample/manage/dao/IDeviceFirmwareMapper.java | 27 +
src/main/java/com/dji/sample/manage/model/dto/ProductConfigDTO.java | 8
src/main/java/com/dji/sample/manage/service/IDeviceService.java | 2
src/main/java/com/dji/sample/manage/service/impl/ConfigProductServiceImpl.java | 5
src/main/java/com/dji/sample/component/mqtt/model/MqttUseEnum.java | 19
src/main/java/com/dji/sample/manage/model/param/DeviceFirmwareUploadParam.java | 3
src/main/java/com/dji/sample/wayline/service/impl/FlightTaskServiceImpl.java | 52 +
src/main/java/com/dji/sample/manage/dao/IFirmwareModelMapper.java | 12
src/main/java/com/dji/sample/component/mqtt/model/MapKeyConst.java | 2
src/main/java/com/dji/sample/manage/model/dto/DeviceFirmwareDTO.java | 3
src/main/java/com/dji/sample/manage/controller/DeviceFirmwareController.java | 16
/dev/null | 19
src/main/java/com/dji/sample/manage/service/impl/AbstractTSAService.java | 4
src/main/java/com/dji/sample/media/service/impl/MediaServiceImpl.java | 53 +-
src/main/java/com/dji/sample/manage/model/dto/TopologyDeviceDTO.java | 2
src/main/java/com/dji/sample/manage/model/enums/DeviceDomainEnum.java | 68 --
src/main/java/com/dji/sample/wayline/controller/WaylineJobController.java | 4
src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskFileDTO.java | 2
src/main/java/com/dji/sample/manage/model/receiver/DistanceLimitStatusReceiver.java | 2
src/main/resources/application.yml | 32
src/main/java/com/dji/sample/manage/service/impl/LiveStreamServiceImpl.java | 11
60 files changed, 919 insertions(+), 422 deletions(-)
diff --git a/sql/cloud_sample.sql b/sql/cloud_sample.sql
index b4fda63..3ff45db 100644
--- a/sql/cloud_sample.sql
+++ b/sql/cloud_sample.sql
@@ -46,7 +46,7 @@
`file_id` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT 'The file_id in the logs_file table.',
`start_time` bigint NOT NULL COMMENT 'The file start time reported by the dock.',
`end_time` bigint NOT NULL COMMENT 'The file end time reported by the dock.',
- `size` int NOT NULL COMMENT 'The file size reported by the dock.',
+ `size` bigint NOT NULL COMMENT 'The file size reported by the dock.',
`device_sn` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT 'The sn of the device.',
`domain` int NOT NULL COMMENT 'This parameter corresponds to the domain in the device dictionary table.',
`create_time` bigint NOT NULL,
@@ -132,7 +132,9 @@
(20,0,77,1,'Mavic 3T',NULL),
(21,1,66,0,'Mavic 3E Camera',NULL),
(22,1,67,0,'Mavic 3T Camera',NULL),
- (23,2,144,0,'DJI RC Pro','Remote control for Mavic 3E/T');
+ (23,2,144,0,'DJI RC Pro','Remote control for Mavic 3E/T and Mavic 3M'),
+ (24,0,77,2,'Mavic 3M',NULL),
+ (25,1,68,0,'Mavic 3M Camera',NULL);
/*!40000 ALTER TABLE `manage_device_dictionary` ENABLE KEYS */;
UNLOCK TABLES;
@@ -151,7 +153,6 @@
`object_key` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'The object key of the firmware package in the bucket.',
`file_size` int NOT NULL COMMENT 'The size of the firmware package.',
`file_md5` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT 'The md5 of the firmware package.',
- `device_name` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT 'model of the device. This parameter corresponds to the device name in the device dictionary table.',
`workspace_id` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`release_note` varchar(1000) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT 'The release note of the firmware package.',
`release_date` bigint NOT NULL COMMENT 'The release date of the firmware package.',
@@ -230,6 +231,22 @@
PRIMARY KEY (`id`),
UNIQUE KEY `payload_sn_UNIQUE` (`payload_sn`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COMMENT='The payload information of the device.';
+
+
+
+# manage_firmware_model
+# ------------------------------------------------------------
+
+DROP TABLE IF EXISTS `manage_firmware_model`;
+
+CREATE TABLE `manage_firmware_model` (
+ `id` bigint unsigned NOT NULL AUTO_INCREMENT,
+ `firmware_id` varchar(64) NOT NULL,
+ `device_name` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'model of the device. This parameter corresponds to the device name in the device dictionary table.',
+ `create_time` bigint NOT NULL,
+ `update_time` bigint NOT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
@@ -431,9 +448,11 @@
`workspace_id` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT 'Which workspace the current job belongs to.',
`task_type` int NOT NULL,
`wayline_type` int NOT NULL COMMENT 'The template type of the wayline.',
- `execute_time` bigint NOT NULL,
+ `execute_time` bigint DEFAULT NULL COMMENT 'actual begin time',
+ `completed_time` bigint DEFAULT NULL COMMENT 'actual end time',
`username` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT 'The name of the creator.',
- `end_time` bigint DEFAULT NULL COMMENT 'end time of the job.',
+ `begin_time` bigint NOT NULL COMMENT 'planned begin time',
+ `end_time` bigint NOT NULL COMMENT 'planned end time',
`error_code` int DEFAULT NULL,
`status` int NOT NULL COMMENT '1: pending; 2: in progress; 3: success; 4: cancel; 5: failed',
`rth_altitude` int NOT NULL COMMENT 'return to home altitude. min: 20m; max: 500m',
@@ -441,6 +460,7 @@
`media_count` int NOT NULL DEFAULT '0',
`create_time` bigint NOT NULL,
`update_time` bigint NOT NULL,
+ `parent_id` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `job_id_UNIQUE` (`job_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COMMENT='Wayline mission information of the dock.';
diff --git a/src/main/java/com/dji/sample/common/error/CommonErrorEnum.java b/src/main/java/com/dji/sample/common/error/CommonErrorEnum.java
index 290cc42..1ab3b32 100644
--- a/src/main/java/com/dji/sample/common/error/CommonErrorEnum.java
+++ b/src/main/java/com/dji/sample/common/error/CommonErrorEnum.java
@@ -9,6 +9,10 @@
ILLEGAL_ARGUMENT(200001, "illegal argument"),
+ REDIS_DATA_NOT_FOUND(201404, "Redis data does not exist."),
+
+ DEVICE_OFFLINE(212015, "Device is offline."),
+
GET_ORGANIZATION_FAILED(210230, "Failed to get organization."),
DEVICE_BINDING_FAILED(210231, "Failed to bind device."),
@@ -21,7 +25,7 @@
SECRET_INVALID(600100, "secret invalid"),
- NO_TOKEN(600101, "accss_token is null"),
+ NO_TOKEN(600101, "token is null"),
TOKEN_EXPIRED(600102, "token is expired"),
diff --git a/src/main/java/com/dji/sample/common/error/StorageErrorEnum.java b/src/main/java/com/dji/sample/common/error/StorageErrorEnum.java
deleted file mode 100644
index 16b5d2f..0000000
--- a/src/main/java/com/dji/sample/common/error/StorageErrorEnum.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.dji.sample.common.error;
-
-/**
- * @author sean
- * @version 1.0
- * @date 2022/5/25
- */
-public enum StorageErrorEnum implements IErrorInfo {
-
- GENERATE_CREDENTIALS_ERROR(217001, "Failed to generate temporary credentials."),
-
- NO_BUCKET(217002, "The bucket does not exist."),
-
- ILLEGAL_PATH_FORMAT(217006, "Illegal path format."),
-
- FILE_CREATION_FAILED(217007, "File creation failed."),
-
- DIR_CREATION_FAILED(217008, "Directory creation failed");
-
- private String msg;
-
- private int code;
-
- StorageErrorEnum(int code, String msg) {
- this.msg = msg;
- this.code = code;
- }
-
- @Override
- public String getErrorMsg() {
- return msg;
- }
-
- @Override
- public Integer getErrorCode() {
- return code;
- }
-}
diff --git a/src/main/java/com/dji/sample/common/util/JwtUtil.java b/src/main/java/com/dji/sample/common/util/JwtUtil.java
index 918f1d7..c04168e 100644
--- a/src/main/java/com/dji/sample/common/util/JwtUtil.java
+++ b/src/main/java/com/dji/sample/common/util/JwtUtil.java
@@ -9,10 +9,9 @@
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
-import java.util.Date;
-import java.util.Map;
-import java.util.Optional;
+import java.util.*;
@Slf4j
@Component
@@ -26,7 +25,7 @@
private static String secret;
- private static Algorithm algorithm;
+ public static Algorithm algorithm;
@Value("${jwt.issuer: DJI}")
private void setIssuer(String issuer) {
@@ -62,15 +61,55 @@
* @param claims custom information
* @return token
*/
- public static String createToken(Map<String, String> claims) {
+ public static String createToken(Map<String, ?> claims) {
+ return JwtUtil.createToken(claims, age, algorithm, subject, issuer);
+ }
+
+ /**
+ *
+ * @param claims
+ * @param age unit: s
+ * @param algorithm
+ * @param subject
+ * @param issuer
+ * @return
+ */
+ public static String createToken(Map<String, ?> claims, Long age, Algorithm algorithm, String subject, String issuer) {
+ if (Objects.isNull(algorithm)) {
+ throw new IllegalArgumentException();
+ }
+
Date now = new Date();
JWTCreator.Builder builder = JWT.create();
// Add custom information to the token's payload segment.
- claims.forEach(builder::withClaim);
- String token = builder.withIssuer(issuer)
- .withSubject(subject)
+ claims.forEach((k, v) -> {
+ if (Objects.nonNull(v.getClass().getClassLoader())) {
+ log.error("claim can't be set to a custom object.");
+ return;
+ }
+ if (v instanceof Map) {
+ builder.withClaim(k, (Map) v);
+ } else if (v instanceof List) {
+ builder.withClaim(k, (List) v);
+ } else {
+ builder.withClaim(k, String.valueOf(v));
+ }
+ });
+
+ if (StringUtils.hasText(subject)) {
+ builder.withSubject(subject);
+ }
+
+ if (StringUtils.hasText(issuer)) {
+ builder.withIssuer(issuer);
+ }
+
+ if (Objects.nonNull(age)) {
+ builder.withExpiresAt(new Date(now.getTime() + age * 1000));
+ }
+
+ String token = builder
.withIssuedAt(now)
- .withExpiresAt(new Date(now.getTime() + age))
.withNotBefore(now)
.sign(algorithm);
log.debug("token created. " + token);
diff --git a/src/main/java/com/dji/sample/component/GlobalScheduleService.java b/src/main/java/com/dji/sample/component/GlobalScheduleService.java
index 81229ab..e092ad4 100644
--- a/src/main/java/com/dji/sample/component/GlobalScheduleService.java
+++ b/src/main/java/com/dji/sample/component/GlobalScheduleService.java
@@ -44,11 +44,13 @@
long expire = RedisOpsUtils.getExpire(key);
if (expire <= 30) {
DeviceDTO device = (DeviceDTO) RedisOpsUtils.get(key);
- if (device.getDomain().equals(DeviceDomainEnum.SUB_DEVICE.getDesc())) {
+ if (DeviceDomainEnum.SUB_DEVICE.getVal() == device.getDomain()) {
deviceService.subDeviceOffline(key.substring(start));
} else {
deviceService.unsubscribeTopicOffline(key.substring(start));
deviceService.pushDeviceOfflineTopo(device.getWorkspaceId(), device.getDeviceSn());
+ RedisOpsUtils.hashDel(RedisConst.LIVE_CAPACITY, new String[]{key});
+ RedisOpsUtils.del(RedisConst.HMS_PREFIX + key);
}
RedisOpsUtils.del(key);
}
diff --git a/src/main/java/com/dji/sample/component/mqtt/config/MqttConfiguration.java b/src/main/java/com/dji/sample/component/mqtt/config/MqttConfiguration.java
index 750ba58..69c6398 100644
--- a/src/main/java/com/dji/sample/component/mqtt/config/MqttConfiguration.java
+++ b/src/main/java/com/dji/sample/component/mqtt/config/MqttConfiguration.java
@@ -1,5 +1,10 @@
package com.dji.sample.component.mqtt.config;
+import com.auth0.jwt.algorithms.Algorithm;
+import com.dji.sample.common.util.JwtUtil;
+import com.dji.sample.component.mqtt.model.MqttClientOptions;
+import com.dji.sample.component.mqtt.model.MqttProtocolEnum;
+import com.dji.sample.component.mqtt.model.MqttUseEnum;
import lombok.Data;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.springframework.boot.context.properties.ConfigurationProperties;
@@ -7,6 +12,9 @@
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.mqtt.core.DefaultMqttPahoClientFactory;
import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
+import org.springframework.util.StringUtils;
+
+import java.util.Map;
/**
*
@@ -16,39 +24,60 @@
*/
@Configuration
@Data
-@ConfigurationProperties(prefix = "mqtt")
+@ConfigurationProperties
public class MqttConfiguration {
- private String protocol;
+ private static Map<MqttUseEnum, MqttClientOptions> mqtt;
- private String host;
-
- private Integer port;
-
- private String username;
-
- private String password;
-
- private String clientId;
+ public void setMqtt(Map<MqttUseEnum, MqttClientOptions> mqtt) {
+ MqttConfiguration.mqtt = mqtt;
+ }
/**
- * The topic to subscribe to immediately when client connects.
+ * Get the configuration options of the basic link of the mqtt client.
+ * @return
*/
- private String inboundTopic;
+ static MqttClientOptions getBasicClientOptions() {
+ if (!mqtt.containsKey(MqttUseEnum.BASIC)) {
+ throw new Error("Please configure the basic mqtt connection parameters first, otherwise application cannot be started.");
+ }
+ return mqtt.get(MqttUseEnum.BASIC);
+ }
+
+ /**
+ * Get the mqtt address of the basic link.
+ * @return
+ */
+ public static String getBasicMqttAddress() {
+ return getMqttAddress(getBasicClientOptions());
+ }
+
+ /**
+ * Splice the mqtt address according to the parameters of different clients.
+ * @param options
+ * @return
+ */
+ private static String getMqttAddress(MqttClientOptions options) {
+ StringBuilder addr = new StringBuilder()
+ .append(options.getProtocol().getProtocolAddr())
+ .append(options.getHost().trim())
+ .append(":")
+ .append(options.getPort());
+ if ((options.getProtocol() == MqttProtocolEnum.WS || options.getProtocol() == MqttProtocolEnum.WSS)
+ && StringUtils.hasText(options.getPath())) {
+ addr.append(options.getPath());
+ }
+ return addr.toString();
+ }
@Bean
public MqttConnectOptions mqttConnectOptions() {
+ MqttClientOptions customizeOptions = getBasicClientOptions();
MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
- mqttConnectOptions.setServerURIs(new String[]{
- new StringBuilder()
- .append(protocol.trim())
- .append("://")
- .append(host.trim())
- .append(":")
- .append(port)
- .toString()});
- mqttConnectOptions.setUserName(username);
- mqttConnectOptions.setPassword(password.toCharArray());
+ mqttConnectOptions.setServerURIs(new String[]{ getBasicMqttAddress() });
+ mqttConnectOptions.setUserName(customizeOptions.getUsername());
+ mqttConnectOptions.setPassword(StringUtils.hasText(customizeOptions.getPassword()) ?
+ customizeOptions.getPassword().toCharArray() : new char[0]);
mqttConnectOptions.setAutomaticReconnect(true);
mqttConnectOptions.setKeepAliveInterval(10);
return mqttConnectOptions;
diff --git a/src/main/java/com/dji/sample/component/mqtt/config/MqttInboundConfiguration.java b/src/main/java/com/dji/sample/component/mqtt/config/MqttInboundConfiguration.java
index 3964aaf..40dada5 100644
--- a/src/main/java/com/dji/sample/component/mqtt/config/MqttInboundConfiguration.java
+++ b/src/main/java/com/dji/sample/component/mqtt/config/MqttInboundConfiguration.java
@@ -1,6 +1,7 @@
package com.dji.sample.component.mqtt.config;
import com.dji.sample.component.mqtt.model.ChannelName;
+import com.dji.sample.component.mqtt.model.MqttClientOptions;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
@@ -29,9 +30,6 @@
public class MqttInboundConfiguration {
@Autowired
- private MqttConfiguration mqttConfiguration;
-
- @Autowired
private MqttPahoClientFactory mqttClientFactory;
@Resource(name = ChannelName.INBOUND)
@@ -43,9 +41,10 @@
*/
@Bean(name = "adapter")
public MessageProducerSupport mqttInbound() {
+ MqttClientOptions options = MqttConfiguration.getBasicClientOptions();
MqttPahoMessageDrivenChannelAdapter adapter = new MqttPahoMessageDrivenChannelAdapter(
- mqttConfiguration.getClientId() + "_consumer_" + System.currentTimeMillis(),
- mqttClientFactory, mqttConfiguration.getInboundTopic().split(","));
+ options.getClientId() + "_consumer_" + System.currentTimeMillis(),
+ mqttClientFactory, options.getInboundTopic().split(","));
DefaultPahoMessageConverter converter = new DefaultPahoMessageConverter();
// use byte types uniformly
converter.setPayloadAsBytes(true);
diff --git a/src/main/java/com/dji/sample/component/mqtt/config/MqttOutboundConfiguration.java b/src/main/java/com/dji/sample/component/mqtt/config/MqttOutboundConfiguration.java
index 69b919b..a376093 100644
--- a/src/main/java/com/dji/sample/component/mqtt/config/MqttOutboundConfiguration.java
+++ b/src/main/java/com/dji/sample/component/mqtt/config/MqttOutboundConfiguration.java
@@ -33,7 +33,7 @@
@ServiceActivator(inputChannel = ChannelName.OUTBOUND)
public MessageHandler mqttOutbound() {
MqttPahoMessageHandler messageHandler = new MqttPahoMessageHandler(
- mqttConfiguration.getClientId() + "_producer_" + System.currentTimeMillis(),
+ MqttConfiguration.getBasicClientOptions().getClientId() + "_producer_" + System.currentTimeMillis(),
mqttClientFactory);
DefaultPahoMessageConverter converter = new DefaultPahoMessageConverter();
// use byte types uniformly
diff --git a/src/main/java/com/dji/sample/component/mqtt/model/MapKeyConst.java b/src/main/java/com/dji/sample/component/mqtt/model/MapKeyConst.java
index 242fd3d..0e4f498 100644
--- a/src/main/java/com/dji/sample/component/mqtt/model/MapKeyConst.java
+++ b/src/main/java/com/dji/sample/component/mqtt/model/MapKeyConst.java
@@ -33,4 +33,6 @@
public static final String FLIGHT_IDS = "flight_ids";
+ public static final String ACL = "acl";
+
}
diff --git a/src/main/java/com/dji/sample/component/mqtt/model/MqttClientOptions.java b/src/main/java/com/dji/sample/component/mqtt/model/MqttClientOptions.java
new file mode 100644
index 0000000..d1168bd
--- /dev/null
+++ b/src/main/java/com/dji/sample/component/mqtt/model/MqttClientOptions.java
@@ -0,0 +1,31 @@
+package com.dji.sample.component.mqtt.model;
+
+import lombok.Data;
+
+/**
+ * @author sean
+ * @version 1.3
+ * @date 2023/1/18
+ */
+@Data
+public class MqttClientOptions {
+
+ private MqttProtocolEnum protocol;
+
+ private String host;
+
+ private Integer port;
+
+ private String username;
+
+ private String password;
+
+ private String clientId;
+
+ private String path;
+
+ /**
+ * The topic to subscribe to immediately when client connects. Only required for basic link.
+ */
+ private String inboundTopic;
+}
diff --git a/src/main/java/com/dji/sample/component/mqtt/model/MqttProtocolEnum.java b/src/main/java/com/dji/sample/component/mqtt/model/MqttProtocolEnum.java
new file mode 100644
index 0000000..ac54b1f
--- /dev/null
+++ b/src/main/java/com/dji/sample/component/mqtt/model/MqttProtocolEnum.java
@@ -0,0 +1,30 @@
+package com.dji.sample.component.mqtt.model;
+
+import lombok.Getter;
+
+/**
+ * @author sean
+ * @version 1.3
+ * @date 2023/1/18
+ */
+@Getter
+public enum MqttProtocolEnum {
+
+ MQTT("tcp"),
+
+ MQTTS("tcp"),
+
+ WS("ws"),
+
+ WSS("wss");
+
+ String protocol;
+
+ MqttProtocolEnum(String protocol) {
+ this.protocol = protocol;
+ }
+
+ public String getProtocolAddr() {
+ return protocol + "://";
+ }
+}
diff --git a/src/main/java/com/dji/sample/component/mqtt/model/MqttUseEnum.java b/src/main/java/com/dji/sample/component/mqtt/model/MqttUseEnum.java
new file mode 100644
index 0000000..3f56704
--- /dev/null
+++ b/src/main/java/com/dji/sample/component/mqtt/model/MqttUseEnum.java
@@ -0,0 +1,19 @@
+package com.dji.sample.component.mqtt.model;
+
+/**
+ * @author sean
+ * @version 1.3
+ * @date 2023/1/18
+ */
+public enum MqttUseEnum {
+
+ /**
+ * The broker is used for basic link.
+ */
+ BASIC,
+
+ /**
+ * This broker is used for the drc link.
+ */
+ DRC
+}
diff --git a/src/main/java/com/dji/sample/component/mqtt/service/impl/MessageSenderServiceImpl.java b/src/main/java/com/dji/sample/component/mqtt/service/impl/MessageSenderServiceImpl.java
index 89e5093..2a76cf5 100644
--- a/src/main/java/com/dji/sample/component/mqtt/service/impl/MessageSenderServiceImpl.java
+++ b/src/main/java/com/dji/sample/component/mqtt/service/impl/MessageSenderServiceImpl.java
@@ -31,7 +31,7 @@
public void publish(String topic, CommonTopicResponse response) {
try {
-
+ log.info("send topic: {}, payload: {}", topic, response.toString());
messageGateway.publish(topic, mapper.writeValueAsBytes(response));
} catch (JsonProcessingException e) {
log.info("Failed to publish the message. {}", response.toString());
@@ -53,6 +53,7 @@
}
public <T> T publishWithReply(Class<T> clazz, String topic, CommonTopicResponse response, int retryTime) {
+ log.info("send topic: {}, payload: {}", topic, response.toString());
AtomicInteger time = new AtomicInteger(0);
// Retry three times
while (time.getAndIncrement() <= retryTime) {
diff --git a/src/main/java/com/dji/sample/component/redis/RedisConst.java b/src/main/java/com/dji/sample/component/redis/RedisConst.java
index 39c686b..7ae29db 100644
--- a/src/main/java/com/dji/sample/component/redis/RedisConst.java
+++ b/src/main/java/com/dji/sample/component/redis/RedisConst.java
@@ -9,6 +9,8 @@
*/
public final class RedisConst {
+ public static final int WAYLINE_JOB_BLOCK_TIME = 600;
+
private RedisConst() {
}
@@ -35,11 +37,23 @@
public static final String LOGS_FILE_PREFIX = "logs_file" + DELIMITER;
- public static final String WAYLINE_JOB = "wayline_job";
+ public static final String WAYLINE_JOB_TIMED_EXECUTE = "wayline_job_timed_execute";
+
+ public static final String WAYLINE_JOB_BLOCK_PREFIX = "wayline_job_block" + DELIMITER;
+
+ public static final String WAYLINE_JOB_RUNNING_PREFIX = "wayline_job_running" + DELIMITER;
+
+ public static final String WAYLINE_JOB_PAUSED_PREFIX = "wayline_job_paused" + DELIMITER;
public static final String OSD_PREFIX = "osd" + DELIMITER;
public static final String MEDIA_FILE_PREFIX = "media_file" + DELIMITER;
public static final String MEDIA_HIGHEST_PRIORITY_PREFIX = "media_highest_priority" + DELIMITER;
+
+ public static final String LIVE_CAPACITY = "live_capacity";
+
+ public static final String MQTT_ACL_PREFIX = "mqtt_acl" + DELIMITER;
+
+ public static final String FILE_UPLOADING_PREFIX = "file_uploading" + DELIMITER;
}
diff --git a/src/main/java/com/dji/sample/component/redis/RedisOpsUtils.java b/src/main/java/com/dji/sample/component/redis/RedisOpsUtils.java
index f71dd1c..a3e83b3 100644
--- a/src/main/java/com/dji/sample/component/redis/RedisOpsUtils.java
+++ b/src/main/java/com/dji/sample/component/redis/RedisOpsUtils.java
@@ -251,4 +251,13 @@
return redisTemplate.opsForZSet().score(key, value);
}
+ /**
+ * ZINCRBY
+ * @param key
+ * @param value
+ * @param delta
+ */
+ public static Double zIncrement(String key, Object value, double delta) {
+ return redisTemplate.opsForZSet().incrementScore(key, value, delta);
+ }
}
diff --git a/src/main/java/com/dji/sample/control/service/impl/ControlServiceImpl.java b/src/main/java/com/dji/sample/control/service/impl/ControlServiceImpl.java
index 43e7fc1..beb1e29 100644
--- a/src/main/java/com/dji/sample/control/service/impl/ControlServiceImpl.java
+++ b/src/main/java/com/dji/sample/control/service/impl/ControlServiceImpl.java
@@ -91,7 +91,8 @@
serviceReplyOpt, new TypeReference<ServiceReply<EventsOutputReceiver>>() {});
if (ResponseResult.CODE_SUCCESS != serviceReply.getResult()) {
return ResponseResult.error(serviceReply.getResult(),
- Objects.nonNull(serviceReply.getOutput()) ? serviceReply.getOutput().getStatus() : "error: " + serviceIdentifier);
+ Objects.nonNull(serviceReply.getOutput()) ? serviceReply.getOutput().getStatus()
+ : "error: " + serviceIdentifier + serviceReply.getResult());
}
if (controlMethodEnum.getProgress()) {
RedisOpsUtils.setWithExpire(serviceIdentifier + RedisConst.DELIMITER + bid, sn,
diff --git a/src/main/java/com/dji/sample/manage/controller/DeviceController.java b/src/main/java/com/dji/sample/manage/controller/DeviceController.java
index 602e8c9..9fcc72d 100644
--- a/src/main/java/com/dji/sample/manage/controller/DeviceController.java
+++ b/src/main/java/com/dji/sample/manage/controller/DeviceController.java
@@ -120,7 +120,7 @@
*/
@GetMapping("/{workspace_id}/devices/bound")
public ResponseResult<PaginationData<DeviceDTO>> getBoundDevicesWithDomain(
- @PathVariable("workspace_id") String workspaceId, String domain,
+ @PathVariable("workspace_id") String workspaceId, Integer domain,
@RequestParam(defaultValue = "1") Long page,
@RequestParam(value = "page_size", defaultValue = "50") Long pageSize) {
PaginationData<DeviceDTO> devices = deviceService.getBoundDevicesWithDomain(workspaceId, page, pageSize, domain);
diff --git a/src/main/java/com/dji/sample/manage/controller/DeviceFirmwareController.java b/src/main/java/com/dji/sample/manage/controller/DeviceFirmwareController.java
index 13b2ff3..45a2770 100644
--- a/src/main/java/com/dji/sample/manage/controller/DeviceFirmwareController.java
+++ b/src/main/java/com/dji/sample/manage/controller/DeviceFirmwareController.java
@@ -18,9 +18,9 @@
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
-import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
+import java.util.stream.Collectors;
import static com.dji.sample.component.AuthInterceptor.TOKEN_CLAIM;
@@ -44,11 +44,13 @@
*/
@GetMapping("/firmware-release-notes/latest")
public ResponseResult<List<DeviceFirmwareNoteDTO>> getLatestFirmwareNote(@RequestParam("device_name") List<String> deviceNames) {
- List<DeviceFirmwareNoteDTO> releaseNotes = new ArrayList<>();
- deviceNames.forEach(deviceName -> {
- Optional<DeviceFirmwareNoteDTO> latestFirmware = service.getLatestFirmwareReleaseNote(deviceName);
- latestFirmware.ifPresent(releaseNotes::add);
- });
+
+ List<DeviceFirmwareNoteDTO> releaseNotes = deviceNames.stream()
+ .map(deviceName -> service.getLatestFirmwareReleaseNote(deviceName))
+ .filter(Optional::isPresent)
+ .map(Optional::get)
+ .collect(Collectors.toList());
+
return ResponseResult.success(releaseNotes);
}
@@ -98,7 +100,7 @@
* @return
*/
@PutMapping("/{workspace_id}/firmwares/{firmware_id}")
- public ResponseResult importFirmwareFile(@PathVariable("workspace_id") String workspaceId,
+ public ResponseResult changeFirmwareStatus(@PathVariable("workspace_id") String workspaceId,
@PathVariable("firmware_id") String firmwareId,
@Valid @RequestBody DeviceFirmwareUpdateParam param) {
diff --git a/src/main/java/com/dji/sample/manage/dao/IDeviceFirmwareMapper.java b/src/main/java/com/dji/sample/manage/dao/IDeviceFirmwareMapper.java
index 55653f5..bc4c4a2 100644
--- a/src/main/java/com/dji/sample/manage/dao/IDeviceFirmwareMapper.java
+++ b/src/main/java/com/dji/sample/manage/dao/IDeviceFirmwareMapper.java
@@ -1,7 +1,12 @@
package com.dji.sample.manage.dao;
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.toolkit.Constants;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dji.sample.manage.model.entity.DeviceFirmwareEntity;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
/**
* @author sean
@@ -9,4 +14,26 @@
* @date 2022/8/16
*/
public interface IDeviceFirmwareMapper extends BaseMapper<DeviceFirmwareEntity> {
+ String sql = "<script> \n" +
+ "SELECT \n" +
+ " * \n" +
+ "from \n" +
+ " (\n" +
+ " select \n" +
+ " a.*, \n" +
+ " group_concat(b.device_name) device_name \n" +
+ " from \n" +
+ " manage_device_firmware a \n" +
+ " join manage_firmware_model b on a.firmware_id = b.firmware_id \n" +
+ " <if test='device_name != null and device_name != \"\"'> \n" +
+ " and b.device_name = #{device_name} \n" +
+ " </if> \n" +
+ " group by firmware_id \n" +
+ " ) c ${ew.customSqlSegment} \n";
+
+ @Select(sql + "</script>")
+ Page<DeviceFirmwareEntity> selectPage(Page page, @Param(Constants.WRAPPER)Wrapper<DeviceFirmwareEntity> wrapper, @Param("device_name") String deviceName);
+
+ @Select(sql + " limit 1 </script>")
+ DeviceFirmwareEntity selectOne(@Param(Constants.WRAPPER)Wrapper<DeviceFirmwareEntity> wrapper, @Param("device_name") String deviceName);
}
diff --git a/src/main/java/com/dji/sample/manage/dao/IFirmwareModelMapper.java b/src/main/java/com/dji/sample/manage/dao/IFirmwareModelMapper.java
new file mode 100644
index 0000000..9cb8ee3
--- /dev/null
+++ b/src/main/java/com/dji/sample/manage/dao/IFirmwareModelMapper.java
@@ -0,0 +1,12 @@
+package com.dji.sample.manage.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.dji.sample.manage.model.entity.FirmwareModelEntity;
+
+/**
+ * @author sean
+ * @version 1.3
+ * @date 2022/12/21
+ */
+public interface IFirmwareModelMapper extends BaseMapper<FirmwareModelEntity> {
+}
diff --git a/src/main/java/com/dji/sample/manage/model/common/AppLicenseProperties.java b/src/main/java/com/dji/sample/manage/model/common/AppLicenseProperties.java
new file mode 100644
index 0000000..cc15023
--- /dev/null
+++ b/src/main/java/com/dji/sample/manage/model/common/AppLicenseProperties.java
@@ -0,0 +1,32 @@
+package com.dji.sample.manage.model.common;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author sean
+ * @version 1.3.1
+ * @date 2023/1/5
+ */
+@Component
+@ConfigurationProperties("cloud-api.app")
+public class AppLicenseProperties {
+
+ public static String id;
+
+ public static String key;
+
+ public static String license;
+
+ public void setId(String id) {
+ AppLicenseProperties.id = id;
+ }
+
+ public void setKey(String key) {
+ AppLicenseProperties.key = key;
+ }
+
+ public void setLicense(String license) {
+ AppLicenseProperties.license = license;
+ }
+}
diff --git a/src/main/java/com/dji/sample/manage/model/dto/DeviceDTO.java b/src/main/java/com/dji/sample/manage/model/dto/DeviceDTO.java
index ce23314..68466d7 100644
--- a/src/main/java/com/dji/sample/manage/model/dto/DeviceDTO.java
+++ b/src/main/java/com/dji/sample/manage/model/dto/DeviceDTO.java
@@ -31,13 +31,11 @@
private String childDeviceSn;
- private String domain;
+ private Integer domain;
private Integer type;
private Integer subType;
-
- private List<DeviceDTO> gatewaysList;
private List<DevicePayloadDTO> payloadsList;
diff --git a/src/main/java/com/dji/sample/manage/model/dto/DeviceFirmwareDTO.java b/src/main/java/com/dji/sample/manage/model/dto/DeviceFirmwareDTO.java
index 3d48f78..b59f289 100644
--- a/src/main/java/com/dji/sample/manage/model/dto/DeviceFirmwareDTO.java
+++ b/src/main/java/com/dji/sample/manage/model/dto/DeviceFirmwareDTO.java
@@ -6,6 +6,7 @@
import lombok.NoArgsConstructor;
import java.time.LocalDate;
+import java.util.List;
/**
* @author sean
@@ -30,7 +31,7 @@
private String fileMd5;
- private String deviceName;
+ private List<String> deviceName;
private String releaseNote;
diff --git a/src/main/java/com/dji/sample/manage/model/dto/FirmwareModelDTO.java b/src/main/java/com/dji/sample/manage/model/dto/FirmwareModelDTO.java
new file mode 100644
index 0000000..d9f10f5
--- /dev/null
+++ b/src/main/java/com/dji/sample/manage/model/dto/FirmwareModelDTO.java
@@ -0,0 +1,24 @@
+package com.dji.sample.manage.model.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+/**
+ * @author sean
+ * @version 1.3
+ * @date 2022/12/21
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class FirmwareModelDTO {
+
+ private String firmwareId;
+
+ private List<String> deviceNames;
+}
diff --git a/src/main/java/com/dji/sample/manage/model/dto/LogsUploadCredentialsDTO.java b/src/main/java/com/dji/sample/manage/model/dto/LogsUploadCredentialsDTO.java
index f156c3a..970fc12 100644
--- a/src/main/java/com/dji/sample/manage/model/dto/LogsUploadCredentialsDTO.java
+++ b/src/main/java/com/dji/sample/manage/model/dto/LogsUploadCredentialsDTO.java
@@ -35,13 +35,16 @@
private LogsFileUploadList params;
+ private String region;
+
public LogsUploadCredentialsDTO(StsCredentialsDTO sts) {
this.bucket = sts.getBucket();
- Long expire = sts.getCredentials().getExpire();
+ long expire = sts.getCredentials().getExpire();
sts.getCredentials().setExpire(System.currentTimeMillis() + (expire - 60) * 1000);
this.credentials = sts.getCredentials();
this.endpoint = sts.getEndpoint();
this.objectKeyPrefix = sts.getObjectKeyPrefix();
this.provider = sts.getProvider();
+ this.region = sts.getRegion();
}
}
diff --git a/src/main/java/com/dji/sample/manage/model/dto/NtpServerDTO.java b/src/main/java/com/dji/sample/manage/model/dto/ProductConfigDTO.java
similarity index 69%
rename from src/main/java/com/dji/sample/manage/model/dto/NtpServerDTO.java
rename to src/main/java/com/dji/sample/manage/model/dto/ProductConfigDTO.java
index 27b05a5..577ba54 100644
--- a/src/main/java/com/dji/sample/manage/model/dto/NtpServerDTO.java
+++ b/src/main/java/com/dji/sample/manage/model/dto/ProductConfigDTO.java
@@ -12,7 +12,13 @@
@Data
@AllArgsConstructor
@NoArgsConstructor
-public class NtpServerDTO {
+public class ProductConfigDTO {
private String ntpServerHost;
+
+ private String appId;
+
+ private String appKey;
+
+ private String appLicense;
}
diff --git a/src/main/java/com/dji/sample/manage/model/dto/TopologyDeviceDTO.java b/src/main/java/com/dji/sample/manage/model/dto/TopologyDeviceDTO.java
index ced5277..ea709cc 100644
--- a/src/main/java/com/dji/sample/manage/model/dto/TopologyDeviceDTO.java
+++ b/src/main/java/com/dji/sample/manage/model/dto/TopologyDeviceDTO.java
@@ -38,5 +38,5 @@
private String gatewaySn;
- private String domain;
+ private Integer domain;
}
diff --git a/src/main/java/com/dji/sample/manage/model/entity/DeviceFirmwareEntity.java b/src/main/java/com/dji/sample/manage/model/entity/DeviceFirmwareEntity.java
index 369f4c6..ced8e39 100644
--- a/src/main/java/com/dji/sample/manage/model/entity/DeviceFirmwareEntity.java
+++ b/src/main/java/com/dji/sample/manage/model/entity/DeviceFirmwareEntity.java
@@ -43,7 +43,7 @@
@TableField("file_md5")
private String fileMd5;
- @TableField("device_name")
+ @TableField(exist = false)
private String deviceName;
@TableField("release_note")
diff --git a/src/main/java/com/dji/sample/manage/model/entity/FirmwareModelEntity.java b/src/main/java/com/dji/sample/manage/model/entity/FirmwareModelEntity.java
new file mode 100644
index 0000000..5c8707d
--- /dev/null
+++ b/src/main/java/com/dji/sample/manage/model/entity/FirmwareModelEntity.java
@@ -0,0 +1,37 @@
+package com.dji.sample.manage.model.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * @author sean
+ * @version 1.3
+ * @date 2022/12/21
+ */
+@Data
+@TableName("manage_firmware_model")
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class FirmwareModelEntity implements Serializable {
+
+ @TableId(type = IdType.AUTO)
+ private Long id;
+
+ @TableField("firmware_id")
+ private String firmwareId;
+
+ @TableField("device_name")
+ private String deviceName;
+
+ @TableField(value = "create_time", fill = FieldFill.INSERT)
+ private Long createTime;
+
+ @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
+ private Long updateTime;
+}
diff --git a/src/main/java/com/dji/sample/manage/model/enums/DeviceDomainEnum.java b/src/main/java/com/dji/sample/manage/model/enums/DeviceDomainEnum.java
index 76b9c4d..22475b2 100644
--- a/src/main/java/com/dji/sample/manage/model/enums/DeviceDomainEnum.java
+++ b/src/main/java/com/dji/sample/manage/model/enums/DeviceDomainEnum.java
@@ -1,77 +1,27 @@
package com.dji.sample.manage.model.enums;
+import lombok.Getter;
+
/**
*
* @author sean.zhou
* @date 2021/11/15
* @version 0.1
*/
+@Getter
public enum DeviceDomainEnum {
- SUB_DEVICE(0, "sub-device"),
+ SUB_DEVICE(0),
- GATEWAY(2, "gateway"),
+ GATEWAY(2),
- PAYLOAD(1, "payload"),
+ PAYLOAD(1),
- DOCK (3, "dock"),
+ DOCK (3);
- UNKNOWN(-1, "unknown");
+ int val;
- private int val;
-
- private String desc;
-
- DeviceDomainEnum(int val, String desc) {
+ DeviceDomainEnum(int val) {
this.val = val;
- this.desc = desc;
}
-
- public int getVal() {
- return val;
- }
-
- public String getDesc() {
- return desc;
- }
-
- public static String getDesc(int val) {
- if (SUB_DEVICE.val == val) {
- return SUB_DEVICE.desc;
- }
-
- if (GATEWAY.val == val) {
- return GATEWAY.desc;
- }
-
- if (PAYLOAD.val == val) {
- return PAYLOAD.desc;
- }
-
- if (DOCK.val == val) {
- return DOCK.desc;
- }
- return UNKNOWN.desc;
- }
-
- public static int getVal(String desc) {
- if (SUB_DEVICE.desc.equals(desc)) {
- return SUB_DEVICE.val;
- }
-
- if (GATEWAY.desc.equals(desc)) {
- return GATEWAY.val;
- }
-
- if (PAYLOAD.desc.equals(desc)) {
- return PAYLOAD.val;
- }
-
- if (DOCK.desc.equals(desc)) {
- return DOCK.val;
- }
- return UNKNOWN.val;
- }
-
-
}
diff --git a/src/main/java/com/dji/sample/manage/model/param/DeviceFirmwareUploadParam.java b/src/main/java/com/dji/sample/manage/model/param/DeviceFirmwareUploadParam.java
index 41a1b31..f48f4f0 100644
--- a/src/main/java/com/dji/sample/manage/model/param/DeviceFirmwareUploadParam.java
+++ b/src/main/java/com/dji/sample/manage/model/param/DeviceFirmwareUploadParam.java
@@ -3,6 +3,7 @@
import lombok.Data;
import javax.validation.constraints.NotNull;
+import java.util.List;
/**
* @author sean
@@ -19,5 +20,5 @@
private Boolean status;
@NotNull
- private String deviceName;
+ private List<String> deviceName;
}
diff --git a/src/main/java/com/dji/sample/manage/model/receiver/DistanceLimitStatusReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/DistanceLimitStatusReceiver.java
index 3ae7a74..1fb2789 100644
--- a/src/main/java/com/dji/sample/manage/model/receiver/DistanceLimitStatusReceiver.java
+++ b/src/main/java/com/dji/sample/manage/model/receiver/DistanceLimitStatusReceiver.java
@@ -35,7 +35,7 @@
valid = StateSwitchEnum.find(state).isPresent();
}
if (Objects.nonNull(distanceLimit)) {
- valid &= StateSwitchEnum.find(distanceLimit).isPresent();
+ valid &= distanceLimit >= DISTANCE_MIN && distanceLimit <= DISTANCE_MAX;
}
return valid;
}
diff --git a/src/main/java/com/dji/sample/manage/service/IDeviceFirmwareService.java b/src/main/java/com/dji/sample/manage/service/IDeviceFirmwareService.java
index 88dc3b0..2d82e7b 100644
--- a/src/main/java/com/dji/sample/manage/service/IDeviceFirmwareService.java
+++ b/src/main/java/com/dji/sample/manage/service/IDeviceFirmwareService.java
@@ -23,11 +23,13 @@
/**
* Query specific firmware information based on the device model and firmware version.
+ *
+ * @param workspaceId
* @param deviceName
* @param version
* @return
*/
- Optional<DeviceFirmwareDTO> getFirmware(String deviceName, String version);
+ Optional<DeviceFirmwareDTO> getFirmware(String workspaceId, String deviceName, String version);
/**
* Get the latest firmware release note for this device model.
@@ -38,10 +40,12 @@
/**
* Get the firmware information that the device needs to update.
+ *
+ * @param workspaceId
* @param upgradeDTOS
* @return
*/
- List<DeviceOtaCreateParam> getDeviceOtaFirmware(List<DeviceFirmwareUpgradeDTO> upgradeDTOS);
+ List<DeviceOtaCreateParam> getDeviceOtaFirmware(String workspaceId, List<DeviceFirmwareUpgradeDTO> upgradeDTOS);
/**
* Interface to handle device firmware update progress.
@@ -80,8 +84,9 @@
/**
* Save the file information of the firmware.
* @param firmware
+ * @param deviceNames
*/
- void saveFirmwareInfo(DeviceFirmwareDTO firmware);
+ void saveFirmwareInfo(DeviceFirmwareDTO firmware, List<String> deviceNames);
/**
* Update the file information of the firmware.
diff --git a/src/main/java/com/dji/sample/manage/service/IDeviceService.java b/src/main/java/com/dji/sample/manage/service/IDeviceService.java
index ff41435..11bb1d7 100644
--- a/src/main/java/com/dji/sample/manage/service/IDeviceService.java
+++ b/src/main/java/com/dji/sample/manage/service/IDeviceService.java
@@ -180,7 +180,7 @@
* @param domain
* @return
*/
- PaginationData<DeviceDTO> getBoundDevicesWithDomain(String workspaceId, Long page, Long pageSize, String domain);
+ PaginationData<DeviceDTO> getBoundDevicesWithDomain(String workspaceId, Long page, Long pageSize, Integer domain);
/**
* Unbind device base on device's sn.
diff --git a/src/main/java/com/dji/sample/manage/service/IFirmwareModelService.java b/src/main/java/com/dji/sample/manage/service/IFirmwareModelService.java
new file mode 100644
index 0000000..4aaaa81
--- /dev/null
+++ b/src/main/java/com/dji/sample/manage/service/IFirmwareModelService.java
@@ -0,0 +1,18 @@
+package com.dji.sample.manage.service;
+
+import com.dji.sample.manage.model.dto.FirmwareModelDTO;
+
+/**
+ * @author sean
+ * @version 1.3
+ * @date 2022/12/21
+ */
+public interface IFirmwareModelService {
+
+ /**
+ * Save the relationship between firmware files and device models.
+ * @param firmwareModel
+ */
+ void saveFirmwareDeviceName(FirmwareModelDTO firmwareModel);
+
+}
diff --git a/src/main/java/com/dji/sample/manage/service/impl/AbstractTSAService.java b/src/main/java/com/dji/sample/manage/service/impl/AbstractTSAService.java
index 56b8217..91e390a 100644
--- a/src/main/java/com/dji/sample/manage/service/impl/AbstractTSAService.java
+++ b/src/main/java/com/dji/sample/manage/service/impl/AbstractTSAService.java
@@ -1,7 +1,6 @@
package com.dji.sample.manage.service.impl;
import com.dji.sample.component.mqtt.model.CommonTopicReceiver;
-import com.dji.sample.component.redis.RedisOpsUtils;
import com.dji.sample.component.websocket.config.ConcurrentWebSocketSession;
import com.dji.sample.component.websocket.model.BizCodeEnum;
import com.dji.sample.component.websocket.model.CustomWebSocketMessage;
@@ -27,9 +26,6 @@
@Autowired
protected ObjectMapper mapper;
-
- @Autowired
- protected RedisOpsUtils redisOps;
@Autowired
private IWebSocketManageService webSocketManageService;
diff --git a/src/main/java/com/dji/sample/manage/service/impl/ConfigProductServiceImpl.java b/src/main/java/com/dji/sample/manage/service/impl/ConfigProductServiceImpl.java
index b117586..2b2f59f 100644
--- a/src/main/java/com/dji/sample/manage/service/impl/ConfigProductServiceImpl.java
+++ b/src/main/java/com/dji/sample/manage/service/impl/ConfigProductServiceImpl.java
@@ -1,7 +1,8 @@
package com.dji.sample.manage.service.impl;
+import com.dji.sample.manage.model.common.AppLicenseProperties;
import com.dji.sample.manage.model.common.NtpServerProperties;
-import com.dji.sample.manage.model.dto.NtpServerDTO;
+import com.dji.sample.manage.model.dto.ProductConfigDTO;
import com.dji.sample.manage.service.IRequestsConfigService;
import org.springframework.stereotype.Service;
@@ -15,6 +16,6 @@
@Override
public Object getConfig() {
- return new NtpServerDTO(NtpServerProperties.host);
+ return new ProductConfigDTO(NtpServerProperties.host, AppLicenseProperties.id, AppLicenseProperties.key, AppLicenseProperties.license);
}
}
diff --git a/src/main/java/com/dji/sample/manage/service/impl/DeviceFirmwareServiceImpl.java b/src/main/java/com/dji/sample/manage/service/impl/DeviceFirmwareServiceImpl.java
index e2f240e..6b99d38 100644
--- a/src/main/java/com/dji/sample/manage/service/impl/DeviceFirmwareServiceImpl.java
+++ b/src/main/java/com/dji/sample/manage/service/impl/DeviceFirmwareServiceImpl.java
@@ -2,6 +2,7 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dji.sample.common.model.Pagination;
import com.dji.sample.common.model.PaginationData;
@@ -12,6 +13,7 @@
import com.dji.sample.component.oss.service.impl.OssServiceContext;
import com.dji.sample.component.redis.RedisConst;
import com.dji.sample.component.redis.RedisOpsUtils;
+import com.dji.sample.component.websocket.config.ConcurrentWebSocketSession;
import com.dji.sample.component.websocket.model.CustomWebSocketMessage;
import com.dji.sample.component.websocket.service.IWebSocketManageService;
import com.dji.sample.component.websocket.service.impl.SendMessageServiceImpl;
@@ -24,6 +26,7 @@
import com.dji.sample.manage.model.param.DeviceOtaCreateParam;
import com.dji.sample.manage.service.IDeviceFirmwareService;
import com.dji.sample.manage.service.IDeviceService;
+import com.dji.sample.manage.service.IFirmwareModelService;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
@@ -79,26 +82,30 @@
@Autowired
private OssServiceContext ossServiceContext;
+ @Autowired
+ private IFirmwareModelService firmwareModelService;
+
@Override
- public Optional<DeviceFirmwareDTO> getFirmware(String deviceName, String version) {
+ public Optional<DeviceFirmwareDTO> getFirmware(String workspaceId, String deviceName, String version) {
return Optional.ofNullable(entity2Dto(mapper.selectOne(
new LambdaQueryWrapper<DeviceFirmwareEntity>()
- .eq(DeviceFirmwareEntity::getDeviceName, deviceName)
- .eq(DeviceFirmwareEntity::getFirmwareVersion, version))));
+ .eq(DeviceFirmwareEntity::getWorkspaceId, workspaceId)
+ .eq(DeviceFirmwareEntity::getFirmwareVersion, version)
+ .eq(DeviceFirmwareEntity::getStatus, true),
+ deviceName)));
}
@Override
public Optional<DeviceFirmwareNoteDTO> getLatestFirmwareReleaseNote(String deviceName) {
return Optional.ofNullable(entity2NoteDto(mapper.selectOne(
- new LambdaQueryWrapper<DeviceFirmwareEntity>()
- .eq(DeviceFirmwareEntity::getDeviceName, deviceName)
+ Wrappers.lambdaQuery(DeviceFirmwareEntity.class)
.eq(DeviceFirmwareEntity::getStatus, true)
- .orderByDesc(DeviceFirmwareEntity::getReleaseDate, DeviceFirmwareEntity::getFirmwareVersion)
- .last(" limit 1 "))));
+ .orderByDesc(DeviceFirmwareEntity::getReleaseDate, DeviceFirmwareEntity::getFirmwareVersion),
+ deviceName)));
}
@Override
- public List<DeviceOtaCreateParam> getDeviceOtaFirmware(List<DeviceFirmwareUpgradeDTO> upgradeDTOS) {
+ public List<DeviceOtaCreateParam> getDeviceOtaFirmware(String workspaceId, List<DeviceFirmwareUpgradeDTO> upgradeDTOS) {
List<DeviceOtaCreateParam> deviceOtaList = new ArrayList<>();
upgradeDTOS.forEach(upgradeDevice -> {
boolean exist = deviceService.checkDeviceOnline(upgradeDevice.getSn());
@@ -106,12 +113,9 @@
throw new IllegalArgumentException("Device is offline.");
}
Optional<DeviceFirmwareDTO> firmwareOpt = this.getFirmware(
- upgradeDevice.getDeviceName(), upgradeDevice.getProductVersion());
+ workspaceId, upgradeDevice.getDeviceName(), upgradeDevice.getProductVersion());
if (firmwareOpt.isEmpty()) {
- throw new IllegalArgumentException("This firmware version does not exist.");
- }
- if (!firmwareOpt.get().getFirmwareStatus()) {
- throw new IllegalArgumentException("This firmware version is not available.");
+ throw new IllegalArgumentException("This firmware version does not exist or is not available.");
}
DeviceOtaCreateParam ota = dto2OtaCreateDto(firmwareOpt.get());
ota.setSn(upgradeDevice.getSn());
@@ -131,7 +135,6 @@
EventsReceiver<EventsOutputReceiver> eventsReceiver = objectMapper.convertValue(receiver.getData(),
new TypeReference<EventsReceiver<EventsOutputReceiver>>(){});
eventsReceiver.setBid(receiver.getBid());
- eventsReceiver.setSn(sn);
EventsOutputReceiver output = eventsReceiver.getOutput();
log.info("SN: {}, {} ===> Upgrading progress: {}",
@@ -148,6 +151,13 @@
// Determine whether it is the ending state, delete the update state key in redis after the job ends.
EventsResultStatusEnum statusEnum = EventsResultStatusEnum.find(output.getStatus());
+ Collection<ConcurrentWebSocketSession> sessions = webSocketManageService.getValueWithWorkspaceAndUserType(
+ device.getWorkspaceId(), UserTypeEnum.WEB.getVal());
+ CustomWebSocketMessage<Object> build = CustomWebSocketMessage.builder()
+ .data(eventsReceiver)
+ .timestamp(System.currentTimeMillis())
+ .bizCode(receiver.getMethod())
+ .build();
if (upgrade) {
if (statusEnum.getEnd()) {
// Delete the cache after the update is complete.
@@ -158,8 +168,14 @@
RedisConst.FIRMWARE_UPGRADING_PREFIX + sn, output.getProgress().getPercent(),
RedisConst.DEVICE_ALIVE_SECOND * RedisConst.DEVICE_ALIVE_SECOND);
}
+ eventsReceiver.setSn(sn);
+ webSocketMessageService.sendBatch(sessions, build);
}
if (childUpgrade) {
+ if (!StringUtils.hasText(eventsReceiver.getSn())) {
+ eventsReceiver.setSn(childDeviceSn);
+ webSocketMessageService.sendBatch(sessions, build);
+ }
if (statusEnum.getEnd()) {
RedisOpsUtils.del(RedisConst.FIRMWARE_UPGRADING_PREFIX + childDeviceSn);
} else {
@@ -169,15 +185,6 @@
RedisConst.DEVICE_ALIVE_SECOND * RedisConst.DEVICE_ALIVE_SECOND);
}
}
-
- webSocketMessageService.sendBatch(
- webSocketManageService.getValueWithWorkspaceAndUserType(
- device.getWorkspaceId(), UserTypeEnum.WEB.getVal()),
- CustomWebSocketMessage.builder()
- .data(eventsReceiver)
- .timestamp(System.currentTimeMillis())
- .bizCode(receiver.getMethod())
- .build());
if (receiver.getNeedReply() != null && receiver.getNeedReply() == 1) {
String replyTopic = headers.get(MqttHeaders.RECEIVED_TOPIC) + TopicConst._REPLY_SUF;
@@ -194,7 +201,8 @@
@Override
public Boolean checkFileExist(String workspaceId, String fileMd5) {
- return mapper.selectCount(new LambdaQueryWrapper<DeviceFirmwareEntity>()
+ return RedisOpsUtils.checkExist(RedisConst.FILE_UPLOADING_PREFIX + workspaceId + fileMd5) ||
+ mapper.selectCount(new LambdaQueryWrapper<DeviceFirmwareEntity>()
.eq(DeviceFirmwareEntity::getWorkspaceId, workspaceId)
.eq(DeviceFirmwareEntity::getFileMd5, fileMd5))
> 0;
@@ -206,9 +214,8 @@
new LambdaQueryWrapper<DeviceFirmwareEntity>()
.eq(DeviceFirmwareEntity::getWorkspaceId, workspaceId)
.eq(Objects.nonNull(param.getStatus()), DeviceFirmwareEntity::getStatus, param.getStatus())
- .eq(StringUtils.hasText(param.getDeviceName()), DeviceFirmwareEntity::getDeviceName, param.getDeviceName())
.like(StringUtils.hasText(param.getProductVersion()), DeviceFirmwareEntity::getFirmwareVersion, param.getProductVersion())
- .orderByDesc(DeviceFirmwareEntity::getReleaseDate));
+ .orderByDesc(DeviceFirmwareEntity::getReleaseDate), param.getDeviceName());
List<DeviceFirmwareDTO> data = page.getRecords().stream().map(this::entity2Dto).collect(Collectors.toList());
return new PaginationData<DeviceFirmwareDTO>(data, new Pagination(page));
@@ -217,14 +224,21 @@
@Override
public void importFirmwareFile(String workspaceId, String creator, DeviceFirmwareUploadParam param, MultipartFile file) {
+ String key = RedisConst.FILE_UPLOADING_PREFIX + workspaceId;
+ String existKey = key + file.getOriginalFilename();
+ if (RedisOpsUtils.getExpire(existKey) > 0) {
+ throw new RuntimeException("Please try again later.");
+ }
+ RedisOpsUtils.setWithExpire(existKey, true, RedisConst.DEVICE_ALIVE_SECOND);
try (InputStream is = file.getInputStream()) {
long size = is.available();
String md5 = DigestUtils.md5DigestAsHex(is);
+ key += md5;
boolean exist = checkFileExist(workspaceId, md5);
if (exist) {
throw new RuntimeException("The file already exists.");
}
-
+ RedisOpsUtils.set(key, System.currentTimeMillis());
Optional<DeviceFirmwareDTO> firmwareOpt = verifyFirmwareFile(file);
if (firmwareOpt.isEmpty()) {
throw new RuntimeException("The file format is incorrect.");
@@ -234,9 +248,8 @@
String objectKey = OssConfiguration.objectDirPrefix + File.separator + firmwareId + FirmwareFileProperties.FIRMWARE_FILE_SUFFIX;
ossServiceContext.putObject(OssConfiguration.bucket, objectKey, file.getInputStream());
- log.info("upload success");
+ log.info("upload success. {}", file.getOriginalFilename());
DeviceFirmwareDTO firmware = DeviceFirmwareDTO.builder()
- .deviceName(param.getDeviceName())
.releaseNote(param.getReleaseNote())
.firmwareStatus(param.getStatus())
.fileMd5(md5)
@@ -250,15 +263,20 @@
.firmwareId(firmwareId)
.build();
- saveFirmwareInfo(firmware);
+ saveFirmwareInfo(firmware, param.getDeviceName());
} catch (IOException e) {
e.printStackTrace();
+ } finally {
+ RedisOpsUtils.del(key);
}
}
@Override
- public void saveFirmwareInfo(DeviceFirmwareDTO firmware) {
- mapper.insert(dto2Entity(firmware));
+ public void saveFirmwareInfo(DeviceFirmwareDTO firmware, List<String> deviceNames) {
+ DeviceFirmwareEntity entity = dto2Entity(firmware);
+ mapper.insert(entity);
+ firmwareModelService.saveFirmwareDeviceName(
+ FirmwareModelDTO.builder().firmwareId(entity.getFirmwareId()).deviceNames(deviceNames).build());
}
@Override
@@ -308,7 +326,6 @@
}
return DeviceFirmwareEntity.builder()
.fileName(dto.getFileName())
- .deviceName(dto.getDeviceName())
.fileMd5(dto.getFileMd5())
.fileSize(dto.getFileSize())
.firmwareId(dto.getFirmwareId())
@@ -340,7 +357,7 @@
return null;
}
return DeviceFirmwareDTO.builder()
- .deviceName(entity.getDeviceName())
+ .deviceName(Arrays.asList(entity.getDeviceName().split(",")))
.fileMd5(entity.getFileMd5())
.fileSize(entity.getFileSize())
.objectKey(entity.getObjectKey())
diff --git a/src/main/java/com/dji/sample/manage/service/impl/DeviceOSDServiceImpl.java b/src/main/java/com/dji/sample/manage/service/impl/DeviceOSDServiceImpl.java
index 16ed4be..b540e08 100644
--- a/src/main/java/com/dji/sample/manage/service/impl/DeviceOSDServiceImpl.java
+++ b/src/main/java/com/dji/sample/manage/service/impl/DeviceOSDServiceImpl.java
@@ -2,6 +2,7 @@
import com.dji.sample.component.mqtt.model.CommonTopicReceiver;
import com.dji.sample.component.redis.RedisConst;
+import com.dji.sample.component.redis.RedisOpsUtils;
import com.dji.sample.component.websocket.config.ConcurrentWebSocketSession;
import com.dji.sample.component.websocket.model.BizCodeEnum;
import com.dji.sample.component.websocket.model.CustomWebSocketMessage;
@@ -58,7 +59,7 @@
public void handleOSD(CommonTopicReceiver receiver, DeviceDTO device,
Collection<ConcurrentWebSocketSession> webSessions,
CustomWebSocketMessage<TelemetryDTO> wsMessage) {
- if (DeviceDomainEnum.SUB_DEVICE.getDesc().equals(device.getDomain())) {
+ if (DeviceDomainEnum.SUB_DEVICE.getVal() == device.getDomain()) {
wsMessage.setBizCode(BizCodeEnum.DEVICE_OSD.getCode());
OsdSubDeviceReceiver data = mapper.convertValue(receiver.getData(), OsdSubDeviceReceiver.class);
@@ -75,7 +76,7 @@
log.warn("Please remount the payload, or restart the drone. Otherwise the data of the payload will not be received.");
}
- redisOps.setWithExpire(RedisConst.OSD_PREFIX + device.getDeviceSn(), data, RedisConst.DEVICE_ALIVE_SECOND);
+ RedisOpsUtils.setWithExpire(RedisConst.OSD_PREFIX + device.getDeviceSn(), data, RedisConst.DEVICE_ALIVE_SECOND);
wsMessage.getData().setHost(data);
sendMessageService.sendBatch(webSessions, wsMessage);
diff --git a/src/main/java/com/dji/sample/manage/service/impl/DeviceServiceImpl.java b/src/main/java/com/dji/sample/manage/service/impl/DeviceServiceImpl.java
index f37da4b..6677ca8 100644
--- a/src/main/java/com/dji/sample/manage/service/impl/DeviceServiceImpl.java
+++ b/src/main/java/com/dji/sample/manage/service/impl/DeviceServiceImpl.java
@@ -111,8 +111,6 @@
Optional<DeviceDTO> gatewayOpt = this.getDeviceBySn(gatewaySn);
if (gatewayOpt.isPresent()) {
DeviceDTO value = gatewayOpt.get();
- value.setBoundTime(null);
- value.setLoginTime(null);
RedisOpsUtils.setWithExpire(key, value, RedisConst.DEVICE_ALIVE_SECOND);
this.pushDeviceOnlineTopo(value.getWorkspaceId(), gatewaySn, gatewaySn);
return true;
@@ -120,7 +118,7 @@
// When connecting for the first time
DeviceEntity gatewayDevice = deviceGatewayConvertToDeviceEntity(gateway);
- return firstSaveDevice(gatewayDevice, null);
+ return onlineSaveDevice(gatewayDevice, null).isPresent();
}
DeviceDTO deviceDTO = (DeviceDTO) (RedisOpsUtils.get(key));
@@ -151,6 +149,7 @@
RedisOpsUtils.del(key);
RedisOpsUtils.del(RedisConst.OSD_PREFIX + device.getDeviceSn());
+ RedisOpsUtils.del(RedisConst.HMS_PREFIX + device.getDeviceSn());
log.debug("{} offline.", deviceSn);
return true;
}
@@ -185,8 +184,8 @@
DeviceQueryParam.builder()
.childSn(deviceSn)
.build());
- gatewaysList.stream().filter(
- gateway -> !gateway.getDeviceSn().equals(deviceGateway.getSn()))
+ gatewaysList.stream()
+ .filter(gateway -> !gateway.getDeviceSn().equals(deviceGateway.getSn()))
.findAny()
.ifPresent(gateway -> {
gateway.setChildDeviceSn("");
@@ -194,34 +193,33 @@
});
DeviceEntity gateway = deviceGatewayConvertToDeviceEntity(deviceGateway);
- DeviceEntity subDevice = subDeviceConvertToDeviceEntity(deviceGateway.getSubDevices().get(0));
- boolean isSave = firstSaveDevice(gateway, deviceSn) && firstSaveDevice(subDevice, null);
- if (!isSave) {
+ Optional<DeviceEntity> gatewayEntityOpt = onlineSaveDevice(gateway, deviceSn);
+ if (gatewayEntityOpt.isEmpty()) {
+ log.error("Failed to go online, please check the status data or code logic.");
return false;
}
- // dock go online
- if (deviceGateway.getDomain() != null && DeviceDomainEnum.DOCK.getVal() == deviceGateway.getDomain()) {
- Optional<DeviceDTO> deviceOpt = this.getDeviceBySn(deviceGateway.getSn());
- if (deviceOpt.isEmpty()) {
- log.info("The dock is not bound and cannot go online. Please refer to the Cloud API document video for binding.");
- return false;
- }
- gateway.setNickname(null);
- subDevice.setNickname(null);
+ DeviceEntity subDevice = subDeviceConvertToDeviceEntity(deviceGateway.getSubDevices().get(0));
+ Optional<DeviceEntity> subDeviceEntityOpt = onlineSaveDevice(subDevice, null);
+ if (subDeviceEntityOpt.isEmpty()) {
+ log.error("Failed to go online, please check the status data or code logic.");
+ return false;
}
- String workspaceId = subDevice.getWorkspaceId();
+ subDevice = subDeviceEntityOpt.get();
+ gateway = gatewayEntityOpt.get();
- this.subscribeTopicOnline(deviceGateway.getSn());
- if (!StringUtils.hasText(workspaceId)) {
- log.info("The drone is not bound and cannot go online. Please refer to the Cloud API document video for binding.");
- return true;
+ // dock go online
+ if (DeviceDomainEnum.DOCK.getVal() == deviceGateway.getDomain() && !subDevice.getBoundStatus()) {
+ // Directly bind the drone of the dock to the same workspace as the dock.
+ bindDevice(DeviceDTO.builder().deviceSn(deviceSn).workspaceId(gateway.getWorkspaceId()).build());
+ subDevice.setWorkspaceId(gateway.getWorkspaceId());
}
// Subscribe to topic related to drone devices.
+ this.subscribeTopicOnline(deviceGateway.getSn());
this.subscribeTopicOnline(deviceSn);
- this.pushDeviceOnlineTopo(workspaceId, deviceGateway.getSn(), deviceSn);
+ this.pushDeviceOnlineTopo(subDevice.getWorkspaceId(), deviceGateway.getSn(), deviceSn);
log.debug("{} online.", subDevice.getDeviceSn());
return true;
@@ -305,34 +303,33 @@
List<DeviceDTO> devicesList = this.getDevicesByParams(
DeviceQueryParam.builder()
.workspaceId(workspaceId)
- .domains(List.of(DeviceDomainEnum.SUB_DEVICE.getVal()))
+ .domains(List.of(DeviceDomainEnum.GATEWAY.getVal(), DeviceDomainEnum.DOCK.getVal()))
.build());
- devicesList.forEach(device -> {
- this.spliceDeviceTopo(device);
- device.setWorkspaceId(workspaceId);
- device.setStatus(RedisOpsUtils.checkExist(RedisConst.DEVICE_ONLINE_PREFIX + device.getDeviceSn()));
- });
+ devicesList.stream()
+ .filter(gateway -> DeviceDomainEnum.DOCK.getVal() == gateway.getDomain() ||
+ RedisOpsUtils.checkExist(RedisConst.DEVICE_ONLINE_PREFIX + gateway.getDeviceSn()))
+ .forEach(this::spliceDeviceTopo);
+
return devicesList;
}
@Override
- public void spliceDeviceTopo(DeviceDTO device) {
+ public void spliceDeviceTopo(DeviceDTO gateway) {
- // remote controller
- List<DeviceDTO> gatewaysList = getDevicesByParams(
- DeviceQueryParam.builder()
- .childSn(device.getDeviceSn())
- .build());
+ gateway.setStatus(RedisOpsUtils.checkExist(RedisConst.DEVICE_ONLINE_PREFIX + gateway.getDeviceSn()));
+
+ // sub device
+ if (!StringUtils.hasText(gateway.getChildDeviceSn())) {
+ return;
+ }
+
+ DeviceDTO subDevice = getDevicesByParams(DeviceQueryParam.builder().deviceSn(gateway.getChildDeviceSn()).build()).get(0);
+ subDevice.setStatus(RedisOpsUtils.checkExist(RedisConst.DEVICE_ONLINE_PREFIX + subDevice.getDeviceSn()));
+ gateway.setChildren(subDevice);
// payloads
- List<DevicePayloadDTO> payloadsList = payloadService
- .getDevicePayloadEntitiesByDeviceSn(device.getDeviceSn());
-
-
- device.setGatewaysList(gatewaysList);
- device.setPayloadsList(payloadsList);
-
+ subDevice.setPayloadsList(payloadService.getDevicePayloadEntitiesByDeviceSn(gateway.getChildDeviceSn()));
}
@Override
@@ -377,24 +374,20 @@
TopologyDeviceDTO.TopologyDeviceDTOBuilder builder = TopologyDeviceDTO.builder();
if (device != null) {
- int domain = DeviceDomainEnum.getVal(device.getDomain());
- String subType = String.valueOf(device.getSubType());
- String type = String.valueOf(device.getType());
-
builder.sn(device.getDeviceSn())
.deviceCallsign(device.getNickname())
.deviceModel(DeviceModelDTO.builder()
- .domain(String.valueOf(domain))
- .subType(subType)
- .type(type)
- .key(domain + "-" + type + "-" + subType)
+ .domain(String.valueOf(device.getDomain()))
+ .subType(String.valueOf(device.getSubType()))
+ .type(String.valueOf(device.getType()))
+ .key(device.getDomain() + "-" + device.getType() + "-" + device.getSubType())
.build())
.iconUrls(device.getIconUrl())
.onlineStatus(RedisOpsUtils.checkExist(RedisConst.DEVICE_ONLINE_PREFIX + device.getDeviceSn()))
.boundStatus(device.getBoundStatus())
.model(device.getDeviceName())
.userId(device.getUserId())
- .domain(DeviceDomainEnum.getDesc(domain))
+ .domain(device.getDomain())
.build();
}
return builder.build();
@@ -518,6 +511,9 @@
.eq(DeviceEntity::getDeviceSn, entity.getDeviceSn()));
// Update the information directly if the device already exists.
if (deviceEntity != null) {
+ if (deviceEntity.getDeviceName().equals(entity.getNickname())) {
+ entity.setNickname(null);
+ }
entity.setId(deviceEntity.getId());
mapper.updateById(entity);
return Optional.of(deviceEntity);
@@ -605,7 +601,7 @@
.workspaceId(entity.getWorkspaceId())
.type(entity.getDeviceType())
.subType(entity.getSubType())
- .domain(DeviceDomainEnum.getDesc(entity.getDomain()))
+ .domain(entity.getDomain())
.iconUrl(IconUrlDTO.builder()
.normalUrl(entity.getUrlNormal())
.selectUrl(entity.getUrlSelect())
@@ -666,18 +662,19 @@
}
String key = RedisConst.DEVICE_ONLINE_PREFIX + device.getDeviceSn();
- DeviceDTO redisDevice = (DeviceDTO)RedisOpsUtils.get(key);
- if (Objects.isNull(redisDevice)) {
+ if (!RedisOpsUtils.checkExist(key)) {
return false;
}
+
+ DeviceDTO redisDevice = (DeviceDTO)RedisOpsUtils.get(key);
redisDevice.setWorkspaceId(device.getWorkspaceId());
RedisOpsUtils.setWithExpire(key, redisDevice, RedisConst.DEVICE_ALIVE_SECOND);
- if (DeviceDomainEnum.GATEWAY.getDesc().equals(redisDevice.getDomain())) {
+ if (DeviceDomainEnum.GATEWAY.getVal() == redisDevice.getDomain()) {
this.pushDeviceOnlineTopo(webSocketManageService.getValueWithWorkspace(device.getWorkspaceId()),
device.getDeviceSn(), device.getDeviceSn());
}
- if (DeviceDomainEnum.SUB_DEVICE.getDesc().equals(redisDevice.getDomain())) {
+ if (DeviceDomainEnum.SUB_DEVICE.getVal() == redisDevice.getDomain()) {
DeviceDTO subDevice = this.getDevicesByParams(DeviceQueryParam.builder()
.childSn(device.getChildDeviceSn())
.build()).get(0);
@@ -774,11 +771,11 @@
@Override
public PaginationData<DeviceDTO> getBoundDevicesWithDomain(String workspaceId, Long page,
- Long pageSize, String domain) {
+ Long pageSize, Integer domain) {
Page<DeviceEntity> pagination = mapper.selectPage(new Page<>(page, pageSize),
new LambdaQueryWrapper<DeviceEntity>()
- .eq(DeviceEntity::getDomain, DeviceDomainEnum.getVal(domain))
+ .eq(DeviceEntity::getDomain, domain)
.eq(DeviceEntity::getWorkspaceId, workspaceId)
.eq(DeviceEntity::getBoundStatus, true));
List<DeviceDTO> devicesList = pagination.getRecords().stream().map(this::deviceEntityConvertToDTO)
@@ -849,7 +846,7 @@
@Override
public ResponseResult createDeviceOtaJob(String workspaceId, List<DeviceFirmwareUpgradeDTO> upgradeDTOS) {
- List<DeviceOtaCreateParam> deviceOtaFirmwares = deviceFirmwareService.getDeviceOtaFirmware(upgradeDTOS);
+ List<DeviceOtaCreateParam> deviceOtaFirmwares = deviceFirmwareService.getDeviceOtaFirmware(workspaceId, upgradeDTOS);
if (deviceOtaFirmwares.isEmpty()) {
return ResponseResult.error();
}
@@ -976,7 +973,7 @@
.boundTime(dto.getBoundTime() != null ?
dto.getBoundTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() : null)
.childSn(dto.getChildDeviceSn())
- .domain(StringUtils.hasText(dto.getDomain()) ? DeviceDomainEnum.getVal(dto.getDomain()) : null)
+ .domain(dto.getDomain())
.firmwareVersion(dto.getFirmwareVersion())
.compatibleStatus(dto.getFirmwareStatus() == null ? null :
DeviceFirmwareStatusEnum.CONSISTENT_UPGRADE != DeviceFirmwareStatusEnum.find(dto.getFirmwareStatus()))
@@ -1041,7 +1038,7 @@
.build();
}
- private Boolean firstSaveDevice(DeviceEntity device, String deviceSn) {
+ private Optional<DeviceEntity> onlineSaveDevice(DeviceEntity device, String childSn) {
Optional<DeviceDTO> deviceOpt = this.getDeviceBySn(device.getDeviceSn());
if (deviceOpt.isEmpty()) {
@@ -1049,15 +1046,19 @@
device.setUrlNormal(IconUrlEnum.NORMAL_PERSON.getUrl());
// Set the icon of the gateway device displayed in the pilot's map when it is selected, required in the TSA module.
device.setUrlSelect(IconUrlEnum.SELECT_PERSON.getUrl());
+ device.setBoundStatus(false);
+ } else {
+ DeviceDTO oldDevice = deviceOpt.get();
+ device.setNickname(oldDevice.getNickname());
+ device.setBoundStatus(oldDevice.getBoundStatus());
}
- deviceOpt.ifPresent(oldDevice -> device.setNickname(oldDevice.getNickname()));
- device.setChildSn(deviceSn);
+ device.setChildSn(childSn);
device.setLoginTime(System.currentTimeMillis());
Optional<DeviceEntity> saveDeviceOpt = this.saveDevice(device);
if (saveDeviceOpt.isEmpty()) {
- return false;
+ return saveDeviceOpt;
}
device.setWorkspaceId(saveDeviceOpt.get().getWorkspaceId());
@@ -1065,13 +1066,13 @@
DeviceDTO.builder()
.deviceSn(device.getDeviceSn())
.workspaceId(device.getWorkspaceId())
- .childDeviceSn(deviceSn)
- .domain(DeviceDomainEnum.getDesc(device.getDomain()))
+ .childDeviceSn(childSn)
+ .domain(device.getDomain())
.type(device.getDeviceType())
.subType(device.getSubType())
.build(),
RedisConst.DEVICE_ALIVE_SECOND);
- return true;
+ return saveDeviceOpt;
}
-}
+}
\ No newline at end of file
diff --git a/src/main/java/com/dji/sample/manage/service/impl/DockOSDServiceImpl.java b/src/main/java/com/dji/sample/manage/service/impl/DockOSDServiceImpl.java
index f0bac72..36cd9b3 100644
--- a/src/main/java/com/dji/sample/manage/service/impl/DockOSDServiceImpl.java
+++ b/src/main/java/com/dji/sample/manage/service/impl/DockOSDServiceImpl.java
@@ -35,7 +35,7 @@
Collection<ConcurrentWebSocketSession> webSessions,
CustomWebSocketMessage<TelemetryDTO> wsMessage) {
- if (DeviceDomainEnum.DOCK.getDesc().equals(device.getDomain())) {
+ if (DeviceDomainEnum.DOCK.getVal() == device.getDomain()) {
wsMessage.setBizCode(BizCodeEnum.DOCK_OSD.getCode());
OsdDockReceiver data = mapper.convertValue(receiver.getData(), OsdDockReceiver.class);
wsMessage.getData().setHost(data);
diff --git a/src/main/java/com/dji/sample/manage/service/impl/FirmwareModelServiceImpl.java b/src/main/java/com/dji/sample/manage/service/impl/FirmwareModelServiceImpl.java
new file mode 100644
index 0000000..6256527
--- /dev/null
+++ b/src/main/java/com/dji/sample/manage/service/impl/FirmwareModelServiceImpl.java
@@ -0,0 +1,44 @@
+package com.dji.sample.manage.service.impl;
+
+import com.dji.sample.manage.dao.IFirmwareModelMapper;
+import com.dji.sample.manage.model.dto.FirmwareModelDTO;
+import com.dji.sample.manage.model.entity.FirmwareModelEntity;
+import com.dji.sample.manage.service.IFirmwareModelService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * @author sean
+ * @version 1.3
+ * @date 2022/12/21
+ */
+@Service
+@Transactional
+public class FirmwareModelServiceImpl implements IFirmwareModelService {
+
+ @Autowired
+ private IFirmwareModelMapper mapper;
+
+ @Override
+ public void saveFirmwareDeviceName(FirmwareModelDTO firmwareModel) {
+ dto2Entity(firmwareModel).forEach(entity -> mapper.insert(entity));
+ }
+
+ private List<FirmwareModelEntity> dto2Entity(FirmwareModelDTO dto) {
+ if (Objects.isNull(dto) || CollectionUtils.isEmpty(dto.getDeviceNames())) {
+ return Collections.EMPTY_LIST;
+ }
+ return dto.getDeviceNames().stream()
+ .map(deviceName -> FirmwareModelEntity.builder()
+ .firmwareId(dto.getFirmwareId())
+ .deviceName(deviceName).build())
+ .collect(Collectors.toList());
+ }
+}
diff --git a/src/main/java/com/dji/sample/manage/service/impl/GatewayOSDServiceImpl.java b/src/main/java/com/dji/sample/manage/service/impl/GatewayOSDServiceImpl.java
index 397c80e..eb788b2 100644
--- a/src/main/java/com/dji/sample/manage/service/impl/GatewayOSDServiceImpl.java
+++ b/src/main/java/com/dji/sample/manage/service/impl/GatewayOSDServiceImpl.java
@@ -47,7 +47,7 @@
public void handleOSD(CommonTopicReceiver receiver, DeviceDTO device,
Collection<ConcurrentWebSocketSession> webSessions,
CustomWebSocketMessage<TelemetryDTO> wsMessage) {
- if (DeviceDomainEnum.GATEWAY.getDesc().equals(device.getDomain())) {
+ if (DeviceDomainEnum.GATEWAY.getVal() == device.getDomain()) {
wsMessage.setBizCode(BizCodeEnum.GATEWAY_OSD.getCode());
OsdGatewayReceiver data = mapper.convertValue(receiver.getData(), OsdGatewayReceiver.class);
diff --git a/src/main/java/com/dji/sample/manage/service/impl/LiveStreamServiceImpl.java b/src/main/java/com/dji/sample/manage/service/impl/LiveStreamServiceImpl.java
index 9f2cdf5..8b441ba 100644
--- a/src/main/java/com/dji/sample/manage/service/impl/LiveStreamServiceImpl.java
+++ b/src/main/java/com/dji/sample/manage/service/impl/LiveStreamServiceImpl.java
@@ -4,7 +4,6 @@
import com.dji.sample.common.model.ResponseResult;
import com.dji.sample.component.mqtt.model.CommonTopicResponse;
import com.dji.sample.component.mqtt.model.ServiceReply;
-import com.dji.sample.component.mqtt.model.StateDataEnum;
import com.dji.sample.component.mqtt.service.IMessageSenderService;
import com.dji.sample.component.redis.RedisConst;
import com.dji.sample.component.redis.RedisOpsUtils;
@@ -79,7 +78,7 @@
// Solve timing problems
for (CapacityDeviceReceiver capacityDeviceReceiver : liveCapacityReceiver.getDeviceList()) {
long last = (long) Objects.requireNonNullElse(
- RedisOpsUtils.get(StateDataEnum.LIVE_CAPACITY + RedisConst.DELIMITER + capacityDeviceReceiver.getSn()), 0L);
+ RedisOpsUtils.get(RedisConst.LIVE_CAPACITY + capacityDeviceReceiver.getSn()), 0L);
if (last > timestamp) {
return;
}
@@ -126,8 +125,8 @@
.toString());
break;
case RTSP:
- String url = receiveReply.getInfo().toString();
- this.resolveUrlUser(url, live);
+ Object url = Objects.requireNonNullElse(receiveReply.getOutput(), receiveReply.getInfo());
+ this.resolveUrlUser(String.valueOf(url), live);
break;
case UNKNOWN:
return ResponseResult.error(LiveErrorEnum.URL_TYPE_NOT_SUPPORTED);
@@ -186,7 +185,7 @@
if (ResponseResult.CODE_SUCCESS != responseResult.getCode()) {
return responseResult;
}
- if (DeviceDomainEnum.GATEWAY.getDesc().equals(responseResult.getData().getDomain())) {
+ if (DeviceDomainEnum.GATEWAY.getVal() == responseResult.getData().getDomain()) {
return ResponseResult.error(LiveErrorEnum.FUNCTION_NOT_SUPPORT);
}
@@ -232,7 +231,7 @@
return ResponseResult.error(LiveErrorEnum.NO_AIRCRAFT);
}
- if (deviceOpt.get().getDomain().equals(DeviceDomainEnum.DOCK.getDesc())) {
+ if (DeviceDomainEnum.DOCK.getVal() == deviceOpt.get().getDomain()) {
return ResponseResult.success(deviceOpt.get());
}
List<DeviceDTO> gatewayList = deviceService.getDevicesByParams(
diff --git a/src/main/java/com/dji/sample/manage/service/impl/UserServiceImpl.java b/src/main/java/com/dji/sample/manage/service/impl/UserServiceImpl.java
index 746fe99..d754831 100644
--- a/src/main/java/com/dji/sample/manage/service/impl/UserServiceImpl.java
+++ b/src/main/java/com/dji/sample/manage/service/impl/UserServiceImpl.java
@@ -101,13 +101,7 @@
String token = JwtUtil.createToken(customClaim.convertToMap());
UserDTO userDTO = entityConvertToDTO(userEntity);
- userDTO.setMqttAddr(new StringBuilder()
- .append(mqttConfiguration.getProtocol().trim())
- .append("://")
- .append(mqttConfiguration.getHost().trim())
- .append(":")
- .append(mqttConfiguration.getPort())
- .toString());
+ userDTO.setMqttAddr(MqttConfiguration.getBasicMqttAddress());
userDTO.setAccessToken(token);
userDTO.setWorkspaceId(workspaceOpt.get().getWorkspaceId());
return ResponseResult.success(userDTO);
@@ -218,13 +212,7 @@
.userType(entity.getUserType())
.mqttUsername(entity.getMqttUsername())
.mqttPassword(entity.getMqttPassword())
- .mqttAddr(new StringBuilder()
- .append(mqttConfiguration.getProtocol().trim())
- .append("://")
- .append(mqttConfiguration.getHost().trim())
- .append(":")
- .append(mqttConfiguration.getPort())
- .toString())
+ .mqttAddr(MqttConfiguration.getBasicMqttAddress())
.build();
}
}
diff --git a/src/main/java/com/dji/sample/media/service/impl/MediaServiceImpl.java b/src/main/java/com/dji/sample/media/service/impl/MediaServiceImpl.java
index d14b3de..8265d48 100644
--- a/src/main/java/com/dji/sample/media/service/impl/MediaServiceImpl.java
+++ b/src/main/java/com/dji/sample/media/service/impl/MediaServiceImpl.java
@@ -30,7 +30,6 @@
import java.util.List;
import java.util.Map;
-import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
@@ -116,12 +115,12 @@
MediaFileCountDTO mediaFileCount = (MediaFileCountDTO) RedisOpsUtils.hashGet(RedisConst.MEDIA_FILE_PREFIX + receiver.getGateway(), jobId);
// duplicate data
if (receiver.getBid().equals(mediaFileCount.getBid()) && receiver.getTid().equals(mediaFileCount.getTid())) {
- System.out.println("相同" + receiver.getBid() + "\t tid:" + receiver.getTid());
messageSenderService.publish(topic, data);
return;
}
- Optional<WaylineJobDTO> jobOpt = waylineJobService.getJobByJobId(jobId);
+ DeviceDTO device = (DeviceDTO) RedisOpsUtils.get(RedisConst.DEVICE_ONLINE_PREFIX + receiver.getGateway());
+ Optional<WaylineJobDTO> jobOpt = waylineJobService.getJobByJobId(device.getWorkspaceId(), jobId);
if (jobOpt.isPresent()) {
boolean isSave = parseMediaFile(callback, jobOpt.get());
if (!isSave) {
@@ -152,7 +151,8 @@
// After uploading, delete the key with the highest priority.
String highestKey = RedisConst.MEDIA_HIGHEST_PRIORITY_PREFIX + receiver.getGateway();
- if (jobId.equals(Objects.requireNonNullElse(RedisOpsUtils.get(highestKey), ""))) {
+ if (RedisOpsUtils.checkExist(highestKey) &&
+ jobId.equals(((MediaFileCountDTO) RedisOpsUtils.get(highestKey)).getJobId())) {
RedisOpsUtils.del(highestKey);
}
@@ -192,25 +192,6 @@
return;
}
- String dockSn = receiver.getGateway();
- String jobId = map.get(MapKeyConst.FLIGHT_ID).toString();
- String key = RedisConst.MEDIA_HIGHEST_PRIORITY_PREFIX + dockSn;
- Object preJobId = RedisOpsUtils.get(key);
-
- RedisOpsUtils.setWithExpire(key, jobId,
- RedisConst.DEVICE_ALIVE_SECOND * 5);
-
- DeviceDTO dock = (DeviceDTO) RedisOpsUtils.get(RedisConst.DEVICE_ONLINE_PREFIX + dockSn);
-
- sendMessageService.sendBatch(webSocketManageService.getValueWithWorkspaceAndUserType(dock.getWorkspaceId(), UserTypeEnum.WEB.getVal()),
- CustomWebSocketMessage.builder()
- .timestamp(System.currentTimeMillis())
- .bizCode(BizCodeEnum.HIGHEST_PRIORITY_UPLOAD_FLIGHT_TASK_MEDIA.getCode())
- .data(MediaFileCountDTO.builder()
- .preJobId(Objects.nonNull(preJobId) ? preJobId.toString() : null)
- .jobId(jobId).build())
- .build());
-
messageSenderService.publish(headers.get(MqttHeaders.RECEIVED_TOPIC) + TopicConst._REPLY_SUF,
CommonTopicResponse.builder()
.data(RequestsReply.success())
@@ -219,5 +200,31 @@
.bid(receiver.getBid())
.tid(receiver.getTid())
.build());
+
+ String dockSn = receiver.getGateway();
+ String jobId = map.get(MapKeyConst.FLIGHT_ID).toString();
+ String key = RedisConst.MEDIA_HIGHEST_PRIORITY_PREFIX + dockSn;
+ MediaFileCountDTO countDTO = new MediaFileCountDTO();
+ if (RedisOpsUtils.checkExist(key)) {
+ countDTO = (MediaFileCountDTO) RedisOpsUtils.get(key);
+ if (jobId.equals(countDTO.getJobId())) {
+ RedisOpsUtils.setWithExpire(key, countDTO, RedisConst.DEVICE_ALIVE_SECOND * 5);
+ return;
+ }
+
+ countDTO.setPreJobId(countDTO.getJobId());
+ }
+ countDTO.setJobId(jobId);
+
+ RedisOpsUtils.setWithExpire(key, countDTO, RedisConst.DEVICE_ALIVE_SECOND * 5);
+
+ DeviceDTO dock = (DeviceDTO) RedisOpsUtils.get(RedisConst.DEVICE_ONLINE_PREFIX + dockSn);
+ sendMessageService.sendBatch(webSocketManageService.getValueWithWorkspaceAndUserType(dock.getWorkspaceId(), UserTypeEnum.WEB.getVal()),
+ CustomWebSocketMessage.builder()
+ .timestamp(System.currentTimeMillis())
+ .bizCode(BizCodeEnum.HIGHEST_PRIORITY_UPLOAD_FLIGHT_TASK_MEDIA.getCode())
+ .data(countDTO)
+ .build());
+
}
}
diff --git a/src/main/java/com/dji/sample/wayline/controller/WaylineJobController.java b/src/main/java/com/dji/sample/wayline/controller/WaylineJobController.java
index 49ff96b..f24bdb2 100644
--- a/src/main/java/com/dji/sample/wayline/controller/WaylineJobController.java
+++ b/src/main/java/com/dji/sample/wayline/controller/WaylineJobController.java
@@ -12,7 +12,7 @@
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.sql.SQLException;
-import java.util.List;
+import java.util.Set;
import static com.dji.sample.component.AuthInterceptor.TOKEN_CLAIM;
@@ -68,7 +68,7 @@
* @throws SQLException
*/
@DeleteMapping("/{workspace_id}/jobs")
- public ResponseResult publishCancelJob(@RequestParam(name = "job_id") List<String> jobIds,
+ public ResponseResult publishCancelJob(@RequestParam(name = "job_id") Set<String> jobIds,
@PathVariable(name = "workspace_id") String workspaceId) throws SQLException {
waylineJobService.cancelFlightTask(workspaceId, jobIds);
return ResponseResult.success();
diff --git a/src/main/java/com/dji/sample/wayline/model/dto/FlightTaskProgressReceiver.java b/src/main/java/com/dji/sample/wayline/model/dto/FlightTaskProgressReceiver.java
deleted file mode 100644
index d2f7c7c..0000000
--- a/src/main/java/com/dji/sample/wayline/model/dto/FlightTaskProgressReceiver.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.dji.sample.wayline.model.dto;
-
-import lombok.Data;
-
-/**
- * @author sean
- * @version 1.1
- * @date 2022/6/9
- */
-@Data
-public class FlightTaskProgressReceiver {
-
- private FlightTaskProgressExt ext;
-
- private FLightTaskProgress progress;
-
- private String status;
-
-}
diff --git a/src/main/java/com/dji/sample/wayline/model/dto/WaylineJobDTO.java b/src/main/java/com/dji/sample/wayline/model/dto/WaylineJobDTO.java
index a4f8486..b797819 100644
--- a/src/main/java/com/dji/sample/wayline/model/dto/WaylineJobDTO.java
+++ b/src/main/java/com/dji/sample/wayline/model/dto/WaylineJobDTO.java
@@ -38,7 +38,11 @@
private LocalDateTime executeTime;
+ private LocalDateTime beginTime;
+
private LocalDateTime endTime;
+
+ private LocalDateTime completedTime;
private Integer status;
@@ -57,4 +61,6 @@
private Integer uploadedCount;
private Boolean uploading;
+
+ private String parentId;
}
diff --git a/src/main/java/com/dji/sample/wayline/model/dto/FlightTaskCreateDTO.java b/src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskCreateDTO.java
similarity index 86%
rename from src/main/java/com/dji/sample/wayline/model/dto/FlightTaskCreateDTO.java
rename to src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskCreateDTO.java
index c4b281d..b920530 100644
--- a/src/main/java/com/dji/sample/wayline/model/dto/FlightTaskCreateDTO.java
+++ b/src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskCreateDTO.java
@@ -14,7 +14,7 @@
@Builder
@AllArgsConstructor
@NoArgsConstructor
-public class FlightTaskCreateDTO {
+public class WaylineTaskCreateDTO {
private String flightId;
@@ -24,9 +24,10 @@
private Long executeTime;
- private FlightTaskFileDTO file;
+ private WaylineTaskFileDTO file;
private Integer rthAltitude;
private Integer outOfControlAction;
+
}
diff --git a/src/main/java/com/dji/sample/wayline/model/dto/FlightTaskFileDTO.java b/src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskFileDTO.java
similarity index 90%
rename from src/main/java/com/dji/sample/wayline/model/dto/FlightTaskFileDTO.java
rename to src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskFileDTO.java
index e5858ee..604eb9d 100644
--- a/src/main/java/com/dji/sample/wayline/model/dto/FlightTaskFileDTO.java
+++ b/src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskFileDTO.java
@@ -14,7 +14,7 @@
@Builder
@AllArgsConstructor
@NoArgsConstructor
-public class FlightTaskFileDTO {
+public class WaylineTaskFileDTO {
private String url;
diff --git a/src/main/java/com/dji/sample/wayline/model/dto/FLightTaskProgress.java b/src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskProgress.java
similarity index 84%
rename from src/main/java/com/dji/sample/wayline/model/dto/FLightTaskProgress.java
rename to src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskProgress.java
index e8e8794..fa814e7 100644
--- a/src/main/java/com/dji/sample/wayline/model/dto/FLightTaskProgress.java
+++ b/src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskProgress.java
@@ -8,7 +8,7 @@
* @date 2022/6/9
*/
@Data
-public class FLightTaskProgress {
+public class WaylineTaskProgress {
private Integer currentStep;
diff --git a/src/main/java/com/dji/sample/wayline/model/dto/FlightTaskProgressExt.java b/src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskProgressExt.java
similarity index 68%
rename from src/main/java/com/dji/sample/wayline/model/dto/FlightTaskProgressExt.java
rename to src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskProgressExt.java
index c75ef1e..bec5eaa 100644
--- a/src/main/java/com/dji/sample/wayline/model/dto/FlightTaskProgressExt.java
+++ b/src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskProgressExt.java
@@ -8,9 +8,13 @@
* @date 2022/6/9
*/
@Data
-public class FlightTaskProgressExt {
+public class WaylineTaskProgressExt {
private Integer currentWaypointIndex;
private Integer mediaCount;
+
+ private String flightId;
+
+ private String trackId;
}
diff --git a/src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskProgressReceiver.java b/src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskProgressReceiver.java
new file mode 100644
index 0000000..b86bc9b
--- /dev/null
+++ b/src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskProgressReceiver.java
@@ -0,0 +1,19 @@
+package com.dji.sample.wayline.model.dto;
+
+import lombok.Data;
+
+/**
+ * @author sean
+ * @version 1.1
+ * @date 2022/6/9
+ */
+@Data
+public class WaylineTaskProgressReceiver {
+
+ private WaylineTaskProgressExt ext;
+
+ private WaylineTaskProgress progress;
+
+ private String status;
+
+}
diff --git a/src/main/java/com/dji/sample/wayline/model/entity/WaylineJobEntity.java b/src/main/java/com/dji/sample/wayline/model/entity/WaylineJobEntity.java
index 64800a0..68f29f7 100644
--- a/src/main/java/com/dji/sample/wayline/model/entity/WaylineJobEntity.java
+++ b/src/main/java/com/dji/sample/wayline/model/entity/WaylineJobEntity.java
@@ -74,4 +74,12 @@
@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
private Long updateTime;
+ @TableField("begin_time")
+ private Long beginTime;
+
+ @TableField("completed_time")
+ private Long completedTime;
+
+ @TableField("parent_id")
+ private String parentId;
}
diff --git a/src/main/java/com/dji/sample/wayline/model/enums/WaylineJobStatusEnum.java b/src/main/java/com/dji/sample/wayline/model/enums/WaylineJobStatusEnum.java
index b33150b..dcd5bb7 100644
--- a/src/main/java/com/dji/sample/wayline/model/enums/WaylineJobStatusEnum.java
+++ b/src/main/java/com/dji/sample/wayline/model/enums/WaylineJobStatusEnum.java
@@ -22,7 +22,9 @@
FAILED(5, true),
- UNKNOWN(6, true);
+ PAUSED(6, false),
+
+ UNKNOWN(-1, true);
int val;
diff --git a/src/main/java/com/dji/sample/wayline/service/IWaylineJobService.java b/src/main/java/com/dji/sample/wayline/service/IWaylineJobService.java
index 90d8594..a18da9f 100644
--- a/src/main/java/com/dji/sample/wayline/service/IWaylineJobService.java
+++ b/src/main/java/com/dji/sample/wayline/service/IWaylineJobService.java
@@ -5,11 +5,13 @@
import com.dji.sample.common.model.ResponseResult;
import com.dji.sample.component.mqtt.model.CommonTopicReceiver;
import com.dji.sample.wayline.model.dto.WaylineJobDTO;
+import com.dji.sample.wayline.model.enums.WaylineJobStatusEnum;
import com.dji.sample.wayline.model.param.CreateJobParam;
import org.springframework.messaging.MessageHeaders;
import java.sql.SQLException;
import java.util.Collection;
+import java.util.List;
import java.util.Optional;
/**
@@ -22,10 +24,21 @@
/**
* Create wayline job in the database.
* @param param
- * @param customClaim user info
+ * @param workspaceId user info
+ * @param username user info
+ * @param beginTime The time the job started.
+ * @param endTime The time the job ended.
* @return
*/
- Optional<WaylineJobDTO> createWaylineJob(CreateJobParam param, CustomClaim customClaim);
+ Optional<WaylineJobDTO> createWaylineJob(CreateJobParam param, String workspaceId, String username, Long beginTime, Long endTime);
+
+ /**
+ * Create a sub-task based on the information of the parent task.
+ * @param workspaceId
+ * @param parentId
+ * @return
+ */
+ Optional<WaylineJobDTO> createWaylineJobByParent(String workspaceId, String parentId);
/**
* Issue wayline mission to the dock.
@@ -41,7 +54,7 @@
* @throws SQLException
* @return
*/
- Boolean executeFlightTask(String jobId);
+ Boolean executeFlightTask(String workspaceId, String jobId);
/**
* Cancel the task Base on job Ids.
@@ -52,11 +65,29 @@
void cancelFlightTask(String workspaceId, Collection<String> jobIds);
/**
+ * Cancel the dock tasks that have been issued but have not yet been executed.
+ * @param workspaceId
+ * @param dockSn
+ * @param jobIds
+ */
+ void publishCancelTask(String workspaceId, String dockSn, List<String> jobIds);
+
+ /**
+ * Query wayline jobs based on conditions.
+ * @param workspaceId
+ * @param jobIds
+ * @param status
+ * @return
+ */
+ List<WaylineJobDTO> getJobsByConditions(String workspaceId, Collection<String> jobIds, WaylineJobStatusEnum status);
+
+ /**
* Query job information based on job id.
+ * @param workspaceId
* @param jobId
* @return job information
*/
- Optional<WaylineJobDTO> getJobByJobId(String jobId);
+ Optional<WaylineJobDTO> getJobByJobId(String workspaceId, String jobId);
/**
* Update job data.
diff --git a/src/main/java/com/dji/sample/wayline/service/impl/FlightTaskServiceImpl.java b/src/main/java/com/dji/sample/wayline/service/impl/FlightTaskServiceImpl.java
index 77ca1cf..224602d 100644
--- a/src/main/java/com/dji/sample/wayline/service/impl/FlightTaskServiceImpl.java
+++ b/src/main/java/com/dji/sample/wayline/service/impl/FlightTaskServiceImpl.java
@@ -12,8 +12,8 @@
import com.dji.sample.manage.model.dto.DeviceDTO;
import com.dji.sample.manage.model.enums.UserTypeEnum;
import com.dji.sample.media.model.MediaFileCountDTO;
-import com.dji.sample.wayline.model.dto.FlightTaskProgressReceiver;
import com.dji.sample.wayline.model.dto.WaylineJobDTO;
+import com.dji.sample.wayline.model.dto.WaylineTaskProgressReceiver;
import com.dji.sample.wayline.model.enums.WaylineJobStatusEnum;
import com.dji.sample.wayline.service.IFlightTaskService;
import com.dji.sample.wayline.service.IWaylineJobService;
@@ -29,7 +29,7 @@
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
-import java.util.Objects;
+import java.util.*;
import java.util.concurrent.TimeUnit;
/**
@@ -59,12 +59,15 @@
@Override
@ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_FLIGHT_TASK_PROGRESS, outputChannel = ChannelName.OUTBOUND)
public void handleProgress(CommonTopicReceiver receiver, MessageHeaders headers) {
- EventsReceiver<FlightTaskProgressReceiver> eventsReceiver = mapper.convertValue(receiver.getData(),
- new TypeReference<EventsReceiver<FlightTaskProgressReceiver>>(){});
+ 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(),
+ new TypeReference<EventsReceiver<WaylineTaskProgressReceiver>>(){});
eventsReceiver.setBid(receiver.getBid());
eventsReceiver.setSn(receiver.getGateway());
- FlightTaskProgressReceiver output = eventsReceiver.getOutput();
+ WaylineTaskProgressReceiver output = eventsReceiver.getOutput();
log.info("Task progress: {}", output.getProgress().toString());
@@ -73,16 +76,19 @@
}
EventsResultStatusEnum statusEnum = EventsResultStatusEnum.find(output.getStatus());
+ String key = RedisConst.WAYLINE_JOB_RUNNING_PREFIX + dockSn;
+ RedisOpsUtils.setWithExpire(key, eventsReceiver, RedisConst.DEVICE_ALIVE_SECOND * RedisConst.DEVICE_ALIVE_SECOND);
+
if (statusEnum.getEnd()) {
WaylineJobDTO job = WaylineJobDTO.builder()
.jobId(receiver.getBid())
.status(WaylineJobStatusEnum.SUCCESS.getVal())
- .endTime(LocalDateTime.now())
+ .completedTime(LocalDateTime.now())
.mediaCount(output.getExt().getMediaCount())
.build();
// record the update of the media count.
- if (Objects.nonNull(job.getMediaCount())) {
+ 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());
}
@@ -93,9 +99,9 @@
}
waylineJobService.updateJob(job);
- RedisOpsUtils.del(receiver.getBid());
+ RedisOpsUtils.del(key);
+ RedisOpsUtils.del(RedisConst.WAYLINE_JOB_PAUSED_PREFIX + receiver.getBid());
}
- RedisOpsUtils.setWithExpire(receiver.getBid(), eventsReceiver, RedisConst.DEVICE_ALIVE_SECOND * RedisConst.DEVICE_ALIVE_SECOND);
DeviceDTO device = (DeviceDTO) RedisOpsUtils.get(RedisConst.DEVICE_ONLINE_PREFIX + receiver.getGateway());
websocketMessageService.sendBatch(
@@ -108,8 +114,7 @@
.build());
if (receiver.getNeedReply() == 1) {
- String topic = headers.get(MqttHeaders.RECEIVED_TOPIC) + TopicConst._REPLY_SUF;
- messageSender.publish(topic,
+ messageSender.publish(receivedTopic + TopicConst._REPLY_SUF,
CommonTopicResponse.builder()
.tid(receiver.getTid())
.bid(receiver.getBid())
@@ -122,39 +127,42 @@
@Scheduled(initialDelay = 10, fixedRate = 5, timeUnit = TimeUnit.SECONDS)
private void checkScheduledJob() {
- Object jobIdValue = RedisOpsUtils.zGetMin(RedisConst.WAYLINE_JOB);
- log.info("Check the timed jobs of the wayline. {}", jobIdValue);
+ Object jobIdValue = RedisOpsUtils.zGetMin(RedisConst.WAYLINE_JOB_TIMED_EXECUTE);
if (Objects.isNull(jobIdValue)) {
return;
}
- String jobId = String.valueOf(jobIdValue);
- double time = RedisOpsUtils.zScore(RedisConst.WAYLINE_JOB, jobIdValue);
+ log.info("Check the timed tasks of the wayline. {}", jobIdValue);
+ // format: {workspace_id}:{dock_sn}:{job_id}
+ String[] jobArr = String.valueOf(jobIdValue).split(RedisConst.DELIMITER);
+ double time = RedisOpsUtils.zScore(RedisConst.WAYLINE_JOB_TIMED_EXECUTE, jobIdValue);
long now = System.currentTimeMillis();
int offset = 30_000;
// Expired tasks are deleted directly.
if (time < now - offset) {
- RedisOpsUtils.zRemove(RedisConst.WAYLINE_JOB, jobId);
+ RedisOpsUtils.zRemove(RedisConst.WAYLINE_JOB_TIMED_EXECUTE, jobIdValue);
waylineJobService.updateJob(WaylineJobDTO.builder()
- .jobId(jobId)
+ .jobId(jobArr[2])
.status(WaylineJobStatusEnum.FAILED.getVal())
- .endTime(LocalDateTime.now())
+ .executeTime(LocalDateTime.now())
+ .completedTime(LocalDateTime.now())
.code(HttpStatus.SC_REQUEST_TIMEOUT).build());
return;
}
if (now <= time && time <= now + offset) {
try {
- waylineJobService.executeFlightTask(jobId);
+ waylineJobService.executeFlightTask(jobArr[0], jobArr[2]);
} catch (Exception e) {
log.info("The scheduled task delivery failed.");
waylineJobService.updateJob(WaylineJobDTO.builder()
- .jobId(jobId)
+ .jobId(jobArr[2])
.status(WaylineJobStatusEnum.FAILED.getVal())
- .endTime(LocalDateTime.now())
+ .executeTime(LocalDateTime.now())
+ .completedTime(LocalDateTime.now())
.code(HttpStatus.SC_INTERNAL_SERVER_ERROR).build());
} finally {
- RedisOpsUtils.zRemove(RedisConst.WAYLINE_JOB, jobId);
+ RedisOpsUtils.zRemove(RedisConst.WAYLINE_JOB_TIMED_EXECUTE, jobIdValue);
}
}
}
diff --git a/src/main/java/com/dji/sample/wayline/service/impl/WaylineFileServiceImpl.java b/src/main/java/com/dji/sample/wayline/service/impl/WaylineFileServiceImpl.java
index 60af321..f540b66 100644
--- a/src/main/java/com/dji/sample/wayline/service/impl/WaylineFileServiceImpl.java
+++ b/src/main/java/com/dji/sample/wayline/service/impl/WaylineFileServiceImpl.java
@@ -187,7 +187,7 @@
ZipEntry nextEntry = unzipFile.getNextEntry();
while (Objects.nonNull(nextEntry)) {
- boolean isWaylines = (KmzFileProperties.FILE_DIR_FIRST + File.separator + KmzFileProperties.FILE_DIR_SECOND_WAYLINES).equals(nextEntry.getName());
+ boolean isWaylines = (KmzFileProperties.FILE_DIR_FIRST + "/" + KmzFileProperties.FILE_DIR_SECOND_WAYLINES).equals(nextEntry.getName());
if (!isWaylines) {
nextEntry = unzipFile.getNextEntry();
continue;
diff --git a/src/main/java/com/dji/sample/wayline/service/impl/WaylineJobServiceImpl.java b/src/main/java/com/dji/sample/wayline/service/impl/WaylineJobServiceImpl.java
index 067a3fc..acbeabe 100644
--- a/src/main/java/com/dji/sample/wayline/service/impl/WaylineJobServiceImpl.java
+++ b/src/main/java/com/dji/sample/wayline/service/impl/WaylineJobServiceImpl.java
@@ -40,9 +40,7 @@
import java.net.URL;
import java.sql.SQLException;
-import java.time.Instant;
-import java.time.LocalDateTime;
-import java.time.ZoneId;
+import java.time.*;
import java.util.*;
import java.util.stream.Collectors;
@@ -74,30 +72,7 @@
@Autowired
private IFileService fileService;
- @Override
- public Optional<WaylineJobDTO> createWaylineJob(CreateJobParam param, CustomClaim customClaim) {
- if (Objects.isNull(param)) {
- return Optional.empty();
- }
- // Immediate tasks, allocating time on the backend.
- if (Objects.isNull(param.getExecuteTime())) {
- param.setExecuteTime(System.currentTimeMillis());
- }
- WaylineJobEntity jobEntity = WaylineJobEntity.builder()
- .name(param.getName())
- .dockSn(param.getDockSn())
- .fileId(param.getFileId())
- .username(customClaim.getUsername())
- .workspaceId(customClaim.getWorkspaceId())
- .jobId(UUID.randomUUID().toString())
- .executeTime(param.getExecuteTime())
- .status(WaylineJobStatusEnum.PENDING.getVal())
- .taskType(param.getTaskType())
- .waylineType(param.getWaylineType())
- .outOfControlAction(param.getOutOfControlAction())
- .rthAltitude(param.getRthAltitude())
- .mediaCount(0)
- .build();
+ private Optional<WaylineJobDTO> insertWaylineJob(WaylineJobEntity jobEntity) {
int id = mapper.insert(jobEntity);
if (id <= 0) {
return Optional.empty();
@@ -106,8 +81,56 @@
}
@Override
+ public Optional<WaylineJobDTO> createWaylineJob(CreateJobParam param, String workspaceId, String username, Long beginTime, Long endTime) {
+ if (Objects.isNull(param)) {
+ return Optional.empty();
+ }
+ // Immediate tasks, allocating time on the backend.
+ WaylineJobEntity jobEntity = WaylineJobEntity.builder()
+ .name(param.getName())
+ .dockSn(param.getDockSn())
+ .fileId(param.getFileId())
+ .username(username)
+ .workspaceId(workspaceId)
+ .jobId(UUID.randomUUID().toString())
+ .beginTime(beginTime)
+ .endTime(endTime)
+ .status(WaylineJobStatusEnum.PENDING.getVal())
+ .taskType(param.getTaskType())
+ .waylineType(param.getWaylineType())
+ .outOfControlAction(param.getOutOfControlAction())
+ .rthAltitude(param.getRthAltitude())
+ .mediaCount(0)
+ .build();
+
+ return insertWaylineJob(jobEntity);
+ }
+
+ @Override
+ public Optional<WaylineJobDTO> createWaylineJobByParent(String workspaceId, String parentId) {
+ Optional<WaylineJobDTO> parentJobOpt = this.getJobByJobId(workspaceId, parentId);
+ if (parentJobOpt.isEmpty()) {
+ return Optional.empty();
+ }
+ WaylineJobEntity jobEntity = this.dto2Entity(parentJobOpt.get());
+ jobEntity.setJobId(UUID.randomUUID().toString());
+ jobEntity.setErrorCode(null);
+ jobEntity.setCompletedTime(null);
+ jobEntity.setExecuteTime(null);
+ jobEntity.setStatus(WaylineJobStatusEnum.PENDING.getVal());
+ jobEntity.setParentId(parentId);
+
+ return this.insertWaylineJob(jobEntity);
+ }
+
+ @Override
public ResponseResult publishFlightTask(CreateJobParam param, CustomClaim customClaim) throws SQLException {
- Optional<WaylineJobDTO> waylineJobOpt = this.createWaylineJob(param, customClaim);
+ if (WaylineTaskTypeEnum.IMMEDIATE.getVal() == param.getTaskType()) {
+ param.setExecuteTime(System.currentTimeMillis());
+ }
+ Optional<WaylineJobDTO> waylineJobOpt = this.createWaylineJob(param,
+ customClaim.getWorkspaceId(), customClaim.getUsername(),
+ param.getExecuteTime(), param.getExecuteTime());
if (waylineJobOpt.isEmpty()) {
throw new SQLException("Failed to create wayline job.");
}
@@ -127,14 +150,14 @@
// get file url
URL url = waylineFileService.getObjectUrl(waylineJob.getWorkspaceId(), waylineFile.get().getWaylineId());
- FlightTaskCreateDTO flightTask = FlightTaskCreateDTO.builder()
+ WaylineTaskCreateDTO flightTask = WaylineTaskCreateDTO.builder()
.flightId(waylineJob.getJobId())
- .executeTime(waylineJob.getExecuteTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli())
+ .executeTime(waylineJob.getBeginTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli())
.taskType(waylineJob.getTaskType())
.waylineType(waylineJob.getWaylineType())
.rthAltitude(waylineJob.getRthAltitude())
.outOfControlAction(waylineJob.getOutOfControlAction())
- .file(FlightTaskFileDTO.builder()
+ .file(WaylineTaskFileDTO.builder()
.url(url.toString())
.fingerprint(waylineFile.get().getSign())
.build())
@@ -156,22 +179,24 @@
this.updateJob(WaylineJobDTO.builder()
.workspaceId(waylineJob.getWorkspaceId())
.jobId(waylineJob.getJobId())
+ .executeTime(LocalDateTime.now())
.status(WaylineJobStatusEnum.FAILED.getVal())
- .endTime(LocalDateTime.now())
+ .completedTime(LocalDateTime.now())
.code(serviceReply.getResult()).build());
return ResponseResult.error("Prepare task ====> Error code: " + serviceReply.getResult());
}
// Issue an immediate task execution command.
if (WaylineTaskTypeEnum.IMMEDIATE.getVal() == waylineJob.getTaskType()) {
- if (!executeFlightTask(waylineJob.getJobId())) {
+ if (!executeFlightTask(waylineJob.getWorkspaceId(), waylineJob.getJobId())) {
return ResponseResult.error("Failed to execute job.");
}
}
if (WaylineTaskTypeEnum.TIMED.getVal() == waylineJob.getTaskType()) {
- boolean isAdd = RedisOpsUtils.zAdd(RedisConst.WAYLINE_JOB, waylineJob.getJobId(),
- waylineJob.getExecuteTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
+ 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.");
}
@@ -181,9 +206,9 @@
}
@Override
- public Boolean executeFlightTask(String jobId) {
+ public Boolean executeFlightTask(String workspaceId, String jobId) {
// get job
- Optional<WaylineJobDTO> waylineJob = this.getJobByJobId(jobId);
+ Optional<WaylineJobDTO> waylineJob = this.getJobByJobId(workspaceId, jobId);
if (waylineJob.isEmpty()) {
throw new IllegalArgumentException("Job doesn't exist.");
}
@@ -194,7 +219,7 @@
}
WaylineJobDTO job = waylineJob.get();
- FlightTaskCreateDTO flightTask = FlightTaskCreateDTO.builder().flightId(jobId).build();
+ WaylineTaskCreateDTO flightTask = WaylineTaskCreateDTO.builder().flightId(jobId).build();
String topic = TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT +
job.getDockSn() + TopicConst.SERVICES_SUF;
@@ -211,53 +236,45 @@
log.info("Execute job ====> Error code: {}", serviceReply.getResult());
this.updateJob(WaylineJobDTO.builder()
.jobId(jobId)
+ .executeTime(LocalDateTime.now())
.status(WaylineJobStatusEnum.FAILED.getVal())
- .endTime(LocalDateTime.now())
+ .completedTime(LocalDateTime.now())
.code(serviceReply.getResult()).build());
return false;
}
this.updateJob(WaylineJobDTO.builder()
.jobId(jobId)
+ .executeTime(LocalDateTime.now())
.status(WaylineJobStatusEnum.IN_PROGRESS.getVal())
.build());
- RedisOpsUtils.setWithExpire(jobId,
- EventsReceiver.<FlightTaskProgressReceiver>builder().bid(jobId).sn(job.getDockSn()).build(),
+ RedisOpsUtils.setWithExpire(RedisConst.WAYLINE_JOB_RUNNING_PREFIX + job.getDockSn(),
+ EventsReceiver.<WaylineTaskProgressReceiver>builder().bid(jobId).sn(job.getDockSn()).build(),
RedisConst.DEVICE_ALIVE_SECOND * RedisConst.DEVICE_ALIVE_SECOND);
return true;
}
@Override
public void cancelFlightTask(String workspaceId, Collection<String> jobIds) {
- List<WaylineJobEntity> waylineJobs = mapper.selectList(
- new LambdaQueryWrapper<WaylineJobEntity>()
- .or(wrapper -> jobIds.forEach(id -> wrapper.eq(WaylineJobEntity::getJobId, id))));
+ List<WaylineJobDTO> waylineJobs = getJobsByConditions(workspaceId, jobIds, WaylineJobStatusEnum.PENDING);
- // Check if the job have ended.
- List<String> endJobs = waylineJobs.stream()
- .filter(job -> WaylineJobStatusEnum.find(job.getStatus()).getEnd())
- .map(WaylineJobEntity::getName)
- .collect(Collectors.toList());
- if (!CollectionUtils.isEmpty(endJobs)) {
- throw new IllegalArgumentException("There are jobs that have ended." + Arrays.toString(endJobs.toArray()));
- }
-
- Set<String> ids = waylineJobs.stream().map(WaylineJobEntity::getJobId).collect(Collectors.toSet());
- for (String id : jobIds) {
- if (!ids.contains(id)) {
- throw new IllegalArgumentException("Job id " + id + " doesn't exist.");
- }
+ Set<String> waylineJobIds = waylineJobs.stream().map(WaylineJobDTO::getJobId).collect(Collectors.toSet());
+ // Check if the task status is correct.
+ boolean isErr = !jobIds.removeAll(waylineJobIds) || !jobIds.isEmpty() ;
+ if (isErr) {
+ throw new IllegalArgumentException("These tasks have an incorrect status and cannot be canceled. "
+ + Arrays.toString(jobIds.toArray()));
}
// Group job id by dock sn.
Map<String, List<String>> dockJobs = waylineJobs.stream()
- .collect(Collectors.groupingBy(WaylineJobEntity::getDockSn,
- Collectors.mapping(WaylineJobEntity::getJobId, Collectors.toList())));
+ .collect(Collectors.groupingBy(WaylineJobDTO::getDockSn,
+ Collectors.mapping(WaylineJobDTO::getJobId, Collectors.toList())));
dockJobs.forEach((dockSn, idList) -> this.publishCancelTask(workspaceId, dockSn, idList));
}
- private void publishCancelTask(String workspaceId, String dockSn, List<String> jobIds) {
+ public void publishCancelTask(String workspaceId, String dockSn, List<String> jobIds) {
boolean isOnline = deviceService.checkDeviceOnline(dockSn);
if (!isOnline) {
throw new RuntimeException("Dock is offline.");
@@ -283,17 +300,30 @@
.workspaceId(workspaceId)
.jobId(jobId)
.status(WaylineJobStatusEnum.CANCEL.getVal())
- .endTime(LocalDateTime.now())
+ .completedTime(LocalDateTime.now())
.build());
- RedisOpsUtils.zRemove(RedisConst.WAYLINE_JOB, jobId);
+ RedisOpsUtils.zRemove(RedisConst.WAYLINE_JOB_TIMED_EXECUTE, workspaceId + RedisConst.DELIMITER + dockSn + RedisConst.DELIMITER + jobId);
}
}
+ public List<WaylineJobDTO> getJobsByConditions(String workspaceId, Collection<String> jobIds, WaylineJobStatusEnum status) {
+ return mapper.selectList(
+ new LambdaQueryWrapper<WaylineJobEntity>()
+ .eq(WaylineJobEntity::getWorkspaceId, workspaceId)
+ .eq(Objects.nonNull(status), WaylineJobEntity::getStatus, status.getVal())
+ .and(!CollectionUtils.isEmpty(jobIds),
+ wrapper -> jobIds.forEach(id -> wrapper.eq(WaylineJobEntity::getJobId, id).or())))
+ .stream()
+ .map(this::entity2Dto)
+ .collect(Collectors.toList());
+ }
+
@Override
- public Optional<WaylineJobDTO> getJobByJobId(String jobId) {
+ public Optional<WaylineJobDTO> getJobByJobId(String workspaceId, String jobId) {
WaylineJobEntity jobEntity = mapper.selectOne(
new LambdaQueryWrapper<WaylineJobEntity>()
+ .eq(WaylineJobEntity::getWorkspaceId, workspaceId)
.eq(WaylineJobEntity::getJobId, jobId));
return Optional.ofNullable(entity2Dto(jobEntity));
}
@@ -336,7 +366,8 @@
String topic = headers.get(MqttHeaders.RECEIVED_TOPIC).toString() + TopicConst._REPLY_SUF;
- Optional<WaylineJobDTO> waylineJobOpt = this.getJobByJobId(jobId);
+ DeviceDTO device = (DeviceDTO) RedisOpsUtils.get(RedisConst.DEVICE_ONLINE_PREFIX + receiver.getGateway());
+ Optional<WaylineJobDTO> waylineJobOpt = this.getJobByJobId(device.getWorkspaceId(), jobId);
if (waylineJobOpt.isEmpty()) {
builder.data(RequestsReply.error(CommonErrorEnum.ILLEGAL_ARGUMENT));
messageSender.publish(topic, builder.build());
@@ -357,8 +388,8 @@
URL url = null;
try {
url = waylineFileService.getObjectUrl(waylineJob.getWorkspaceId(), waylineFile.get().getWaylineId());
- builder.data(RequestsReply.success(FlightTaskCreateDTO.builder()
- .file(FlightTaskFileDTO.builder()
+ builder.data(RequestsReply.success(WaylineTaskCreateDTO.builder()
+ .file(WaylineTaskFileDTO.builder()
.url(url.toString())
.fingerprint(waylineFile.get().getSign())
.build())
@@ -377,14 +408,15 @@
@Override
public void uploadMediaHighestPriority(String workspaceId, String jobId) {
- Optional<WaylineJobDTO> jobOpt = getJobByJobId(jobId);
+ Optional<WaylineJobDTO> jobOpt = getJobByJobId(workspaceId, jobId);
if (jobOpt.isEmpty()) {
throw new RuntimeException(CommonErrorEnum.ILLEGAL_ARGUMENT.getErrorMsg());
}
String dockSn = jobOpt.get().getDockSn();
String key = RedisConst.MEDIA_HIGHEST_PRIORITY_PREFIX + dockSn;
- if (RedisOpsUtils.checkExist(key) && jobId.equals(RedisOpsUtils.get(key).toString())) {
+ if (RedisOpsUtils.checkExist(key) &&
+ jobId.equals(((MediaFileCountDTO) RedisOpsUtils.get(key)).getJobId())) {
return;
}
@@ -399,7 +431,6 @@
if (ResponseResult.CODE_SUCCESS != reply.getResult()) {
throw new RuntimeException("Failed to set media job upload priority. Error Code: " + reply.getResult());
}
- RedisOpsUtils.setWithExpire(key, jobId, RedisConst.DEVICE_ALIVE_SECOND * 5);
}
private WaylineJobEntity dto2Entity(WaylineJobDTO dto) {
@@ -407,16 +438,32 @@
if (dto == null) {
return builder.build();
}
+ if (Objects.nonNull(dto.getBeginTime())) {
+ builder.beginTime(dto.getBeginTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
+ }
if (Objects.nonNull(dto.getEndTime())) {
builder.endTime(dto.getEndTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
}
if (Objects.nonNull(dto.getExecuteTime())) {
builder.executeTime(dto.getExecuteTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
}
+ if (Objects.nonNull(dto.getCompletedTime())) {
+ builder.completedTime(dto.getCompletedTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
+ }
return builder.status(dto.getStatus())
.mediaCount(dto.getMediaCount())
.name(dto.getJobName())
.errorCode(dto.getCode())
+ .jobId(dto.getJobId())
+ .fileId(dto.getFileId())
+ .dockSn(dto.getDockSn())
+ .workspaceId(dto.getWorkspaceId())
+ .taskType(dto.getTaskType())
+ .waylineType(dto.getWaylineType())
+ .username(dto.getUsername())
+ .rthAltitude(dto.getRthAltitude())
+ .outOfControlAction(dto.getOutOfControlAction())
+ .parentId(dto.getParentId())
.build();
}
@@ -436,9 +483,17 @@
.orElse(DeviceDTO.builder().build()).getNickname())
.username(entity.getUsername())
.workspaceId(entity.getWorkspaceId())
- .status(entity.getStatus())
+ .status(WaylineJobStatusEnum.IN_PROGRESS.getVal() == entity.getStatus() &&
+ RedisOpsUtils.checkExist(RedisConst.WAYLINE_JOB_PAUSED_PREFIX + entity.getJobId()) ?
+ WaylineJobStatusEnum.PAUSED.getVal() : entity.getStatus())
.code(entity.getErrorCode())
- .executeTime(LocalDateTime.ofInstant(Instant.ofEpochMilli(entity.getExecuteTime()), ZoneId.systemDefault()))
+ .beginTime(LocalDateTime.ofInstant(Instant.ofEpochMilli(entity.getBeginTime()), ZoneId.systemDefault()))
+ .endTime(Objects.nonNull(entity.getEndTime()) ?
+ LocalDateTime.ofInstant(Instant.ofEpochMilli(entity.getEndTime()), ZoneId.systemDefault()) : null)
+ .executeTime(Objects.nonNull(entity.getExecuteTime()) ?
+ LocalDateTime.ofInstant(Instant.ofEpochMilli(entity.getExecuteTime()), ZoneId.systemDefault()) : null)
+ .completedTime(WaylineJobStatusEnum.find(entity.getStatus()).getEnd() ?
+ LocalDateTime.ofInstant(Instant.ofEpochMilli(entity.getUpdateTime()), ZoneId.systemDefault()) : null)
.taskType(entity.getTaskType())
.waylineType(entity.getWaylineType())
.rthAltitude(entity.getRthAltitude())
@@ -449,7 +504,7 @@
builder.endTime(LocalDateTime.ofInstant(Instant.ofEpochMilli(entity.getEndTime()), ZoneId.systemDefault()));
}
if (WaylineJobStatusEnum.IN_PROGRESS.getVal() == entity.getStatus() && RedisOpsUtils.getExpire(entity.getJobId()) > 0) {
- EventsReceiver<FlightTaskProgressReceiver> taskProgress = (EventsReceiver<FlightTaskProgressReceiver>) RedisOpsUtils.get(entity.getJobId());
+ EventsReceiver<WaylineTaskProgressReceiver> taskProgress = (EventsReceiver<WaylineTaskProgressReceiver>) RedisOpsUtils.get(RedisConst.WAYLINE_JOB_RUNNING_PREFIX + entity.getDockSn());
if (Objects.nonNull(taskProgress.getOutput()) && Objects.nonNull(taskProgress.getOutput().getProgress())) {
builder.progress(taskProgress.getOutput().getProgress().getPercent());
}
@@ -465,7 +520,7 @@
Object mediaFileCount = RedisOpsUtils.hashGet(countKey, entity.getJobId());
if (Objects.nonNull(mediaFileCount)) {
builder.uploadedCount(((MediaFileCountDTO) mediaFileCount).getUploadedCount())
- .uploading(RedisOpsUtils.checkExist(key) && entity.getJobId().equals(RedisOpsUtils.get(key)));
+ .uploading(RedisOpsUtils.checkExist(key) && entity.getJobId().equals(((MediaFileCountDTO)RedisOpsUtils.get(key)).getJobId()));
return builder.build();
}
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index de9dcfd..75c4872 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -39,14 +39,19 @@
age: 86400
mqtt:
- protocol: tcp
- host: Please enter your ip. # 192.168.1.1
- port: 1883
- username: JavaServer
- password: 123456
- client-id: 123456
- # Topics that need to be subscribed when initially connecting to mqtt, multiple topics are divided by ",".
- inbound-topic: sys/product/+/status,thing/product/+/requests
+ # @see com.dji.sample.component.mqtt.model.MqttUseEnum
+ # BASIC parameters are required.
+ BASIC:
+ protocol: MQTT # @see com.dji.sample.component.mqtt.model.MqttProtocolEnum
+ host: Please enter your ip.
+ port: 1883
+ username: JavaServer
+ password: 123456
+ client-id: 123456
+ # If the protocol is ws/wss, this value is required.
+ path:
+ # Topics that need to be subscribed when initially connecting to mqtt, multiple topics are divided by ",".
+ inbound-topic: sys/product/+/status,thing/product/+/requests
url:
manage:
@@ -68,7 +73,7 @@
prefix: /control
version: /api/v1
-# Tutorial: https://help.aliyun.com/document_detail/100624.htm?spm=a2c4g.11186623.0.0.74075e34eIhK7T#concept-xzh-nzk-2gb
+# Tutorial: https://www.alibabacloud.com/help/en/object-storage-service/latest/use-a-temporary-credential-provided-by-sts-to-access-oss
oss:
enable: true
provider: ali # @see com.dji.sample.component.OssConfiguration.model.enums.OssTypeEnum
@@ -114,4 +119,11 @@
ntp:
server:
- host: Google.mzr.me
\ No newline at end of file
+ host: Google.mzr.me
+
+# To create a license for an application: https://developer.dji.com/user/apps/#all
+cloud-api:
+ app:
+ id: Please enter the app id.
+ key: Please enter the app key.
+ license: Please enter the app license.
\ No newline at end of file
--
Gitblit v1.9.3