From b301d70c5f5a8eb11ab3259c0a38844b08e57106 Mon Sep 17 00:00:00 2001 From: Vincent Date: Fri, 22 Sep 2023 13:55:05 +0800 Subject: [PATCH 01/20] =?UTF-8?q?fix:=20flightId=E6=98=AF=E5=BA=94?= =?UTF-8?q?=E7=94=A8=E5=B1=82=E6=8F=90=E4=BE=9B=E7=9A=84,=E5=BA=94?= =?UTF-8?q?=E7=94=A8=E5=B1=82=E6=9C=89=E8=87=AA=E5=B7=B1=E7=9A=84id?= =?UTF-8?q?=E6=9E=84=E5=BB=BA=E8=A7=84=E5=88=99,=E5=A6=82=E6=9E=9C?= =?UTF-8?q?=E4=B8=8D=E6=98=AF=E8=AE=BE=E5=A4=87=E5=8E=9F=E5=9B=A0=E5=BF=85?= =?UTF-8?q?=E9=A1=BB=E6=8C=87=E5=AE=9A=E6=A0=BC=E5=BC=8F,=E6=9C=80?= =?UTF-8?q?=E5=A5=BD=E5=B0=B1=E4=B8=8D=E8=A6=81=E6=8E=A7=E5=88=B6flightId?= =?UTF-8?q?=E7=9A=84=E6=A0=BC=E5=BC=8F=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sdk/cloudapi/media/UploadFlighttaskMediaPrioritize.java | 3 ++- .../dji/sdk/cloudapi/wayline/FlighttaskExecuteRequest.java | 5 ++++- .../dji/sdk/cloudapi/wayline/FlighttaskPrepareRequest.java | 3 ++- .../com/dji/sdk/cloudapi/wayline/FlighttaskUndoRequest.java | 5 ++++- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/dji/sdk/cloudapi/media/UploadFlighttaskMediaPrioritize.java b/src/main/java/com/dji/sdk/cloudapi/media/UploadFlighttaskMediaPrioritize.java index 59c197f..5dfe88f 100644 --- a/src/main/java/com/dji/sdk/cloudapi/media/UploadFlighttaskMediaPrioritize.java +++ b/src/main/java/com/dji/sdk/cloudapi/media/UploadFlighttaskMediaPrioritize.java @@ -12,8 +12,9 @@ import javax.validation.constraints.Pattern; */ public class UploadFlighttaskMediaPrioritize extends BaseModel { + /* fix: flightId是应用层提供的,应用层有自己的id构建规则,如果不是设备原因必须指定格式,最好就不要控制flightId的格式了 by witcom@2023.09.22 */ @NotNull - @Pattern(regexp = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") + //@Pattern(regexp = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") private String flightId; public UploadFlighttaskMediaPrioritize() { diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskExecuteRequest.java b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskExecuteRequest.java index 451b784..eddd18c 100644 --- a/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskExecuteRequest.java +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskExecuteRequest.java @@ -12,8 +12,11 @@ import javax.validation.constraints.Pattern; */ public class FlighttaskExecuteRequest extends BaseModel { + /** + * fix: flightId是应用层提供的,应用层有自己的id构建规则,如果不是设备原因必须指定格式,最好就不要控制flightId的格式了 by witcom@2023.09.22 + */ @NotNull - @Pattern(regexp = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") + //@Pattern(regexp = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") private String flightId; public FlighttaskExecuteRequest() { diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskPrepareRequest.java b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskPrepareRequest.java index 41a7934..b111338 100755 --- a/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskPrepareRequest.java +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskPrepareRequest.java @@ -20,9 +20,10 @@ public class FlighttaskPrepareRequest extends BaseModel { /** * Task ID + * fix: flightId是应用层提供的,应用层有自己的id构建规则,如果不是设备原因必须指定格式,最好就不要控制flightId的格式了 by witcom@2023.09.22 */ @NotNull - @Pattern(regexp = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") + //@Pattern(regexp = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") private String flightId; /** diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskUndoRequest.java b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskUndoRequest.java index a38af28..cf385df 100644 --- a/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskUndoRequest.java +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskUndoRequest.java @@ -14,9 +14,12 @@ import java.util.List; */ public class FlighttaskUndoRequest extends BaseModel { + /** + * fix: flightId是应用层提供的,应用层有自己的id构建规则,如果不是设备原因必须指定格式,最好就不要控制flightId的格式了 by witcom@2023.09.22 + */ @NotNull @Size(min = 1) - private List<@Pattern(regexp = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") String> flightIds; + private List flightIds; public FlighttaskUndoRequest() { } From c8a40b9504476cb5ca5f06512ef4273077a7d067 Mon Sep 17 00:00:00 2001 From: Vincent Date: Fri, 22 Sep 2023 14:06:07 +0800 Subject: [PATCH 02/20] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=9C=AA?= =?UTF-8?q?=E5=90=AF=E5=8A=A8debug=E6=97=B6=E4=BB=8D=E7=84=B6=E9=9C=80?= =?UTF-8?q?=E8=A6=81=E6=9E=84=E9=80=A0debug=E5=8F=82=E6=95=B0=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/dji/sdk/mqtt/InboundMessageRouter.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/dji/sdk/mqtt/InboundMessageRouter.java b/src/main/java/com/dji/sdk/mqtt/InboundMessageRouter.java index 4d2a417..aae6d98 100644 --- a/src/main/java/com/dji/sdk/mqtt/InboundMessageRouter.java +++ b/src/main/java/com/dji/sdk/mqtt/InboundMessageRouter.java @@ -37,7 +37,10 @@ public class InboundMessageRouter extends AbstractMessageRouter { String topic = headers.get(MqttHeaders.RECEIVED_TOPIC).toString(); byte[] payload = (byte[])message.getPayload(); - log.debug("received topic: {} \t payload =>{}", topic, new String(payload)); + //fix: 修复未启动debug时仍然需要构造debug参数的问题 by witcom@2023.09.22 + if(log.isDebugEnabled()) { + log.debug("received topic: {} \t payload =>{}", topic, new String(payload)); + } CloudApiTopicEnum topicEnum = CloudApiTopicEnum.find(topic); MessageChannel bean = (MessageChannel) SpringBeanUtils.getBean(topicEnum.getBeanName()); From 0850908d83e86da899c89bf4f3cb48a9fd4610d0 Mon Sep 17 00:00:00 2001 From: Vincent Date: Fri, 22 Sep 2023 16:53:30 +0800 Subject: [PATCH 03/20] =?UTF-8?q?fix:=20OsdRouter=E5=9C=A8=E8=AE=BE?= =?UTF-8?q?=E5=A4=87=E6=9C=AA=E6=B3=A8=E5=86=8C=E7=9A=84=E6=83=85=E5=86=B5?= =?UTF-8?q?=E4=B8=8B=E6=8A=A5osd=E6=97=B6=E4=BA=A7=E7=94=9F=E5=A4=A7?= =?UTF-8?q?=E9=87=8F=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/dji/sdk/common/SDKManager.java | 9 +++++ .../java/com/dji/sdk/mqtt/osd/OsdRouter.java | 36 +++++++++++-------- 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/dji/sdk/common/SDKManager.java b/src/main/java/com/dji/sdk/common/SDKManager.java index ce07689..684f647 100644 --- a/src/main/java/com/dji/sdk/common/SDKManager.java +++ b/src/main/java/com/dji/sdk/common/SDKManager.java @@ -8,6 +8,7 @@ import com.dji.sdk.exception.CloudSDKErrorEnum; import com.dji.sdk.exception.CloudSDKException; import java.util.Objects; +import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; /** @@ -30,6 +31,14 @@ public class SDKManager { "The device has not been registered, please call the 'SDKManager.registerDevice()' method to register the device first."); } + public static Optional findDeviceSDK(String gatewaySn) { + if(SDK_MAP.containsKey(gatewaySn)){ + return Optional.of(SDK_MAP.get(gatewaySn)); + }else { + return Optional.empty(); + } + } + public static GatewayManager registerDevice(String gatewaySn, String droneSn, DeviceDomainEnum domain, DeviceTypeEnum type, DeviceSubTypeEnum subType, String gatewayThingVersion, String droneThingVersion) { return registerDevice(gatewaySn, droneSn, GatewayTypeEnum.find(DeviceEnum.find(domain, type, subType)), gatewayThingVersion, droneThingVersion); diff --git a/src/main/java/com/dji/sdk/mqtt/osd/OsdRouter.java b/src/main/java/com/dji/sdk/mqtt/osd/OsdRouter.java index 87f5282..6fbdde0 100644 --- a/src/main/java/com/dji/sdk/mqtt/osd/OsdRouter.java +++ b/src/main/java/com/dji/sdk/mqtt/osd/OsdRouter.java @@ -15,10 +15,7 @@ import org.springframework.integration.mqtt.support.MqttHeaders; import org.springframework.messaging.Message; import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; +import java.util.*; import static com.dji.sdk.mqtt.TopicConst.*; @@ -45,19 +42,28 @@ public class OsdRouter { } }, null) .handle((response, headers) -> { - GatewayManager gateway = SDKManager.getDeviceSDK(response.getGateway()); - OsdDeviceTypeEnum typeEnum = OsdDeviceTypeEnum.find(gateway.getType(), response.getFrom().equals(response.getGateway())); - Map data = (Map) response.getData(); - if (!typeEnum.isGateway()) { - List payloadData = (List) data.getOrDefault(PayloadModelEnum.PAYLOAD_KEY, new ArrayList<>()); - PayloadModelEnum.getAllIndexWithPosition().stream().filter(data::containsKey) - .map(data::get).forEach(payloadData::add); - data.put(PayloadModelEnum.PAYLOAD_KEY, payloadData); - } - return response.setData(Common.getObjectMapper().convertValue(data, typeEnum.getClassType())); + + // fix: getDeviceSDK抛出异常导致在设备未注册的情况下报osd时产生大量日志 witcom@2023.09.22 + //GatewayManager gateway = SDKManager.getDeviceSDK(response.getGateway()); + return SDKManager.findDeviceSDK(response.getGateway()) + .map(gateway-> { + + OsdDeviceTypeEnum typeEnum = OsdDeviceTypeEnum.find(gateway.getType(), response.getFrom().equals(response.getGateway())); + Map data = (Map) response.getData(); + if (!typeEnum.isGateway()) { + List payloadData = (List) data.getOrDefault(PayloadModelEnum.PAYLOAD_KEY, new ArrayList<>()); + PayloadModelEnum.getAllIndexWithPosition().stream().filter(data::containsKey) + .map(data::get).forEach(payloadData::add); + data.put(PayloadModelEnum.PAYLOAD_KEY, payloadData); + } + return response.setData(Common.getObjectMapper().convertValue(data, typeEnum.getClassType())); + }) + .orElse(null); }) + .filter(Objects::nonNull) .route(response -> OsdDeviceTypeEnum.find(response.getData().getClass()), - mapping -> Arrays.stream(OsdDeviceTypeEnum.values()).forEach(key -> mapping.channelMapping(key, key.getChannelName()))) + mapping -> Arrays.stream(OsdDeviceTypeEnum.values()) + .forEach(key -> mapping.channelMapping(key, key.getChannelName()))) .get(); } From 9d392c5eab796af1481b9771cb8547c42dff2f3f Mon Sep 17 00:00:00 2001 From: Vincent Date: Fri, 22 Sep 2023 20:04:09 +0800 Subject: [PATCH 04/20] =?UTF-8?q?feat:=20=E4=B8=BApublishWithReply?= =?UTF-8?q?=E6=8F=90=E4=BE=9B=E9=85=8D=E7=BD=AE=E9=80=89=E9=A1=B9.=20feat:?= =?UTF-8?q?=20=E6=94=AF=E6=8C=81beforePublishHook,=20afterPublishHook?= =?UTF-8?q?=E5=9B=9E=E8=B0=83.=20feat:=20publishWithReply=E6=8F=90?= =?UTF-8?q?=E4=BE=9BCompletableFuture=E6=94=AF=E6=8C=81.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dji/sdk/common/JDKLockBarrierImpl.java | 79 ++++++++++++++++++ .../com/dji/sdk/common/PublishBarrier.java | 22 +++++ .../dji/sdk/common/PublishBarrierResult.java | 41 ++++++++++ .../dji/sdk/common/PublishConfiguration.java | 82 +++++++++++++++++++ .../com/dji/sdk/common/PublishOption.java | 59 +++++++++++++ .../sdk/config/DefaultBeanConfiguration.java | 38 +++++++++ .../com/dji/sdk/mqtt/ChanBarrierAdapter.java | 43 ++++++++++ .../com/dji/sdk/mqtt/MqttGatewayPublish.java | 52 +++++++++++- .../property/PropertySetReplyHandler.java | 16 +++- .../sdk/mqtt/services/ServicesPublish.java | 34 ++++++++ .../mqtt/services/ServicesReplyHandler.java | 16 +++- 11 files changed, 475 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/dji/sdk/common/JDKLockBarrierImpl.java create mode 100644 src/main/java/com/dji/sdk/common/PublishBarrier.java create mode 100644 src/main/java/com/dji/sdk/common/PublishBarrierResult.java create mode 100644 src/main/java/com/dji/sdk/common/PublishConfiguration.java create mode 100644 src/main/java/com/dji/sdk/common/PublishOption.java create mode 100644 src/main/java/com/dji/sdk/config/DefaultBeanConfiguration.java create mode 100644 src/main/java/com/dji/sdk/mqtt/ChanBarrierAdapter.java diff --git a/src/main/java/com/dji/sdk/common/JDKLockBarrierImpl.java b/src/main/java/com/dji/sdk/common/JDKLockBarrierImpl.java new file mode 100644 index 0000000..85e8483 --- /dev/null +++ b/src/main/java/com/dji/sdk/common/JDKLockBarrierImpl.java @@ -0,0 +1,79 @@ +/************************************************* + * @copyright 2017 Flision Corporation Inc. + * @author: Vincent Chan @ Canton + * @date: 2023年09月22日 + * @version: 1.0.0 + * @description: + **************************************************/ +package com.dji.sdk.common; + +import com.dji.sdk.mqtt.Chan; +import com.dji.sdk.mqtt.CommonTopicRequest; +import com.dji.sdk.mqtt.CommonTopicResponse; + +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; + +public class JDKLockBarrierImpl implements PublishBarrier{ + + /** + * 在我的实现中是采用一个定期清理的TimedCache储存请求 + */ + private final ConcurrentHashMap container = new ConcurrentHashMap<>(); + + @Override + public void put(String identity, CommonTopicResponse receiveData) { + if(hasIdentity(identity)){ + container.get(identity).setData(receiveData); + } + } + + @Override + public void registerRequest(String identity, CommonTopicRequest requestData) { + container.put(identity,new JDKHolder()); + } + + @Override + public PublishBarrierResult await(String identity, long timeout) { + JDKHolder jdkHolder = container.get(identity); + if(Objects.isNull(jdkHolder)){ + throw new RuntimeException("等待指令返回前未注册指令到栅栏"); + } + jdkHolder.await(timeout); + + return jdkHolder.getResult(); + } + + @Override + public boolean hasIdentity(String identity) { + return container.containsKey(identity); + } + + public static class JDKHolder{ + volatile Object locker = new Object(); + CommonTopicResponse response = null; + + public void await(long timeout) { + synchronized (locker){ + try { + locker.wait(timeout); + }catch (InterruptedException e){} + } + } + + public void setData(CommonTopicResponse receiveData) { + this.response = receiveData; + synchronized (locker){ + locker.notify(); + } + } + + public PublishBarrierResult getResult() { + if(Objects.nonNull(response)){ + return PublishBarrierResult.ok(response); + }else{ + return PublishBarrierResult.EMPTY; + } + } + } +} diff --git a/src/main/java/com/dji/sdk/common/PublishBarrier.java b/src/main/java/com/dji/sdk/common/PublishBarrier.java new file mode 100644 index 0000000..55221c4 --- /dev/null +++ b/src/main/java/com/dji/sdk/common/PublishBarrier.java @@ -0,0 +1,22 @@ +/************************************************* + * @copyright 2017 Flision Corporation Inc. + * @author: Vincent Chan @ Canton + * @date: 2023年09月22日 + * @version: 1.0.0 + * @description: + **************************************************/ +package com.dji.sdk.common; + +import com.dji.sdk.mqtt.CommonTopicRequest; +import com.dji.sdk.mqtt.CommonTopicResponse; + +public interface PublishBarrier { + + void put(String identity, CommonTopicResponse receiveData); + + void registerRequest(String identity, CommonTopicRequest requestData); + + PublishBarrierResult await(String identity,long timeout); + + boolean hasIdentity(String identity); +} diff --git a/src/main/java/com/dji/sdk/common/PublishBarrierResult.java b/src/main/java/com/dji/sdk/common/PublishBarrierResult.java new file mode 100644 index 0000000..f50f29b --- /dev/null +++ b/src/main/java/com/dji/sdk/common/PublishBarrierResult.java @@ -0,0 +1,41 @@ +/************************************************* + * @copyright 2017 Flision Corporation Inc. + * @author: Vincent Chan @ Canton + * @date: 2023年09月22日 + * @version: 1.0.0 + * @description: + **************************************************/ +package com.dji.sdk.common; + +import com.dji.sdk.mqtt.CommonTopicResponse; + +public class PublishBarrierResult { + + public static PublishBarrierResult EMPTY = new PublishBarrierResult(); + + public static PublishBarrierResult ok(CommonTopicResponse data){ + return new PublishBarrierResult().setData(data); + } + + + boolean timeout = true; + + CommonTopicResponse data; + + private PublishBarrierResult() { + } + + private PublishBarrierResult setData(CommonTopicResponse data) { + this.data = data; + this.timeout = false; + return this; + } + + public boolean isTimeout(){ + return timeout; + } + + public CommonTopicResponse getData(){ + return data; + } +} diff --git a/src/main/java/com/dji/sdk/common/PublishConfiguration.java b/src/main/java/com/dji/sdk/common/PublishConfiguration.java new file mode 100644 index 0000000..4aae251 --- /dev/null +++ b/src/main/java/com/dji/sdk/common/PublishConfiguration.java @@ -0,0 +1,82 @@ +/************************************************* + * @copyright 2017 Flision Corporation Inc. + * @author: Vincent Chan @ Canton + * @date: 2023年09月22日 + * @version: 1.0.0 + * @description: + **************************************************/ +package com.dji.sdk.common; + +import com.dji.sdk.mqtt.CommonTopicRequest; + +import java.util.Objects; +import java.util.function.BiConsumer; +import java.util.function.Consumer; + +public class PublishConfiguration { + + String bid; + String tid; + + //默认超时 + int timeout = 3; + //请求发送前调用 + Consumer beforePublishHook = (e)->{}; + //收到请求回信后调用 + BiConsumer afterPublishHook = (req,rsp) ->{}; + + + public String getBid() { + return bid; + } + + public String getTid() { + return tid; + } + + public long getTimeout() { + return timeout * 1000; + } + + public void setBizId(String bid) { + this.bid = bid; + } + + public void setTransactionId(String tid) { + this.tid = tid; + } + + public void setTimeout(int timeout) { + this.timeout = timeout; + } + + public void setBeforePublishHook(Consumer callback) { + beforePublishHook = callback; + } + + public void setAfterPublishReplyHook(BiConsumer callback) { + afterPublishHook = callback; + } + + public void invokeBeforePublishHook(CommonTopicRequest req){ + if(Objects.nonNull(beforePublishHook)){ + try { + beforePublishHook.accept(req); + }catch (Throwable ex){ + //do nothing + //业务层的异常不理会 + } + } + } + + public void invokeAfterPublishReplyHook(CommonTopicRequest req, PublishBarrierResult result){ + if(Objects.nonNull(afterPublishHook)){ + try{ + afterPublishHook.accept(req,result); + }catch (Throwable ex){ + //do nothing + //业务层的异常不理会 + } + } + } +} diff --git a/src/main/java/com/dji/sdk/common/PublishOption.java b/src/main/java/com/dji/sdk/common/PublishOption.java new file mode 100644 index 0000000..505f667 --- /dev/null +++ b/src/main/java/com/dji/sdk/common/PublishOption.java @@ -0,0 +1,59 @@ +/************************************************* + * @copyright 2017 Flision Corporation Inc. + * @author: Vincent Chan @ Canton + * @date: 2023年09月22日 + * @version: 1.0.0 + * @description: + **************************************************/ +package com.dji.sdk.common; + +import com.dji.sdk.mqtt.CommonTopicRequest; +import com.dji.sdk.mqtt.CommonTopicResponse; +import com.google.common.base.Strings; + +import java.util.Objects; +import java.util.function.BiConsumer; +import java.util.function.Consumer; + +public class PublishOption { + + public static Consumer DEFAULT = (cfg)->{}; + + final PublishConfiguration configuration; + + public PublishOption(PublishConfiguration configuration) { + this.configuration = configuration; + } + + public PublishOption withBizId(String bid){ + if(!Strings.isNullOrEmpty(bid)){ + configuration.setBizId(bid); + } + return this; + } + + public PublishOption withTransactionId(String tid){ + if(!Strings.isNullOrEmpty(tid)){ + configuration.setTransactionId(tid); + } + return this; + } + + public PublishOption timeout(int second){ + configuration.setTimeout(second); + return this; + } + + public PublishOption beforePublish(Consumer callback){ + if(Objects.nonNull(callback)){ + configuration.setBeforePublishHook(callback); + } + return this; + } + public PublishOption afterPublishReply(BiConsumer callback){ + if(Objects.nonNull(callback)){ + configuration.setAfterPublishReplyHook(callback); + } + return this; + } +} diff --git a/src/main/java/com/dji/sdk/config/DefaultBeanConfiguration.java b/src/main/java/com/dji/sdk/config/DefaultBeanConfiguration.java new file mode 100644 index 0000000..853201d --- /dev/null +++ b/src/main/java/com/dji/sdk/config/DefaultBeanConfiguration.java @@ -0,0 +1,38 @@ +/************************************************* + * @copyright 2017 Flision Corporation Inc. + * @author: Vincent Chan @ Canton + * @date: 2023年09月22日 + * @version: 1.0.0 + * @description: + **************************************************/ +package com.dji.sdk.config; + +import com.dji.sdk.common.JDKLockBarrierImpl; +import com.dji.sdk.common.PublishBarrier; +import com.dji.sdk.mqtt.ChanBarrierAdapter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class DefaultBeanConfiguration { + + /** + * 使用者可以自定义PublishBarrier的实现,默认采用Chan实现 + */ + @Bean + @ConditionalOnMissingBean(PublishBarrier.class) + public PublishBarrier chanBarrier(){ + /** 原Chan实现 */ + return new ChanBarrierAdapter(); + } + + /** + * PublishBarrier 另一个实现, 采用同步锁 + */ +// @Bean +// @ConditionalOnMissingBean(PublishBarrier.class) +// public PublishBarrier jdkBarrier(){ +// return new JDKLockBarrierImpl(); +// } +} diff --git a/src/main/java/com/dji/sdk/mqtt/ChanBarrierAdapter.java b/src/main/java/com/dji/sdk/mqtt/ChanBarrierAdapter.java new file mode 100644 index 0000000..0238202 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/ChanBarrierAdapter.java @@ -0,0 +1,43 @@ +/************************************************* + * @copyright 2017 Flision Corporation Inc. + * @author: Vincent Chan @ Canton + * @date: 2023年09月22日 + * @version: 1.0.0 + * @description: + **************************************************/ +package com.dji.sdk.mqtt; + +import com.dji.sdk.common.PublishBarrier; +import com.dji.sdk.common.PublishBarrierResult; + +import java.util.Objects; + +public class ChanBarrierAdapter implements PublishBarrier { + @Override + public void put(String identity, CommonTopicResponse receiveData) { + Chan instance = Chan.getInstance(identity, false); + if(Objects.nonNull(instance)){ + instance.put(receiveData); + } + } + + @Override + public void registerRequest(String identity, CommonTopicRequest requestData) { + Chan.getInstance(identity, true); + } + + @Override + public PublishBarrierResult await(String identity,long timeout) { + Chan instance = Chan.getInstance(identity, false); + + CommonTopicResponse response = instance.get(identity, timeout); + + return Objects.nonNull(response) ? PublishBarrierResult.ok(response) : PublishBarrierResult.EMPTY; + } + + @Override + public boolean hasIdentity(String identity) { + Chan instance = Chan.getInstance(identity, false); + return Objects.nonNull(instance); + } +} diff --git a/src/main/java/com/dji/sdk/mqtt/MqttGatewayPublish.java b/src/main/java/com/dji/sdk/mqtt/MqttGatewayPublish.java index 8d60425..f04336b 100644 --- a/src/main/java/com/dji/sdk/mqtt/MqttGatewayPublish.java +++ b/src/main/java/com/dji/sdk/mqtt/MqttGatewayPublish.java @@ -1,9 +1,10 @@ package com.dji.sdk.mqtt; -import com.dji.sdk.common.Common; +import com.dji.sdk.common.*; import com.dji.sdk.exception.CloudSDKErrorEnum; import com.dji.sdk.exception.CloudSDKException; import com.fasterxml.jackson.core.JsonProcessingException; +import com.google.common.base.Strings; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.TypeMismatchException; import org.springframework.integration.mqtt.support.MqttHeaders; @@ -14,7 +15,10 @@ import org.springframework.util.StringUtils; import javax.annotation.Resource; import java.util.Objects; import java.util.UUID; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Consumer; /** * @author sean.zhou @@ -32,6 +36,9 @@ public class MqttGatewayPublish { @Resource private IMqttMessageGateway messageGateway; + @Resource + private PublishBarrier publishBarrier; + public void publish(String topic, int qos, CommonTopicRequest request) { try { log.debug("send topic: {}, payload: {}", topic, request.toString()); @@ -73,7 +80,9 @@ public class MqttGatewayPublish { AtomicInteger time = new AtomicInteger(0); boolean hasBid = StringUtils.hasText(request.getBid()); request.setBid(hasBid ? request.getBid() : UUID.randomUUID().toString()); + // Retry + // Is Retry necessary? why not use Spring @Retryable instead? while (time.getAndIncrement() <= retryCount) { this.publish(topic, request); @@ -97,5 +106,46 @@ public class MqttGatewayPublish { throw new CloudSDKException(CloudSDKErrorEnum.MQTT_PUBLISH_ABNORMAL, "No message reply received."); } + public CompletableFuture> publishWithReply(Class clazz, String topic, CommonTopicRequest request, Consumer options){ + PublishConfiguration config = prepareConfiguration(options); + request.setBid(config.getBid()); + request.setTid(config.getTid()); + + //use to log request data or the last chance to change some data + config.invokeBeforePublishHook(request); + + //注册barrier + String identity = request.getTid(); //提供栅栏标识 + publishBarrier.registerRequest(identity, request); + + return CompletableFuture.supplyAsync(()->{ + this.publish(topic, request); + + if(log.isDebugEnabled()){ log.debug("等待{}指令返回",identity); }; + PublishBarrierResult result = publishBarrier.await(identity,config.getTimeout()); + config.invokeAfterPublishReplyHook(request, result); + + if(result.isTimeout()){ + throw new CloudSDKException("Timeout"); //TODO: 换个更明确的异常更好 + } + if(log.isDebugEnabled()){ log.debug("{}指令已返回",identity); } + return result.getData(); + }); + } + + private PublishConfiguration prepareConfiguration(Consumer options){ + PublishConfiguration config = new PublishConfiguration(); + PublishOption option = new PublishOption(config); + options.accept(option); + + if(Strings.isNullOrEmpty(config.getBid())){ + config.setBizId(UUID.randomUUID().toString()); + } + + if(Strings.isNullOrEmpty(config.getTid())){ + config.setTransactionId(UUID.randomUUID().toString()); + } + return config; + } } \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/mqtt/property/PropertySetReplyHandler.java b/src/main/java/com/dji/sdk/mqtt/property/PropertySetReplyHandler.java index 1723e22..dc15147 100644 --- a/src/main/java/com/dji/sdk/mqtt/property/PropertySetReplyHandler.java +++ b/src/main/java/com/dji/sdk/mqtt/property/PropertySetReplyHandler.java @@ -1,6 +1,7 @@ package com.dji.sdk.mqtt.property; import com.dji.sdk.common.Common; +import com.dji.sdk.common.PublishBarrier; import com.dji.sdk.mqtt.Chan; import com.dji.sdk.mqtt.ChannelName; import com.fasterxml.jackson.core.type.TypeReference; @@ -9,6 +10,7 @@ import org.springframework.integration.annotation.ServiceActivator; import org.springframework.messaging.Message; import org.springframework.stereotype.Component; +import javax.annotation.Resource; import java.io.IOException; import java.util.Objects; @@ -20,6 +22,9 @@ import java.util.Objects; @Component public class PropertySetReplyHandler { + @Resource + PublishBarrier barrier; + private static final String RESULT_KEY = "result"; /** @@ -32,13 +37,18 @@ public class PropertySetReplyHandler { byte[] payload = (byte[])message.getPayload(); TopicPropertySetResponse receiver = Common.getObjectMapper().readValue(payload, new TypeReference() {}); - Chan chan = Chan.getInstance(receiver.getTid(), false); - if (Objects.isNull(chan)) { + //fix: use Barrier instead witcom@2023.09.22 + //Chan chan = Chan.getInstance(receiver.getTid(), false); +// if (Objects.isNull(chan)) { +// return; +// } + if(!barrier.hasIdentity(receiver.getTid())) { return; } receiver.setData(PropertySetReplyResultEnum.find( Common.getObjectMapper().convertValue(receiver.getData(), JsonNode.class).findValue(RESULT_KEY).intValue())); // Put the message to the chan object. - chan.put(receiver); + //chan.put(receiver); + barrier.put(receiver.getTid(), receiver); } } diff --git a/src/main/java/com/dji/sdk/mqtt/services/ServicesPublish.java b/src/main/java/com/dji/sdk/mqtt/services/ServicesPublish.java index 9ca29d2..6528453 100644 --- a/src/main/java/com/dji/sdk/mqtt/services/ServicesPublish.java +++ b/src/main/java/com/dji/sdk/mqtt/services/ServicesPublish.java @@ -1,6 +1,8 @@ package com.dji.sdk.mqtt.services; import com.dji.sdk.common.Common; +import com.dji.sdk.common.PublishOption; +import com.dji.sdk.mqtt.CommonTopicResponse; import com.dji.sdk.mqtt.MqttGatewayPublish; import com.dji.sdk.mqtt.TopicConst; import com.fasterxml.jackson.core.type.TypeReference; @@ -10,6 +12,8 @@ import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.util.Objects; import java.util.UUID; +import java.util.concurrent.CompletableFuture; +import java.util.function.Consumer; /** * @author sean @@ -60,6 +64,8 @@ public class ServicesPublish { public TopicServicesResponse> publish( TypeReference clazz, String sn, String method, Object data, String bid, int retryCount, long timeout) { + return this.publish(clazz, sn, method,data,ops-> ops.withBizId(bid).timeout((int)(timeout / 1000))).join(); + /* String topic = TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + Objects.requireNonNull(sn) + TopicConst.SERVICES_SUF; TopicServicesResponse response = (TopicServicesResponse) gatewayPublish.publishWithReply( ServicesReplyReceiver.class, topic, new TopicServicesRequest<>() @@ -84,6 +90,34 @@ public class ServicesPublish { reply.setOutput(mapper.convertValue(replyReceiver.getOutput(), clazz)); } return response.setData(reply); + + */ } + public CompletableFuture>> publish(TypeReference clazz, String sn, String method, Object data, Consumer options){ + String topic = TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + Objects.requireNonNull(sn) + TopicConst.SERVICES_SUF; + return gatewayPublish.publishWithReply(ServicesReplyReceiver.class, topic, new TopicServicesRequest<>() + .setTimestamp(System.currentTimeMillis()) + .setMethod(method) + .setData(Objects.requireNonNullElse(data, "")), options) + .thenApply(response->(TopicServicesResponse)response) + .thenApply(response->{ + ServicesReplyReceiver replyReceiver = (ServicesReplyReceiver) response.getData(); + ServicesReplyData reply = new ServicesReplyData().setResult(replyReceiver.getResult()); + if (Objects.isNull(clazz)) { + reply.setOutput((T) Objects.requireNonNullElse( + replyReceiver.getOutput(), Objects.requireNonNullElse(replyReceiver.getInfo(), ""))); + return response.setData(reply); + } + // put together in "output" + ObjectMapper mapper = Common.getObjectMapper(); + if (Objects.nonNull(replyReceiver.getInfo())) { + reply.setOutput(mapper.convertValue(replyReceiver.getInfo(), clazz)); + } + if (Objects.nonNull(replyReceiver.getOutput())) { + reply.setOutput(mapper.convertValue(replyReceiver.getOutput(), clazz)); + } + return response.setData(reply); + }); + } } diff --git a/src/main/java/com/dji/sdk/mqtt/services/ServicesReplyHandler.java b/src/main/java/com/dji/sdk/mqtt/services/ServicesReplyHandler.java index 01ee174..6e80d24 100644 --- a/src/main/java/com/dji/sdk/mqtt/services/ServicesReplyHandler.java +++ b/src/main/java/com/dji/sdk/mqtt/services/ServicesReplyHandler.java @@ -3,6 +3,7 @@ package com.dji.sdk.mqtt.services; import com.dji.sdk.cloudapi.log.FileUploadListResponse; import com.dji.sdk.cloudapi.log.LogMethodEnum; import com.dji.sdk.common.Common; +import com.dji.sdk.common.PublishBarrier; import com.dji.sdk.mqtt.Chan; import com.dji.sdk.mqtt.ChannelName; import com.fasterxml.jackson.core.type.TypeReference; @@ -10,6 +11,7 @@ import org.springframework.integration.annotation.ServiceActivator; import org.springframework.messaging.Message; import org.springframework.stereotype.Component; +import javax.annotation.Resource; import java.io.IOException; import java.util.Objects; @@ -21,6 +23,9 @@ import java.util.Objects; @Component public class ServicesReplyHandler { + @Resource + PublishBarrier barrier; + /** * Handle the reply message from topic "/services_reply". * @param message reply message @@ -32,14 +37,19 @@ public class ServicesReplyHandler { TopicServicesResponse receiver = Common.getObjectMapper() .readValue(payload, new TypeReference>() {}); - Chan chan = Chan.getInstance(receiver.getTid(), false); - if (Objects.isNull(chan)) { + //fix: use Barrier instead witcom@2023.09.22 +// Chan chan = Chan.getInstance(receiver.getTid(), false); +// if (Objects.isNull(chan)) { +// return; +// } + if(!barrier.hasIdentity(receiver.getTid())){ return; } if (LogMethodEnum.FILE_UPLOAD_LIST.getMethod().equals(receiver.getMethod())) { receiver.getData().setOutput(Common.getObjectMapper().convertValue(receiver.getData(), new TypeReference() {})); } - chan.put(receiver); + barrier.put(receiver.getTid(), receiver); + //chan.put(receiver); } } From 163f08aff534df4250a984b58183553b05f55995 Mon Sep 17 00:00:00 2001 From: Vincent Date: Fri, 22 Sep 2023 20:48:19 +0800 Subject: [PATCH 05/20] =?UTF-8?q?fix:=20MqttGatewayPublish#publish()=20log?= =?UTF-8?q?.debug=20=E6=9C=AA=E5=88=A4=E5=AE=9AisDebugEnable=20feat:=20add?= =?UTF-8?q?=20remark=20on=20ServicesPublish?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/dji/sdk/mqtt/MqttGatewayPublish.java | 8 ++++++-- .../com/dji/sdk/mqtt/services/ServicesPublish.java | 10 ++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/dji/sdk/mqtt/MqttGatewayPublish.java b/src/main/java/com/dji/sdk/mqtt/MqttGatewayPublish.java index f04336b..956e200 100644 --- a/src/main/java/com/dji/sdk/mqtt/MqttGatewayPublish.java +++ b/src/main/java/com/dji/sdk/mqtt/MqttGatewayPublish.java @@ -41,7 +41,9 @@ public class MqttGatewayPublish { public void publish(String topic, int qos, CommonTopicRequest request) { try { - log.debug("send topic: {}, payload: {}", topic, request.toString()); + if(log.isDebugEnabled()) { + log.debug("send topic: {}, payload: {}", topic, request.toString()); + } byte[] payload = Common.getObjectMapper().writeValueAsBytes(request); messageGateway.publish(topic, payload, qos); } catch (JsonProcessingException e) { @@ -52,7 +54,9 @@ public class MqttGatewayPublish { public void publish(String topic, int qos, CommonTopicResponse response) { try { - log.debug("send topic: {}, payload: {}", topic, response.toString()); + if(log.isDebugEnabled()) { + log.debug("send topic: {}, payload: {}", topic, response.toString()); + } byte[] payload = Common.getObjectMapper().writeValueAsBytes(response); messageGateway.publish(topic, payload, qos); } catch (JsonProcessingException e) { diff --git a/src/main/java/com/dji/sdk/mqtt/services/ServicesPublish.java b/src/main/java/com/dji/sdk/mqtt/services/ServicesPublish.java index 6528453..d554365 100644 --- a/src/main/java/com/dji/sdk/mqtt/services/ServicesPublish.java +++ b/src/main/java/com/dji/sdk/mqtt/services/ServicesPublish.java @@ -94,6 +94,16 @@ public class ServicesPublish { */ } + /** + * Remark by witcom@2023.09.22 + * TODO: 在贡献的版本到这里就不再往下修改了,需要修改所有AbstractXXXService和AOP,改动量很大 + * 主要思想是 + * 1.提供异步支持 + * 2.Chan的实现可由用户自定义 + * 3.提供发送选项参数 + * 4.提供发送前,接收后钩子用于记录请求和返回接近最原始的记录 + */ + public CompletableFuture>> publish(TypeReference clazz, String sn, String method, Object data, Consumer options){ String topic = TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + Objects.requireNonNull(sn) + TopicConst.SERVICES_SUF; return gatewayPublish.publishWithReply(ServicesReplyReceiver.class, topic, new TopicServicesRequest<>() From a79449a8a4cf21daf8b916bc1e1cb4847161e0ce Mon Sep 17 00:00:00 2001 From: Vincent Date: Mon, 25 Sep 2023 14:15:13 +0800 Subject: [PATCH 06/20] =?UTF-8?q?fix:=20SdkManager=E6=94=B9=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=EF=BC=8C=E7=94=B1=E5=AE=A2=E6=88=B7=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?gateway=E7=AE=A1=E7=90=86=E7=AD=96=E7=95=A5=20feat:=20=E6=8F=90?= =?UTF-8?q?=E4=BE=9BLocalCacheSDKManager=E9=BB=98=E8=AE=A4=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../component/ApplicationBootInitial.java | 6 +- .../service/impl/ControlServiceImpl.java | 3 + .../control/service/impl/DrcServiceImpl.java | 3 + .../service/impl/DeviceLogsServiceImpl.java | 3 + .../service/impl/DeviceServiceImpl.java | 3 + .../service/impl/LiveStreamServiceImpl.java | 3 + .../manage/service/impl/SDKDeviceService.java | 3 + .../service/impl/FlightTaskServiceImpl.java | 3 + .../dji/sdk/common/LocalCacheSDKManager.java | 65 +++++++++++++++++++ .../java/com/dji/sdk/common/SDKManager.java | 19 +++++- .../sdk/config/DefaultBeanConfiguration.java | 8 +++ .../java/com/dji/sdk/mqtt/osd/OsdRouter.java | 5 +- .../com/dji/sdk/mqtt/osd/OsdSubscribe.java | 7 +- .../com/dji/sdk/mqtt/state/StateRouter.java | 10 ++- .../dji/sdk/mqtt/state/StateSubscribe.java | 7 +- .../dji/sdk/mqtt/status/StatusSubscribe.java | 7 +- 16 files changed, 143 insertions(+), 12 deletions(-) create mode 100644 src/main/java/com/dji/sdk/common/LocalCacheSDKManager.java diff --git a/src/main/java/com/dji/sample/component/ApplicationBootInitial.java b/src/main/java/com/dji/sample/component/ApplicationBootInitial.java index 16a691c..5b1573a 100644 --- a/src/main/java/com/dji/sample/component/ApplicationBootInitial.java +++ b/src/main/java/com/dji/sample/component/ApplicationBootInitial.java @@ -11,6 +11,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; +import javax.annotation.Resource; import java.util.Optional; /** @@ -27,6 +28,9 @@ public class ApplicationBootInitial implements CommandLineRunner { @Autowired private IDeviceRedisService deviceRedisService; + @Resource + SDKManager sdkManager; + /** * Subscribe to the devices that exist in the redis when the program starts, * to prevent the data from being different from the pilot side due to program interruptions. @@ -44,7 +48,7 @@ public class ApplicationBootInitial implements CommandLineRunner { .map(Optional::get) .filter(device -> DeviceDomainEnum.DRONE != device.getDomain()) .forEach(device -> deviceService.subDeviceOnlineSubscribeTopic( - SDKManager.registerDevice(device.getDeviceSn(), device.getChildDeviceSn(), device.getDomain(), + sdkManager.registerDevice(device.getDeviceSn(), device.getChildDeviceSn(), device.getDomain(), device.getType(), device.getSubType(), device.getThingVersion(), deviceRedisService.getDeviceOnline(device.getChildDeviceSn()).map(DeviceDTO::getThingVersion).orElse(null)))); 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 530729e..4bd5b0f 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 @@ -68,6 +68,9 @@ public class ControlServiceImpl implements IControlService { @Qualifier("SDKWaylineService") private AbstractWaylineService abstractWaylineService; + @Autowired + SDKManager SDKManager; + private RemoteDebugHandler checkDebugCondition(String sn, RemoteDebugParam param, RemoteDebugMethodEnum controlMethodEnum) { RemoteDebugHandler handler = Objects.nonNull(controlMethodEnum.getClazz()) ? mapper.convertValue(Objects.nonNull(param) ? param : new Object(), controlMethodEnum.getClazz()) diff --git a/src/main/java/com/dji/sample/control/service/impl/DrcServiceImpl.java b/src/main/java/com/dji/sample/control/service/impl/DrcServiceImpl.java index 7aa86f3..29a61ec 100644 --- a/src/main/java/com/dji/sample/control/service/impl/DrcServiceImpl.java +++ b/src/main/java/com/dji/sample/control/service/impl/DrcServiceImpl.java @@ -84,6 +84,9 @@ public class DrcServiceImpl implements IDrcService { @Autowired private AbstractControlService abstractControlService; + @Autowired + SDKManager SDKManager; + @Override public void setDrcModeInRedis(String dockSn, String clientId) { RedisOpsUtils.setWithExpire(RedisConst.DRC_PREFIX + dockSn, clientId, RedisConst.DRC_MODE_ALIVE_SECOND); diff --git a/src/main/java/com/dji/sample/manage/service/impl/DeviceLogsServiceImpl.java b/src/main/java/com/dji/sample/manage/service/impl/DeviceLogsServiceImpl.java index 799de27..8acb72e 100644 --- a/src/main/java/com/dji/sample/manage/service/impl/DeviceLogsServiceImpl.java +++ b/src/main/java/com/dji/sample/manage/service/impl/DeviceLogsServiceImpl.java @@ -85,6 +85,9 @@ public class DeviceLogsServiceImpl extends AbstractLogService implements IDevice @Autowired private AbstractLogService abstractLogService; + @Autowired + SDKManager SDKManager; + @Override public PaginationData getUploadedLogs(String deviceSn, DeviceLogsQueryParam param) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper() 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 f5bbe95..018ab0b 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 @@ -124,6 +124,9 @@ public class DeviceServiceImpl implements IDeviceService { @Autowired private AbstractFirmwareService abstractFirmwareService; + @Autowired + SDKManager SDKManager; + @Override public void subDeviceOffline(String deviceSn) { // If no information about this device exists in the cache, the drone is considered to be offline. 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 2b1f590..13d14ff 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 @@ -46,6 +46,9 @@ public class LiveStreamServiceImpl implements ILiveStreamService { @Autowired private AbstractLivestreamService abstractLivestreamService; + @Autowired + SDKManager SDKManager; + @Override public List getLiveCapacity(String workspaceId) { diff --git a/src/main/java/com/dji/sample/manage/service/impl/SDKDeviceService.java b/src/main/java/com/dji/sample/manage/service/impl/SDKDeviceService.java index 81db422..541212d 100644 --- a/src/main/java/com/dji/sample/manage/service/impl/SDKDeviceService.java +++ b/src/main/java/com/dji/sample/manage/service/impl/SDKDeviceService.java @@ -57,6 +57,9 @@ public class SDKDeviceService extends AbstractDeviceService { @Autowired private IDevicePayloadService devicePayloadService; + @Autowired + SDKManager SDKManager; + @Override public TopicStatusResponse updateTopoOnline(TopicStatusRequest request, MessageHeaders headers) { UpdateTopoSubDevice updateTopoSubDevice = request.getData().getSubDevices().get(0); 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 938cd80..a7589e6 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 @@ -62,6 +62,9 @@ public class FlightTaskServiceImpl extends AbstractWaylineService implements IFl @Autowired private ObjectMapper mapper; + @Autowired + SDKManager SDKManager; + @Autowired private IWebSocketMessageService websocketMessageService; diff --git a/src/main/java/com/dji/sdk/common/LocalCacheSDKManager.java b/src/main/java/com/dji/sdk/common/LocalCacheSDKManager.java new file mode 100644 index 0000000..5bf9ff5 --- /dev/null +++ b/src/main/java/com/dji/sdk/common/LocalCacheSDKManager.java @@ -0,0 +1,65 @@ +/************************************************* + * @copyright 2017 Flision Corporation Inc. + * @author: Vincent Chan @ Canton + * @date: 2023年09月25日 + * @version: 1.0.0 + * @description: + **************************************************/ +package com.dji.sdk.common; + +import com.dji.sdk.cloudapi.device.DeviceDomainEnum; +import com.dji.sdk.cloudapi.device.DeviceEnum; +import com.dji.sdk.cloudapi.device.DeviceSubTypeEnum; +import com.dji.sdk.cloudapi.device.DeviceTypeEnum; +import com.dji.sdk.exception.CloudSDKErrorEnum; +import com.dji.sdk.exception.CloudSDKException; +import org.springframework.stereotype.Component; + +import java.util.Objects; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; + +public class LocalCacheSDKManager implements SDKManager{ + + final ConcurrentHashMap SDK_MAP = new ConcurrentHashMap<>(16); + + + @Override + public GatewayManager getDeviceSDK(String gatewaySn) { + if (SDK_MAP.containsKey(gatewaySn)) { + return SDK_MAP.get(gatewaySn); + } + throw new CloudSDKException(CloudSDKErrorEnum.NOT_REGISTERED, + "The device has not been registered, please call the 'SDKManager.registerDevice()' method to register the device first."); + } + + @Override + public Optional findDeviceSDK(String gatewaySn) { + if(SDK_MAP.containsKey(gatewaySn)){ + return Optional.of(SDK_MAP.get(gatewaySn)); + }else { + return Optional.empty(); + } + } + + @Override + public GatewayManager registerDevice(String gatewaySn, String droneSn, DeviceDomainEnum domain, DeviceTypeEnum type, DeviceSubTypeEnum subType, String gatewayThingVersion, String droneThingVersion) { + return registerDevice(gatewaySn, droneSn, GatewayTypeEnum.find(DeviceEnum.find(domain, type, subType)), gatewayThingVersion, droneThingVersion); + } + + @Override + public GatewayManager registerDevice(String gatewaySn, String droneSn, GatewayTypeEnum type, String gatewayThingVersion, String droneThingVersion) { + return registerDevice(new GatewayManager(Objects.requireNonNull(gatewaySn), droneSn, type, gatewayThingVersion, droneThingVersion)); + } + + @Override + public GatewayManager registerDevice(GatewayManager gateway) { + SDK_MAP.put(gateway.getGatewaySn(), gateway); + return gateway; + } + + @Override + public void logoutDevice(String gatewaySn) { + SDK_MAP.remove(gatewaySn); + } +} diff --git a/src/main/java/com/dji/sdk/common/SDKManager.java b/src/main/java/com/dji/sdk/common/SDKManager.java index 684f647..61b4b3f 100644 --- a/src/main/java/com/dji/sdk/common/SDKManager.java +++ b/src/main/java/com/dji/sdk/common/SDKManager.java @@ -15,9 +15,24 @@ import java.util.concurrent.ConcurrentHashMap; * @author sean * @version 1.7 * @date 2023/5/19 + * + * fix: 改接口,由客户决定Gateway管理策略 witcom@2023.09.25 */ -public class SDKManager { +public interface SDKManager { + GatewayManager getDeviceSDK(String gatewaySn); + + Optional findDeviceSDK(String gatewaySn); + GatewayManager registerDevice(String gatewaySn, String droneSn, + DeviceDomainEnum domain, DeviceTypeEnum type, DeviceSubTypeEnum subType, String gatewayThingVersion, String droneThingVersion); + + GatewayManager registerDevice(String gatewaySn, String droneSn, GatewayTypeEnum type, String gatewayThingVersion, String droneThingVersion); + + GatewayManager registerDevice(GatewayManager gateway); + + void logoutDevice(String gatewaySn); + +/* private SDKManager() { } @@ -56,4 +71,6 @@ public class SDKManager { public static void logoutDevice(String gatewaySn) { SDK_MAP.remove(gatewaySn); } + + */ } diff --git a/src/main/java/com/dji/sdk/config/DefaultBeanConfiguration.java b/src/main/java/com/dji/sdk/config/DefaultBeanConfiguration.java index 853201d..3e03b0c 100644 --- a/src/main/java/com/dji/sdk/config/DefaultBeanConfiguration.java +++ b/src/main/java/com/dji/sdk/config/DefaultBeanConfiguration.java @@ -8,7 +8,9 @@ package com.dji.sdk.config; import com.dji.sdk.common.JDKLockBarrierImpl; +import com.dji.sdk.common.LocalCacheSDKManager; import com.dji.sdk.common.PublishBarrier; +import com.dji.sdk.common.SDKManager; import com.dji.sdk.mqtt.ChanBarrierAdapter; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; @@ -17,6 +19,12 @@ import org.springframework.context.annotation.Configuration; @Configuration public class DefaultBeanConfiguration { + @Bean + @ConditionalOnMissingBean(SDKManager.class) + public SDKManager localCacheSDKManager(){ + return new LocalCacheSDKManager(); + } + /** * 使用者可以自定义PublishBarrier的实现,默认采用Chan实现 */ diff --git a/src/main/java/com/dji/sdk/mqtt/osd/OsdRouter.java b/src/main/java/com/dji/sdk/mqtt/osd/OsdRouter.java index 6fbdde0..814dfa2 100644 --- a/src/main/java/com/dji/sdk/mqtt/osd/OsdRouter.java +++ b/src/main/java/com/dji/sdk/mqtt/osd/OsdRouter.java @@ -14,6 +14,7 @@ import org.springframework.integration.dsl.IntegrationFlows; import org.springframework.integration.mqtt.support.MqttHeaders; import org.springframework.messaging.Message; +import javax.annotation.Resource; import java.io.IOException; import java.util.*; @@ -29,7 +30,7 @@ import static com.dji.sdk.mqtt.TopicConst.*; public class OsdRouter { @Bean - public IntegrationFlow osdRouterFlow() { + public IntegrationFlow osdRouterFlow(SDKManager sdkManager) { return IntegrationFlows .from(ChannelName.INBOUND_OSD) .transform(Message.class, source -> { @@ -45,7 +46,7 @@ public class OsdRouter { // fix: getDeviceSDK抛出异常导致在设备未注册的情况下报osd时产生大量日志 witcom@2023.09.22 //GatewayManager gateway = SDKManager.getDeviceSDK(response.getGateway()); - return SDKManager.findDeviceSDK(response.getGateway()) + return sdkManager.findDeviceSDK(response.getGateway()) .map(gateway-> { OsdDeviceTypeEnum typeEnum = OsdDeviceTypeEnum.find(gateway.getType(), response.getFrom().equals(response.getGateway())); diff --git a/src/main/java/com/dji/sdk/mqtt/osd/OsdSubscribe.java b/src/main/java/com/dji/sdk/mqtt/osd/OsdSubscribe.java index bc359b2..ca433c6 100644 --- a/src/main/java/com/dji/sdk/mqtt/osd/OsdSubscribe.java +++ b/src/main/java/com/dji/sdk/mqtt/osd/OsdSubscribe.java @@ -22,8 +22,11 @@ public class OsdSubscribe { @Resource private IMqttTopicService topicService; + @Resource + SDKManager sdkManager; + public void subscribe(GatewayManager gateway, boolean unsubscribeSubDevice) { - SDKManager.registerDevice(gateway); + sdkManager.registerDevice(gateway); topicService.subscribe(String.format(TOPIC, gateway.getGatewaySn())); if (unsubscribeSubDevice) { topicService.unsubscribe(String.format(TOPIC, gateway.getDroneSn())); @@ -35,7 +38,7 @@ public class OsdSubscribe { } public void unsubscribe(GatewayManager gateway) { - SDKManager.logoutDevice(gateway.getGatewaySn()); + sdkManager.logoutDevice(gateway.getGatewaySn()); topicService.unsubscribe(String.format(TOPIC, gateway.getGatewaySn())); if (null != gateway.getDroneSn()) { topicService.unsubscribe(String.format(TOPIC, gateway.getDroneSn())); diff --git a/src/main/java/com/dji/sdk/mqtt/state/StateRouter.java b/src/main/java/com/dji/sdk/mqtt/state/StateRouter.java index b26c00e..30ccfbb 100644 --- a/src/main/java/com/dji/sdk/mqtt/state/StateRouter.java +++ b/src/main/java/com/dji/sdk/mqtt/state/StateRouter.java @@ -1,6 +1,7 @@ package com.dji.sdk.mqtt.state; import com.dji.sdk.common.Common; +import com.dji.sdk.common.GatewayTypeEnum; import com.dji.sdk.common.SDKManager; import com.dji.sdk.exception.CloudSDKErrorEnum; import com.dji.sdk.exception.CloudSDKException; @@ -13,6 +14,7 @@ import org.springframework.integration.dsl.IntegrationFlows; import org.springframework.integration.mqtt.support.MqttHeaders; import org.springframework.messaging.Message; +import javax.annotation.Resource; import java.io.IOException; import java.util.Arrays; import java.util.Map; @@ -29,6 +31,9 @@ import static com.dji.sdk.mqtt.TopicConst.*; @Configuration public class StateRouter { + @Resource + SDKManager sdkManager; + @Bean public IntegrationFlow stateDataRouterFlow() { return IntegrationFlows @@ -51,13 +56,14 @@ public class StateRouter { private Class getTypeReference(String gatewaySn, Object data) { Set keys = ((Map) data).keySet(); - switch (SDKManager.getDeviceSDK(gatewaySn).getType()) { + GatewayTypeEnum type = sdkManager.getDeviceSDK(gatewaySn).getType(); + switch (type) { case RC: return RcStateDataKeyEnum.find(keys).getClassType(); case DOCK: return DockStateDataKeyEnum.find(keys).getClassType(); default: - throw new CloudSDKException(CloudSDKErrorEnum.WRONG_DATA, "Unexpected value: " + SDKManager.getDeviceSDK(gatewaySn).getType()); + throw new CloudSDKException(CloudSDKErrorEnum.WRONG_DATA, "Unexpected value: " + type); } } } \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/mqtt/state/StateSubscribe.java b/src/main/java/com/dji/sdk/mqtt/state/StateSubscribe.java index 7a1a746..cf8ec17 100644 --- a/src/main/java/com/dji/sdk/mqtt/state/StateSubscribe.java +++ b/src/main/java/com/dji/sdk/mqtt/state/StateSubscribe.java @@ -20,10 +20,13 @@ public class StateSubscribe { @Resource private IMqttTopicService topicService; + @Resource + SDKManager sdkManager; + public static final String TOPIC = TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + "%s" + TopicConst.STATE_SUF; public void subscribe(GatewayManager gateway, boolean unsubscribeSubDevice) { - SDKManager.registerDevice(gateway); + sdkManager.registerDevice(gateway); topicService.subscribe(String.format(TOPIC, gateway.getGatewaySn())); if (unsubscribeSubDevice) { topicService.unsubscribe(String.format(TOPIC, gateway.getDroneSn())); @@ -35,7 +38,7 @@ public class StateSubscribe { } public void unsubscribe(GatewayManager gateway) { - SDKManager.logoutDevice(gateway.getGatewaySn()); + sdkManager.logoutDevice(gateway.getGatewaySn()); topicService.unsubscribe(String.format(TOPIC, gateway.getGatewaySn())); if (null != gateway.getDroneSn()) { topicService.unsubscribe(String.format(TOPIC, gateway.getDroneSn())); diff --git a/src/main/java/com/dji/sdk/mqtt/status/StatusSubscribe.java b/src/main/java/com/dji/sdk/mqtt/status/StatusSubscribe.java index 2412067..178e70d 100644 --- a/src/main/java/com/dji/sdk/mqtt/status/StatusSubscribe.java +++ b/src/main/java/com/dji/sdk/mqtt/status/StatusSubscribe.java @@ -22,8 +22,11 @@ public class StatusSubscribe { @Resource private IMqttTopicService topicService; + @Resource + SDKManager sdkManager; + public void subscribe(GatewayManager gateway) { - SDKManager.registerDevice(gateway); + sdkManager.registerDevice(gateway); topicService.subscribe(String.format(TOPIC, gateway.getGatewaySn())); } @@ -32,7 +35,7 @@ public class StatusSubscribe { } public void unsubscribe(GatewayManager gateway) { - SDKManager.logoutDevice(gateway.getGatewaySn()); + sdkManager.logoutDevice(gateway.getGatewaySn()); topicService.unsubscribe(String.format(TOPIC, gateway.getGatewaySn())); } From 52ec34679583284d54165a6b7339d82def621bdd Mon Sep 17 00:00:00 2001 From: Vincent Date: Mon, 25 Sep 2023 15:18:43 +0800 Subject: [PATCH 07/20] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E5=85=A8?= =?UTF-8?q?=E5=B1=80=E5=8F=91=E9=80=81=E9=BB=98=E8=AE=A4=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dji/sdk/common/PublishConfiguration.java | 12 +++++- .../sdk/config/DefaultBeanConfiguration.java | 42 +++++++++++++++++-- .../com/dji/sdk/mqtt/GlobalPublishOption.java | 23 ++++++++++ .../com/dji/sdk/mqtt/MqttGatewayPublish.java | 15 ++++++- 4 files changed, 84 insertions(+), 8 deletions(-) create mode 100644 src/main/java/com/dji/sdk/mqtt/GlobalPublishOption.java diff --git a/src/main/java/com/dji/sdk/common/PublishConfiguration.java b/src/main/java/com/dji/sdk/common/PublishConfiguration.java index 4aae251..7ea22ab 100644 --- a/src/main/java/com/dji/sdk/common/PublishConfiguration.java +++ b/src/main/java/com/dji/sdk/common/PublishConfiguration.java @@ -21,9 +21,9 @@ public class PublishConfiguration { //默认超时 int timeout = 3; //请求发送前调用 - Consumer beforePublishHook = (e)->{}; + Consumer beforePublishHook = null; //收到请求回信后调用 - BiConsumer afterPublishHook = (req,rsp) ->{}; + BiConsumer afterPublishHook = null; public String getBid() { @@ -79,4 +79,12 @@ public class PublishConfiguration { } } } + + public boolean noneBeforePublishHook() { + return Objects.isNull(beforePublishHook); + } + + public boolean noneAfterPublishHook() { + return Objects.isNull(afterPublishHook); + } } diff --git a/src/main/java/com/dji/sdk/config/DefaultBeanConfiguration.java b/src/main/java/com/dji/sdk/config/DefaultBeanConfiguration.java index 3e03b0c..80c40d1 100644 --- a/src/main/java/com/dji/sdk/config/DefaultBeanConfiguration.java +++ b/src/main/java/com/dji/sdk/config/DefaultBeanConfiguration.java @@ -7,18 +7,52 @@ **************************************************/ package com.dji.sdk.config; -import com.dji.sdk.common.JDKLockBarrierImpl; -import com.dji.sdk.common.LocalCacheSDKManager; -import com.dji.sdk.common.PublishBarrier; -import com.dji.sdk.common.SDKManager; +import com.dji.sdk.common.*; import com.dji.sdk.mqtt.ChanBarrierAdapter; +import com.dji.sdk.mqtt.CommonTopicRequest; +import com.dji.sdk.mqtt.GlobalPublishOption; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import java.util.UUID; +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import java.util.function.Supplier; + @Configuration public class DefaultBeanConfiguration { + /** + * 全局发送默认设置 + * @return + */ + @Bean + @ConditionalOnMissingBean(GlobalPublishOption.class) + public GlobalPublishOption defaultPublishOption(){ + return new GlobalPublishOption() { + @Override + public Supplier defaultTransactionId() { + return ()-> UUID.randomUUID().toString(); + } + + @Override + public Supplier defaultBizId() { + return ()-> UUID.randomUUID().toString(); + } + + @Override + public Consumer defaultBeforePublishHook() { + return null; + } + + @Override + public BiConsumer defaultAfterPublishHook() { + return null; + } + }; + } + @Bean @ConditionalOnMissingBean(SDKManager.class) public SDKManager localCacheSDKManager(){ diff --git a/src/main/java/com/dji/sdk/mqtt/GlobalPublishOption.java b/src/main/java/com/dji/sdk/mqtt/GlobalPublishOption.java new file mode 100644 index 0000000..88f797a --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/GlobalPublishOption.java @@ -0,0 +1,23 @@ +/************************************************* + * @copyright 2017 Flision Corporation Inc. + * @author: Vincent Chan @ Canton + * @date: 2023年09月25日 + * @version: 1.0.0 + * @description: 全局发送默认配置 + **************************************************/ +package com.dji.sdk.mqtt; + +import com.dji.sdk.common.PublishBarrierResult; + +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import java.util.function.Supplier; + +public interface GlobalPublishOption { + Supplier defaultTransactionId(); + Supplier defaultBizId(); + + Consumer defaultBeforePublishHook(); + BiConsumer defaultAfterPublishHook(); + +} diff --git a/src/main/java/com/dji/sdk/mqtt/MqttGatewayPublish.java b/src/main/java/com/dji/sdk/mqtt/MqttGatewayPublish.java index 956e200..e2d1b88 100644 --- a/src/main/java/com/dji/sdk/mqtt/MqttGatewayPublish.java +++ b/src/main/java/com/dji/sdk/mqtt/MqttGatewayPublish.java @@ -39,6 +39,9 @@ public class MqttGatewayPublish { @Resource private PublishBarrier publishBarrier; + @Resource + private GlobalPublishOption globalOptions; + public void publish(String topic, int qos, CommonTopicRequest request) { try { if(log.isDebugEnabled()) { @@ -144,11 +147,19 @@ public class MqttGatewayPublish { options.accept(option); if(Strings.isNullOrEmpty(config.getBid())){ - config.setBizId(UUID.randomUUID().toString()); + config.setBizId(globalOptions.defaultBizId().get()); } if(Strings.isNullOrEmpty(config.getTid())){ - config.setTransactionId(UUID.randomUUID().toString()); + config.setTransactionId(globalOptions.defaultTransactionId().get()); + } + + if(config.noneBeforePublishHook()){ + config.setBeforePublishHook(globalOptions.defaultBeforePublishHook()); + } + + if(config.noneAfterPublishHook()){ + config.setAfterPublishReplyHook(globalOptions.defaultAfterPublishHook()); } return config; } From 6e92736e61253262326599124cdb3492695521a3 Mon Sep 17 00:00:00 2001 From: Vincent Date: Mon, 25 Sep 2023 15:41:20 +0800 Subject: [PATCH 08/20] =?UTF-8?q?feat:=20=E4=BD=BF=E6=A0=85=E6=A0=8F?= =?UTF-8?q?=E6=A0=87=E8=AF=86=E5=8F=AF=E7=94=B1=E7=94=A8=E6=88=B7=E8=87=AA?= =?UTF-8?q?=E5=AE=9A=E4=B9=89=E6=A0=87=E8=AF=86=E7=94=9F=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/dji/sdk/common/JDKLockBarrierImpl.java | 10 ++++++++++ src/main/java/com/dji/sdk/common/PublishBarrier.java | 4 ++++ src/main/java/com/dji/sdk/mqtt/ChanBarrierAdapter.java | 10 ++++++++++ src/main/java/com/dji/sdk/mqtt/MqttGatewayPublish.java | 2 +- .../dji/sdk/mqtt/property/PropertySetReplyHandler.java | 5 +++-- .../dji/sdk/mqtt/services/ServicesReplyHandler.java | 5 +++-- 6 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/dji/sdk/common/JDKLockBarrierImpl.java b/src/main/java/com/dji/sdk/common/JDKLockBarrierImpl.java index 85e8483..e7d5ae8 100644 --- a/src/main/java/com/dji/sdk/common/JDKLockBarrierImpl.java +++ b/src/main/java/com/dji/sdk/common/JDKLockBarrierImpl.java @@ -21,6 +21,16 @@ public class JDKLockBarrierImpl implements PublishBarrier{ */ private final ConcurrentHashMap container = new ConcurrentHashMap<>(); + @Override + public String generateIdentity(CommonTopicRequest requestData) { + return requestData.getTid(); + } + + @Override + public String generateIdentity(CommonTopicResponse receiveData) { + return receiveData.getTid(); + } + @Override public void put(String identity, CommonTopicResponse receiveData) { if(hasIdentity(identity)){ diff --git a/src/main/java/com/dji/sdk/common/PublishBarrier.java b/src/main/java/com/dji/sdk/common/PublishBarrier.java index 55221c4..e5b0071 100644 --- a/src/main/java/com/dji/sdk/common/PublishBarrier.java +++ b/src/main/java/com/dji/sdk/common/PublishBarrier.java @@ -12,6 +12,10 @@ import com.dji.sdk.mqtt.CommonTopicResponse; public interface PublishBarrier { + //构建栅栏标识方法 + String generateIdentity(CommonTopicRequest requestData); + String generateIdentity(CommonTopicResponse receiveData); + void put(String identity, CommonTopicResponse receiveData); void registerRequest(String identity, CommonTopicRequest requestData); diff --git a/src/main/java/com/dji/sdk/mqtt/ChanBarrierAdapter.java b/src/main/java/com/dji/sdk/mqtt/ChanBarrierAdapter.java index 0238202..368db35 100644 --- a/src/main/java/com/dji/sdk/mqtt/ChanBarrierAdapter.java +++ b/src/main/java/com/dji/sdk/mqtt/ChanBarrierAdapter.java @@ -13,6 +13,16 @@ import com.dji.sdk.common.PublishBarrierResult; import java.util.Objects; public class ChanBarrierAdapter implements PublishBarrier { + @Override + public String generateIdentity(CommonTopicRequest requestData) { + return requestData.getTid(); + } + + @Override + public String generateIdentity(CommonTopicResponse receiveData) { + return receiveData.getTid(); + } + @Override public void put(String identity, CommonTopicResponse receiveData) { Chan instance = Chan.getInstance(identity, false); diff --git a/src/main/java/com/dji/sdk/mqtt/MqttGatewayPublish.java b/src/main/java/com/dji/sdk/mqtt/MqttGatewayPublish.java index e2d1b88..ceeaf97 100644 --- a/src/main/java/com/dji/sdk/mqtt/MqttGatewayPublish.java +++ b/src/main/java/com/dji/sdk/mqtt/MqttGatewayPublish.java @@ -122,7 +122,7 @@ public class MqttGatewayPublish { config.invokeBeforePublishHook(request); //注册barrier - String identity = request.getTid(); //提供栅栏标识 + String identity = publishBarrier.generateIdentity(request); //提供栅栏标识 publishBarrier.registerRequest(identity, request); return CompletableFuture.supplyAsync(()->{ diff --git a/src/main/java/com/dji/sdk/mqtt/property/PropertySetReplyHandler.java b/src/main/java/com/dji/sdk/mqtt/property/PropertySetReplyHandler.java index dc15147..11c171e 100644 --- a/src/main/java/com/dji/sdk/mqtt/property/PropertySetReplyHandler.java +++ b/src/main/java/com/dji/sdk/mqtt/property/PropertySetReplyHandler.java @@ -42,13 +42,14 @@ public class PropertySetReplyHandler { // if (Objects.isNull(chan)) { // return; // } - if(!barrier.hasIdentity(receiver.getTid())) { + String identity = barrier.generateIdentity(receiver); + if(!barrier.hasIdentity(identity)) { return; } receiver.setData(PropertySetReplyResultEnum.find( Common.getObjectMapper().convertValue(receiver.getData(), JsonNode.class).findValue(RESULT_KEY).intValue())); // Put the message to the chan object. //chan.put(receiver); - barrier.put(receiver.getTid(), receiver); + barrier.put(identity, receiver); } } diff --git a/src/main/java/com/dji/sdk/mqtt/services/ServicesReplyHandler.java b/src/main/java/com/dji/sdk/mqtt/services/ServicesReplyHandler.java index 6e80d24..1ea2af3 100644 --- a/src/main/java/com/dji/sdk/mqtt/services/ServicesReplyHandler.java +++ b/src/main/java/com/dji/sdk/mqtt/services/ServicesReplyHandler.java @@ -42,14 +42,15 @@ public class ServicesReplyHandler { // if (Objects.isNull(chan)) { // return; // } - if(!barrier.hasIdentity(receiver.getTid())){ + String identity = barrier.generateIdentity(receiver); + if(!barrier.hasIdentity(identity)){ return; } if (LogMethodEnum.FILE_UPLOAD_LIST.getMethod().equals(receiver.getMethod())) { receiver.getData().setOutput(Common.getObjectMapper().convertValue(receiver.getData(), new TypeReference() {})); } - barrier.put(receiver.getTid(), receiver); + barrier.put(identity, receiver); //chan.put(receiver); } } From 97c4d3f4b238f192338ba95b423526ec56aa4ade Mon Sep 17 00:00:00 2001 From: Vincent Date: Mon, 25 Sep 2023 16:59:56 +0800 Subject: [PATCH 09/20] =?UTF-8?q?fix:=20=E8=B0=83=E6=95=B4publish=20hook?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E4=BD=BF=E5=AE=A2=E6=88=B7=E7=9C=8B=E5=88=B0?= =?UTF-8?q?=E6=9B=B4=E5=A4=9A=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dji/sdk/common/PublishBarrierResult.java | 4 +- .../dji/sdk/common/PublishConfiguration.java | 16 ++++---- .../com/dji/sdk/common/PublishOption.java | 6 +-- .../com/dji/sdk/common/PublishRequest.java | 20 ++++++++++ .../com/dji/sdk/common/PublishResult.java | 17 ++++++++ .../common/ReadonlyPublishConfiguration.java | 17 ++++++++ .../sdk/config/DefaultBeanConfiguration.java | 6 +-- .../com/dji/sdk/mqtt/GlobalPublishOption.java | 5 ++- .../com/dji/sdk/mqtt/MqttGatewayPublish.java | 39 +++++++++++++++++-- 9 files changed, 107 insertions(+), 23 deletions(-) create mode 100644 src/main/java/com/dji/sdk/common/PublishRequest.java create mode 100644 src/main/java/com/dji/sdk/common/PublishResult.java create mode 100644 src/main/java/com/dji/sdk/common/ReadonlyPublishConfiguration.java diff --git a/src/main/java/com/dji/sdk/common/PublishBarrierResult.java b/src/main/java/com/dji/sdk/common/PublishBarrierResult.java index f50f29b..38314fd 100644 --- a/src/main/java/com/dji/sdk/common/PublishBarrierResult.java +++ b/src/main/java/com/dji/sdk/common/PublishBarrierResult.java @@ -9,7 +9,7 @@ package com.dji.sdk.common; import com.dji.sdk.mqtt.CommonTopicResponse; -public class PublishBarrierResult { +public class PublishBarrierResult implements PublishResult { public static PublishBarrierResult EMPTY = new PublishBarrierResult(); @@ -35,7 +35,7 @@ public class PublishBarrierResult { return timeout; } - public CommonTopicResponse getData(){ + public CommonTopicResponse getData(){ return data; } } diff --git a/src/main/java/com/dji/sdk/common/PublishConfiguration.java b/src/main/java/com/dji/sdk/common/PublishConfiguration.java index 7ea22ab..bfd008c 100644 --- a/src/main/java/com/dji/sdk/common/PublishConfiguration.java +++ b/src/main/java/com/dji/sdk/common/PublishConfiguration.java @@ -7,13 +7,11 @@ **************************************************/ package com.dji.sdk.common; -import com.dji.sdk.mqtt.CommonTopicRequest; - import java.util.Objects; import java.util.function.BiConsumer; import java.util.function.Consumer; -public class PublishConfiguration { +public class PublishConfiguration implements ReadonlyPublishConfiguration { String bid; String tid; @@ -21,9 +19,9 @@ public class PublishConfiguration { //默认超时 int timeout = 3; //请求发送前调用 - Consumer beforePublishHook = null; + Consumer beforePublishHook = null; //收到请求回信后调用 - BiConsumer afterPublishHook = null; + BiConsumer afterPublishHook = null; public String getBid() { @@ -50,15 +48,15 @@ public class PublishConfiguration { this.timeout = timeout; } - public void setBeforePublishHook(Consumer callback) { + public void setBeforePublishHook(Consumer callback) { beforePublishHook = callback; } - public void setAfterPublishReplyHook(BiConsumer callback) { + public void setAfterPublishReplyHook(BiConsumer callback) { afterPublishHook = callback; } - public void invokeBeforePublishHook(CommonTopicRequest req){ + public void invokeBeforePublishHook(PublishRequest req){ if(Objects.nonNull(beforePublishHook)){ try { beforePublishHook.accept(req); @@ -69,7 +67,7 @@ public class PublishConfiguration { } } - public void invokeAfterPublishReplyHook(CommonTopicRequest req, PublishBarrierResult result){ + public void invokeAfterPublishReplyHook(PublishRequest req, PublishBarrierResult result){ if(Objects.nonNull(afterPublishHook)){ try{ afterPublishHook.accept(req,result); diff --git a/src/main/java/com/dji/sdk/common/PublishOption.java b/src/main/java/com/dji/sdk/common/PublishOption.java index 505f667..5f33e49 100644 --- a/src/main/java/com/dji/sdk/common/PublishOption.java +++ b/src/main/java/com/dji/sdk/common/PublishOption.java @@ -7,8 +7,6 @@ **************************************************/ package com.dji.sdk.common; -import com.dji.sdk.mqtt.CommonTopicRequest; -import com.dji.sdk.mqtt.CommonTopicResponse; import com.google.common.base.Strings; import java.util.Objects; @@ -44,13 +42,13 @@ public class PublishOption { return this; } - public PublishOption beforePublish(Consumer callback){ + public PublishOption beforePublish(Consumer callback){ if(Objects.nonNull(callback)){ configuration.setBeforePublishHook(callback); } return this; } - public PublishOption afterPublishReply(BiConsumer callback){ + public PublishOption afterPublishReply(BiConsumer callback){ if(Objects.nonNull(callback)){ configuration.setAfterPublishReplyHook(callback); } diff --git a/src/main/java/com/dji/sdk/common/PublishRequest.java b/src/main/java/com/dji/sdk/common/PublishRequest.java new file mode 100644 index 0000000..81c8674 --- /dev/null +++ b/src/main/java/com/dji/sdk/common/PublishRequest.java @@ -0,0 +1,20 @@ +/************************************************* + * @copyright 2017 Flision Corporation Inc. + * @author: Vincent Chan @ Canton + * @date: 2023年09月25日 + * @version: 1.0.0 + * @description: + **************************************************/ +package com.dji.sdk.common; + +import com.dji.sdk.common.ReadonlyPublishConfiguration; +import com.dji.sdk.mqtt.CommonTopicRequest; + +public interface PublishRequest { + + String getTopic(); + + CommonTopicRequest getOriginRequest(); + + ReadonlyPublishConfiguration getConfiguration(); +} diff --git a/src/main/java/com/dji/sdk/common/PublishResult.java b/src/main/java/com/dji/sdk/common/PublishResult.java new file mode 100644 index 0000000..8b23693 --- /dev/null +++ b/src/main/java/com/dji/sdk/common/PublishResult.java @@ -0,0 +1,17 @@ +/************************************************* + * @copyright 2017 Flision Corporation Inc. + * @author: Vincent Chan @ Canton + * @date: 2023年09月25日 + * @version: 1.0.0 + * @description: + **************************************************/ +package com.dji.sdk.common; + +import com.dji.sdk.mqtt.CommonTopicResponse; + +public interface PublishResult { + + boolean isTimeout(); + + CommonTopicResponse getData(); +} diff --git a/src/main/java/com/dji/sdk/common/ReadonlyPublishConfiguration.java b/src/main/java/com/dji/sdk/common/ReadonlyPublishConfiguration.java new file mode 100644 index 0000000..ff4e880 --- /dev/null +++ b/src/main/java/com/dji/sdk/common/ReadonlyPublishConfiguration.java @@ -0,0 +1,17 @@ +/************************************************* + * @copyright 2017 Flision Corporation Inc. + * @author: Vincent Chan @ Canton + * @date: 2023年09月25日 + * @version: 1.0.0 + * @description: + **************************************************/ +package com.dji.sdk.common; + +public interface ReadonlyPublishConfiguration { + + String getBid(); + + String getTid(); + + long getTimeout(); +} diff --git a/src/main/java/com/dji/sdk/config/DefaultBeanConfiguration.java b/src/main/java/com/dji/sdk/config/DefaultBeanConfiguration.java index 80c40d1..9829b4a 100644 --- a/src/main/java/com/dji/sdk/config/DefaultBeanConfiguration.java +++ b/src/main/java/com/dji/sdk/config/DefaultBeanConfiguration.java @@ -9,8 +9,8 @@ package com.dji.sdk.config; import com.dji.sdk.common.*; import com.dji.sdk.mqtt.ChanBarrierAdapter; -import com.dji.sdk.mqtt.CommonTopicRequest; import com.dji.sdk.mqtt.GlobalPublishOption; +import com.dji.sdk.common.PublishRequest; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -42,12 +42,12 @@ public class DefaultBeanConfiguration { } @Override - public Consumer defaultBeforePublishHook() { + public Consumer defaultBeforePublishHook() { return null; } @Override - public BiConsumer defaultAfterPublishHook() { + public BiConsumer defaultAfterPublishHook() { return null; } }; diff --git a/src/main/java/com/dji/sdk/mqtt/GlobalPublishOption.java b/src/main/java/com/dji/sdk/mqtt/GlobalPublishOption.java index 88f797a..50872ca 100644 --- a/src/main/java/com/dji/sdk/mqtt/GlobalPublishOption.java +++ b/src/main/java/com/dji/sdk/mqtt/GlobalPublishOption.java @@ -8,6 +8,7 @@ package com.dji.sdk.mqtt; import com.dji.sdk.common.PublishBarrierResult; +import com.dji.sdk.common.PublishRequest; import java.util.function.BiConsumer; import java.util.function.Consumer; @@ -17,7 +18,7 @@ public interface GlobalPublishOption { Supplier defaultTransactionId(); Supplier defaultBizId(); - Consumer defaultBeforePublishHook(); - BiConsumer defaultAfterPublishHook(); + Consumer defaultBeforePublishHook(); + BiConsumer defaultAfterPublishHook(); } diff --git a/src/main/java/com/dji/sdk/mqtt/MqttGatewayPublish.java b/src/main/java/com/dji/sdk/mqtt/MqttGatewayPublish.java index ceeaf97..f25155c 100644 --- a/src/main/java/com/dji/sdk/mqtt/MqttGatewayPublish.java +++ b/src/main/java/com/dji/sdk/mqtt/MqttGatewayPublish.java @@ -16,7 +16,6 @@ import javax.annotation.Resource; import java.util.Objects; import java.util.UUID; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; @@ -119,7 +118,9 @@ public class MqttGatewayPublish { request.setTid(config.getTid()); //use to log request data or the last chance to change some data - config.invokeBeforePublishHook(request); + //CommonTopicRequest丢失了一些需要记录的内容,把这些内容封到PublishRequest交出去 + PublishRequest wrapRequest = new CommonTopicRequestWrapper(clazz,topic, request, config); + config.invokeBeforePublishHook(wrapRequest); //注册barrier String identity = publishBarrier.generateIdentity(request); //提供栅栏标识 @@ -130,7 +131,7 @@ public class MqttGatewayPublish { if(log.isDebugEnabled()){ log.debug("等待{}指令返回",identity); }; PublishBarrierResult result = publishBarrier.await(identity,config.getTimeout()); - config.invokeAfterPublishReplyHook(request, result); + config.invokeAfterPublishReplyHook(wrapRequest, result); if(result.isTimeout()){ throw new CloudSDKException("Timeout"); //TODO: 换个更明确的异常更好 @@ -163,4 +164,36 @@ public class MqttGatewayPublish { } return config; } + + static class CommonTopicRequestWrapper implements PublishRequest{ + final CommonTopicRequest request; + final String topic; + final Class clazz; + + final ReadonlyPublishConfiguration config; + + public CommonTopicRequestWrapper(Class clazz, String topic,CommonTopicRequest request, PublishConfiguration config) { + this.clazz = clazz; + this.request = request; + this.topic = topic; + this.config = config; + } + + @Override + public String getTopic() { + return topic; + } + + @Override + public CommonTopicRequest getOriginRequest() { + return request; + } + + @Override + public ReadonlyPublishConfiguration getConfiguration() { + return config; + } + + + } } \ No newline at end of file From 9627b13c6fd31f261c57beac4f9f54700702f31a Mon Sep 17 00:00:00 2001 From: Vincent Date: Sun, 8 Oct 2023 15:52:34 +0800 Subject: [PATCH 10/20] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E8=AE=BE?= =?UTF-8?q?=E5=A4=87=E6=9C=AA=E6=B3=A8=E5=86=8C=E5=89=8D=E8=AE=BE=E5=A4=87?= =?UTF-8?q?=E6=8E=A8=E9=80=81state=E5=AF=BC=E8=87=B4=E4=BA=A7=E7=94=9F?= =?UTF-8?q?=E5=A4=A7=E9=87=8F=E6=97=A5=E5=BF=97=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/dji/sdk/mqtt/state/StateRouter.java | 54 ++++++++++++------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/dji/sdk/mqtt/state/StateRouter.java b/src/main/java/com/dji/sdk/mqtt/state/StateRouter.java index 30ccfbb..2dc37ed 100644 --- a/src/main/java/com/dji/sdk/mqtt/state/StateRouter.java +++ b/src/main/java/com/dji/sdk/mqtt/state/StateRouter.java @@ -7,6 +7,8 @@ import com.dji.sdk.exception.CloudSDKErrorEnum; import com.dji.sdk.exception.CloudSDKException; import com.dji.sdk.mqtt.ChannelName; import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.integration.dsl.IntegrationFlow; @@ -16,18 +18,16 @@ import org.springframework.messaging.Message; import javax.annotation.Resource; import java.io.IOException; -import java.util.Arrays; -import java.util.Map; -import java.util.Set; +import java.util.*; import static com.dji.sdk.mqtt.TopicConst.*; /** - * * @author sean.zhou - * @date 2021/11/17 * @version 0.1 + * @date 2021/11/17 */ +@Slf4j @Configuration public class StateRouter { @@ -39,31 +39,47 @@ public class StateRouter { return IntegrationFlows .from(ChannelName.INBOUND_STATE) .transform(Message.class, source -> { + ObjectMapper objectMapper = Common.getObjectMapper(); try { - TopicStateRequest response = Common.getObjectMapper().readValue((byte[]) source.getPayload(), new TypeReference() {}); + TopicStateRequest response = objectMapper.readValue((byte[]) source.getPayload(), new TypeReference() { + }); String topic = String.valueOf(source.getHeaders().get(MqttHeaders.RECEIVED_TOPIC)); String from = topic.substring((THING_MODEL_PRE + PRODUCT).length(), topic.indexOf(STATE_SUF)); - return response.setFrom(from) - .setData(Common.getObjectMapper().convertValue(response.getData(), getTypeReference(response.getGateway(), response.getData()))); - } catch (IOException e) { + //fix: 修复设备未注册前设备推送state导致产生大量日志的问题 witcom@2023.10.08 + return getTypeReference(response.getGateway(), response.getData()) + .map(clazz -> response.setFrom(from).setData(objectMapper.convertValue(response.getData(), clazz))) + .orElse(null); +// return response.setFrom(from) +// .setData(objectMapper.convertValue(response.getData(), typeReference)); + } /*catch (IOException e) { + //witcom: Which part will throw IOException??? throw new CloudSDKException(e); + }*/ catch (Exception ex) { + log.warn("[StateRouter]"+ex.getMessage()); + return null; } }, null) + .filter(Objects::nonNull) .route(response -> StateDataKeyEnum.find(response.getData().getClass()), mapping -> Arrays.stream(StateDataKeyEnum.values()).forEach(key -> mapping.channelMapping(key, key.getChannelName()))) .get(); } - private Class getTypeReference(String gatewaySn, Object data) { + private Optional getTypeReference(String gatewaySn, Object data) { Set keys = ((Map) data).keySet(); - GatewayTypeEnum type = sdkManager.getDeviceSDK(gatewaySn).getType(); - switch (type) { - case RC: - return RcStateDataKeyEnum.find(keys).getClassType(); - case DOCK: - return DockStateDataKeyEnum.find(keys).getClassType(); - default: - throw new CloudSDKException(CloudSDKErrorEnum.WRONG_DATA, "Unexpected value: " + type); - } + //fix: 捕捉数据流发现在注册前设备可能会推送state主题导致产生大量日志 witcom@2023.10.08 + //GatewayTypeEnum type = sdkManager.getDeviceSDK(gatewaySn).getType(); + return sdkManager.findDeviceSDK(gatewaySn) + .map(gw -> { + GatewayTypeEnum type = gw.getType(); + switch (type) { + case RC: + return RcStateDataKeyEnum.find(keys).getClassType(); + case DOCK: + return DockStateDataKeyEnum.find(keys).getClassType(); + default: + throw new CloudSDKException(CloudSDKErrorEnum.WRONG_DATA, "Unexpected value: " + type); + } + }); } } \ No newline at end of file From 89c34336e7ff017188867b3426c6e56799a97647 Mon Sep 17 00:00:00 2001 From: Vincent Date: Mon, 9 Oct 2023 16:01:31 +0800 Subject: [PATCH 11/20] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8Dflow.transform?= =?UTF-8?q?=E4=B8=8D=E8=83=BD=E8=BF=94=E5=9B=9Enull=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=E4=BA=A7=E7=94=9F=E5=A4=A7=E9=87=8F=E6=97=A5=E5=BF=97=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dji/sdk/mqtt/FlowTransformWrapper.java | 51 +++++++++++++++++++ .../com/dji/sdk/mqtt/state/StateRouter.java | 34 ++++++++----- 2 files changed, 73 insertions(+), 12 deletions(-) create mode 100644 src/main/java/com/dji/sdk/mqtt/FlowTransformWrapper.java diff --git a/src/main/java/com/dji/sdk/mqtt/FlowTransformWrapper.java b/src/main/java/com/dji/sdk/mqtt/FlowTransformWrapper.java new file mode 100644 index 0000000..b0c87a8 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/FlowTransformWrapper.java @@ -0,0 +1,51 @@ +/************************************************* + * @copyright 2017 Flision Corporation Inc. + * @author: Vincent Chan @ Canton + * @date: 2023年10月09日 + * @version: 1.0.0 + * @description: + **************************************************/ +package com.dji.sdk.mqtt; + +public class FlowTransformWrapper { + + public final static String DEFAULT_ERROR_MSG = "null"; + + public static FlowTransformWrapper error(){ + return new FlowTransformWrapper(DEFAULT_ERROR_MSG); + } + + public static FlowTransformWrapper ok(CommonTopicRequest request){ + return new FlowTransformWrapper(request); + } + + CommonTopicRequest request; + boolean bError; + String errorMessage; + + private FlowTransformWrapper(CommonTopicRequest request){ + this.request = request; + this.bError = false; + } + + private FlowTransformWrapper(String errorMessage){ + this.bError = true; + this.errorMessage = errorMessage; + } + + public CommonTopicRequest getRequest() { + return request; + } + + public boolean hasError() { + return bError; + } + + public boolean continuee(){ + return !hasError(); + } + + public String getErrorMessage() { + return errorMessage; + } +} diff --git a/src/main/java/com/dji/sdk/mqtt/state/StateRouter.java b/src/main/java/com/dji/sdk/mqtt/state/StateRouter.java index 2dc37ed..dbc1440 100644 --- a/src/main/java/com/dji/sdk/mqtt/state/StateRouter.java +++ b/src/main/java/com/dji/sdk/mqtt/state/StateRouter.java @@ -6,6 +6,7 @@ import com.dji.sdk.common.SDKManager; import com.dji.sdk.exception.CloudSDKErrorEnum; import com.dji.sdk.exception.CloudSDKException; import com.dji.sdk.mqtt.ChannelName; +import com.dji.sdk.mqtt.FlowTransformWrapper; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; @@ -36,29 +37,38 @@ public class StateRouter { @Bean public IntegrationFlow stateDataRouterFlow() { + ObjectMapper objectMapper = Common.getObjectMapper(); return IntegrationFlows .from(ChannelName.INBOUND_STATE) .transform(Message.class, source -> { - ObjectMapper objectMapper = Common.getObjectMapper(); try { - TopicStateRequest response = objectMapper.readValue((byte[]) source.getPayload(), new TypeReference() { - }); + TopicStateRequest response = objectMapper.readValue( + (byte[]) source.getPayload(), + new TypeReference() {}); String topic = String.valueOf(source.getHeaders().get(MqttHeaders.RECEIVED_TOPIC)); String from = topic.substring((THING_MODEL_PRE + PRODUCT).length(), topic.indexOf(STATE_SUF)); - //fix: 修复设备未注册前设备推送state导致产生大量日志的问题 witcom@2023.10.08 + + return FlowTransformWrapper.ok(response.setFrom(from)); + } catch (Exception ex) { + log.warn("[StateRouter]"+ex.getMessage()); + return FlowTransformWrapper.error(); + } + }, null) + .filter(FlowTransformWrapper::continuee) + .handle((wrapper, headers) -> { + + TopicStateRequest response = (TopicStateRequest)wrapper.getRequest(); + + //fix: 修复设备未注册前设备推送state导致产生大量日志的问题 witcom@2023.10.08 + try { return getTypeReference(response.getGateway(), response.getData()) - .map(clazz -> response.setFrom(from).setData(objectMapper.convertValue(response.getData(), clazz))) + .map(clazz -> response.setData(objectMapper.convertValue(response.getData(), clazz))) .orElse(null); -// return response.setFrom(from) -// .setData(objectMapper.convertValue(response.getData(), typeReference)); - } /*catch (IOException e) { - //witcom: Which part will throw IOException??? - throw new CloudSDKException(e); - }*/ catch (Exception ex) { + }catch (CloudSDKException ex){ log.warn("[StateRouter]"+ex.getMessage()); return null; } - }, null) + }) .filter(Objects::nonNull) .route(response -> StateDataKeyEnum.find(response.getData().getClass()), mapping -> Arrays.stream(StateDataKeyEnum.values()).forEach(key -> mapping.channelMapping(key, key.getChannelName()))) From 9d9d0cf21b285fa2790fb414d78a63c1a3baeab6 Mon Sep 17 00:00:00 2001 From: Vincent Date: Mon, 9 Oct 2023 16:46:21 +0800 Subject: [PATCH 12/20] =?UTF-8?q?feat:=20PropertySetPublish=20=E6=96=B0?= =?UTF-8?q?=E5=A2=9ECompletableFuture=E6=94=AF=E6=8C=81=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sdk/mqtt/property/PropertySetPublish.java | 34 ++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/dji/sdk/mqtt/property/PropertySetPublish.java b/src/main/java/com/dji/sdk/mqtt/property/PropertySetPublish.java index 3426a85..2927c8b 100644 --- a/src/main/java/com/dji/sdk/mqtt/property/PropertySetPublish.java +++ b/src/main/java/com/dji/sdk/mqtt/property/PropertySetPublish.java @@ -1,5 +1,8 @@ package com.dji.sdk.mqtt.property; +import com.dji.sdk.common.PublishOption; +import com.dji.sdk.mqtt.CommonTopicRequest; +import com.dji.sdk.mqtt.CommonTopicResponse; import com.dji.sdk.mqtt.MqttGatewayPublish; import com.dji.sdk.mqtt.TopicConst; import org.springframework.stereotype.Component; @@ -7,6 +10,8 @@ import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.util.Objects; import java.util.UUID; +import java.util.concurrent.CompletableFuture; +import java.util.function.Consumer; /** * @author sean @@ -29,12 +34,33 @@ public class PropertySetPublish { public PropertySetReplyResultEnum publish(String sn, Object data, int retryCount, long timeout) { String topic = TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + Objects.requireNonNull(sn) + TopicConst.PROPERTY_SUF + TopicConst.SET_SUF; + + return gatewayPublish.publishWithReply(PropertySetReplyResultEnum.class,topic, + new CommonTopicRequest<>() + .setTimestamp(System.currentTimeMillis()) + .setData(Objects.requireNonNull(data)), + ops->ops.timeout((int)(timeout/1000))) + .join() + .getData(); + +// return gatewayPublish.publishWithReply( +// PropertySetReplyResultEnum.class, topic, new TopicPropertySetRequest<>() +// .setTid(UUID.randomUUID().toString()) +// .setBid(null) +// .setTimestamp(System.currentTimeMillis()) +// .setData(Objects.requireNonNull(data)), retryCount, timeout).getData(); + } + + public CompletableFuture> + publish(String sn, Object data, Consumer options){ + String topic = TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + Objects.requireNonNull(sn) + TopicConst.PROPERTY_SUF + TopicConst.SET_SUF; return gatewayPublish.publishWithReply( - PropertySetReplyResultEnum.class, topic, new TopicPropertySetRequest<>() - .setTid(UUID.randomUUID().toString()) - .setBid(null) + PropertySetReplyResultEnum.class, + topic, + new CommonTopicRequest<>() .setTimestamp(System.currentTimeMillis()) - .setData(Objects.requireNonNull(data)), retryCount, timeout).getData(); + .setData(Objects.requireNonNull(data)), + options); } } From 4f38be09258fd725d6e2a016d40de435c938ca0a Mon Sep 17 00:00:00 2001 From: Vincent Date: Mon, 9 Oct 2023 17:34:40 +0800 Subject: [PATCH 13/20] =?UTF-8?q?fix:=20=E5=8F=96=E6=B6=88FlyToPoint,=20Ta?= =?UTF-8?q?keoffToPoint=20flightId=E8=A7=84=E5=88=99=E9=99=90=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/dji/sdk/cloudapi/control/FlyToPointRequest.java | 2 +- .../com/dji/sdk/cloudapi/control/TakeoffToPointRequest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/dji/sdk/cloudapi/control/FlyToPointRequest.java b/src/main/java/com/dji/sdk/cloudapi/control/FlyToPointRequest.java index 8af4ca9..297d8a9 100644 --- a/src/main/java/com/dji/sdk/cloudapi/control/FlyToPointRequest.java +++ b/src/main/java/com/dji/sdk/cloudapi/control/FlyToPointRequest.java @@ -13,7 +13,7 @@ import java.util.List; */ public class FlyToPointRequest extends BaseModel { - @Pattern(regexp = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") + //@Pattern(regexp = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") @NotNull private String flyToId; diff --git a/src/main/java/com/dji/sdk/cloudapi/control/TakeoffToPointRequest.java b/src/main/java/com/dji/sdk/cloudapi/control/TakeoffToPointRequest.java index 2c5424e..823a83f 100644 --- a/src/main/java/com/dji/sdk/cloudapi/control/TakeoffToPointRequest.java +++ b/src/main/java/com/dji/sdk/cloudapi/control/TakeoffToPointRequest.java @@ -19,7 +19,7 @@ import javax.validation.constraints.Pattern; */ public class TakeoffToPointRequest extends BaseModel { - @Pattern(regexp = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") + //@Pattern(regexp = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") @NotNull private String flightId; From 37533747057091346d43b17f92717586f77f5583 Mon Sep 17 00:00:00 2001 From: Vincent Date: Thu, 12 Oct 2023 15:37:32 +0800 Subject: [PATCH 14/20] =?UTF-8?q?fix:=20=E7=AE=80=E5=8C=96SDKManager?= =?UTF-8?q?=E6=89=80=E9=9C=80=E5=AE=9E=E7=8E=B0=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/dji/sdk/common/SDKManager.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/dji/sdk/common/SDKManager.java b/src/main/java/com/dji/sdk/common/SDKManager.java index 61b4b3f..f67fc7d 100644 --- a/src/main/java/com/dji/sdk/common/SDKManager.java +++ b/src/main/java/com/dji/sdk/common/SDKManager.java @@ -20,13 +20,21 @@ import java.util.concurrent.ConcurrentHashMap; */ public interface SDKManager { - GatewayManager getDeviceSDK(String gatewaySn); + default GatewayManager getDeviceSDK(String gatewaySn){ + return findDeviceSDK(gatewaySn) + .orElseThrow(()-> new CloudSDKException(CloudSDKErrorEnum.NOT_REGISTERED, + "The device has not been registered, please call the 'SDKManager.registerDevice()' method to register the device first.")); + } Optional findDeviceSDK(String gatewaySn); - GatewayManager registerDevice(String gatewaySn, String droneSn, - DeviceDomainEnum domain, DeviceTypeEnum type, DeviceSubTypeEnum subType, String gatewayThingVersion, String droneThingVersion); + default GatewayManager registerDevice(String gatewaySn, String droneSn, + DeviceDomainEnum domain, DeviceTypeEnum type, DeviceSubTypeEnum subType, String gatewayThingVersion, String droneThingVersion){ + return registerDevice(gatewaySn, droneSn, GatewayTypeEnum.find(DeviceEnum.find(domain, type, subType)), gatewayThingVersion, droneThingVersion); + } - GatewayManager registerDevice(String gatewaySn, String droneSn, GatewayTypeEnum type, String gatewayThingVersion, String droneThingVersion); + default GatewayManager registerDevice(String gatewaySn, String droneSn, GatewayTypeEnum type, String gatewayThingVersion, String droneThingVersion){ + return registerDevice(new GatewayManager(Objects.requireNonNull(gatewaySn), droneSn, type, gatewayThingVersion, droneThingVersion)); + } GatewayManager registerDevice(GatewayManager gateway); From 07b0fd39b77505e51e94562688a6f87b19def8e9 Mon Sep 17 00:00:00 2001 From: Vincent Date: Mon, 30 Oct 2023 14:26:43 +0800 Subject: [PATCH 15/20] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E4=B8=80?= =?UTF-8?q?=E4=BA=9Bnpe=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dji/sdk/cloudapi/device/DockLiveErrorStatus.java | 3 +++ .../dji/sdk/cloudapi/device/DroneModeCodeEnum.java | 5 ++++- .../cloudapi/device/api/AbstractDeviceService.java | 4 +++- .../dji/sdk/cloudapi/wayline/ExecutionStepEnum.java | 11 ++++++----- .../com/dji/sdk/mqtt/state/DockStateDataKeyEnum.java | 8 +++++--- .../com/dji/sdk/mqtt/state/RcStateDataKeyEnum.java | 7 ++++--- src/main/java/com/dji/sdk/mqtt/state/StateRouter.java | 6 +++--- 7 files changed, 28 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/dji/sdk/cloudapi/device/DockLiveErrorStatus.java b/src/main/java/com/dji/sdk/cloudapi/device/DockLiveErrorStatus.java index aa67276..1d1b0a2 100644 --- a/src/main/java/com/dji/sdk/cloudapi/device/DockLiveErrorStatus.java +++ b/src/main/java/com/dji/sdk/cloudapi/device/DockLiveErrorStatus.java @@ -40,11 +40,14 @@ public class DockLiveErrorStatus { } public String getMessage() { + if(success){ return "success";} return errorCode.getMessage(); } @JsonValue public Integer getCode() { + //witcom: errorCode.getCode() will cause npe 2023.10.30 + if(success){ return 0; } return source.getSource() * MOD + errorCode.getCode(); } diff --git a/src/main/java/com/dji/sdk/cloudapi/device/DroneModeCodeEnum.java b/src/main/java/com/dji/sdk/cloudapi/device/DroneModeCodeEnum.java index 526460b..fba4165 100644 --- a/src/main/java/com/dji/sdk/cloudapi/device/DroneModeCodeEnum.java +++ b/src/main/java/com/dji/sdk/cloudapi/device/DroneModeCodeEnum.java @@ -45,7 +45,10 @@ public enum DroneModeCodeEnum { APAS(15), - VIRTUAL_JOYSTICK(16); + VIRTUAL_JOYSTICK(16), + + //witcom: 飞机报这个号上来报异常 + UNKNOWN_1(17); private final int code; diff --git a/src/main/java/com/dji/sdk/cloudapi/device/api/AbstractDeviceService.java b/src/main/java/com/dji/sdk/cloudapi/device/api/AbstractDeviceService.java index b8b5352..5b3c7e3 100644 --- a/src/main/java/com/dji/sdk/cloudapi/device/api/AbstractDeviceService.java +++ b/src/main/java/com/dji/sdk/cloudapi/device/api/AbstractDeviceService.java @@ -169,7 +169,9 @@ public class AbstractDeviceService { * @param request data * @param headers The headers for a {@link Message}. */ - @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_DOCK_WPMZ_VERSION) + //witcom: wrong ChannelName. is INBOUND_STATE_DOCK_PAYLOAD?? +// @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_DOCK_WPMZ_VERSION) + @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_DOCK_PAYLOAD) public void dockPayload(TopicStateRequest request, MessageHeaders headers) { throw new UnsupportedOperationException("dockPayload not implemented"); } diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/ExecutionStepEnum.java b/src/main/java/com/dji/sdk/cloudapi/wayline/ExecutionStepEnum.java index f142ce6..8a4e287 100644 --- a/src/main/java/com/dji/sdk/cloudapi/wayline/ExecutionStepEnum.java +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/ExecutionStepEnum.java @@ -52,15 +52,16 @@ public enum ExecutionStepEnum { return msg; } + //witcom: 这个函数跑不进来,跑了下面的函数,导致FlightTaskProgress报不上来 @JsonCreator public static ExecutionStepEnum find(int step) { return Arrays.stream(values()).filter(stepEnum -> stepEnum.min <= step && stepEnum.max >= step).findAny() .orElseThrow(() -> new CloudSDKException(ExecutionStepEnum.class, step)); } - @JsonCreator - public static ExecutionStepEnum find(String msg) { - return Arrays.stream(values()).filter(stepEnum -> stepEnum.msg.equals(msg)).findAny() - .orElseThrow(() -> new CloudSDKException(ExecutionStepEnum.class, msg)); - } +// @JsonCreator +// public static ExecutionStepEnum find(String msg) { +// return Arrays.stream(values()).filter(stepEnum -> stepEnum.msg.equals(msg)).findAny() +// .orElseThrow(() -> new CloudSDKException(ExecutionStepEnum.class, msg)); +// } } diff --git a/src/main/java/com/dji/sdk/mqtt/state/DockStateDataKeyEnum.java b/src/main/java/com/dji/sdk/mqtt/state/DockStateDataKeyEnum.java index f657eb0..f19879a 100644 --- a/src/main/java/com/dji/sdk/mqtt/state/DockStateDataKeyEnum.java +++ b/src/main/java/com/dji/sdk/mqtt/state/DockStateDataKeyEnum.java @@ -6,6 +6,7 @@ import com.dji.sdk.exception.CloudSDKException; import java.util.Arrays; import java.util.Collections; +import java.util.Optional; import java.util.Set; /** @@ -47,9 +48,10 @@ public enum DockStateDataKeyEnum { return keys; } - public static DockStateDataKeyEnum find(Set keys) { - return Arrays.stream(values()).filter(keyEnum -> !Collections.disjoint(keys, keyEnum.keys)).findAny() - .orElseThrow(() -> new CloudSDKException(DockStateDataKeyEnum.class, keys)); + public static Optional find(Set keys) { + // com.dji.sdk.mqtt.state.DockStateDataKeyEnum has unknown data: [[mode_code_reason]] + return Arrays.stream(values()).filter(keyEnum -> !Collections.disjoint(keys, keyEnum.keys)).findAny(); + // .orElseThrow(() -> new CloudSDKException(DockStateDataKeyEnum.class, keys)); } } diff --git a/src/main/java/com/dji/sdk/mqtt/state/RcStateDataKeyEnum.java b/src/main/java/com/dji/sdk/mqtt/state/RcStateDataKeyEnum.java index b0dfb1d..9b31ed2 100644 --- a/src/main/java/com/dji/sdk/mqtt/state/RcStateDataKeyEnum.java +++ b/src/main/java/com/dji/sdk/mqtt/state/RcStateDataKeyEnum.java @@ -6,6 +6,7 @@ import com.dji.sdk.exception.CloudSDKException; import java.util.Arrays; import java.util.Collections; +import java.util.Optional; import java.util.Set; /** @@ -45,9 +46,9 @@ public enum RcStateDataKeyEnum { return keys; } - public static RcStateDataKeyEnum find(Set keys) { - return Arrays.stream(values()).filter(keyEnum -> !Collections.disjoint(keys, keyEnum.keys)).findAny() - .orElseThrow(() -> new CloudSDKException(RcStateDataKeyEnum.class, keys)); + public static Optional find(Set keys) { + return Arrays.stream(values()).filter(keyEnum -> !Collections.disjoint(keys, keyEnum.keys)).findAny(); + //.orElseThrow(() -> new CloudSDKException(RcStateDataKeyEnum.class, keys)); } } diff --git a/src/main/java/com/dji/sdk/mqtt/state/StateRouter.java b/src/main/java/com/dji/sdk/mqtt/state/StateRouter.java index dbc1440..7ba7886 100644 --- a/src/main/java/com/dji/sdk/mqtt/state/StateRouter.java +++ b/src/main/java/com/dji/sdk/mqtt/state/StateRouter.java @@ -80,13 +80,13 @@ public class StateRouter { //fix: 捕捉数据流发现在注册前设备可能会推送state主题导致产生大量日志 witcom@2023.10.08 //GatewayTypeEnum type = sdkManager.getDeviceSDK(gatewaySn).getType(); return sdkManager.findDeviceSDK(gatewaySn) - .map(gw -> { + .flatMap(gw -> { GatewayTypeEnum type = gw.getType(); switch (type) { case RC: - return RcStateDataKeyEnum.find(keys).getClassType(); + return RcStateDataKeyEnum.find(keys).map(v->v.getClassType()); case DOCK: - return DockStateDataKeyEnum.find(keys).getClassType(); + return DockStateDataKeyEnum.find(keys).map(v->v.getClassType()); default: throw new CloudSDKException(CloudSDKErrorEnum.WRONG_DATA, "Unexpected value: " + type); } From c5e09610f92f5ed0ddda6f5d61b9c5d83aecd9f0 Mon Sep 17 00:00:00 2001 From: Vincent Date: Tue, 31 Oct 2023 13:21:08 +0800 Subject: [PATCH 16/20] =?UTF-8?q?fix:=20RemoteDebugSteoKeyEnum=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0Unknown=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/dji/sdk/cloudapi/debug/RemoteDebugStepKeyEnum.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/dji/sdk/cloudapi/debug/RemoteDebugStepKeyEnum.java b/src/main/java/com/dji/sdk/cloudapi/debug/RemoteDebugStepKeyEnum.java index ddeca50..60f99b6 100644 --- a/src/main/java/com/dji/sdk/cloudapi/debug/RemoteDebugStepKeyEnum.java +++ b/src/main/java/com/dji/sdk/cloudapi/debug/RemoteDebugStepKeyEnum.java @@ -59,7 +59,9 @@ public enum RemoteDebugStepKeyEnum { FREE_PUTTER("free_putter", "Free Putter"), - STOP_CHARGE("stop_charge", "Stop charging"); + STOP_CHARGE("stop_charge", "Stop charging"), + + UNKNOWN("unknown","Unknown"); private final String stepKey; @@ -79,10 +81,11 @@ public enum RemoteDebugStepKeyEnum { return message; } + //fix: 提供unknown取代异常 witcom@2023.10.30 @JsonCreator public static RemoteDebugStepKeyEnum find(String stepKey) { return Arrays.stream(values()).filter(stepKeyEnum -> stepKeyEnum.stepKey.equals(stepKey)).findAny() - .orElseThrow(() -> new CloudSDKException(RemoteDebugStepKeyEnum.class,stepKey)); + .orElse(UNKNOWN); } } From 6f2fd1e5c620a1d252fe6f7a6c5f1b0b3755c592 Mon Sep 17 00:00:00 2001 From: Vincent Date: Thu, 9 Nov 2023 15:47:00 +0800 Subject: [PATCH 17/20] fix: mark an bug --- .../com/dji/sdk/cloudapi/wayline/FlighttaskBreakPoint.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskBreakPoint.java b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskBreakPoint.java index 6d0c232..fb8ee1e 100755 --- a/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskBreakPoint.java +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskBreakPoint.java @@ -26,10 +26,11 @@ public class FlighttaskBreakPoint { /** * Current wayline segment process + * bug: Cannot deserialize value of type `com.dji.sdk.cloudapi.wayline.FlighttaskBreakReasonEnum` from number 1281: index value outside legal index range [0..-1] mark by witcom 2023.11.09 */ - @NotNull - @Min(0) - @Max(1) +// @NotNull +// @Min(0) +// @Max(1) private Float progress; /** From 17725883849a3aaa9e8a168732abb86eddc425d0 Mon Sep 17 00:00:00 2001 From: Vincent Date: Fri, 8 Dec 2023 09:53:18 +0800 Subject: [PATCH 18/20] fix: Cannot construct instance of `com.dji.sdk.cloudapi.device.CameraModeEnum` --- src/main/java/com/dji/sdk/cloudapi/device/CameraModeEnum.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/dji/sdk/cloudapi/device/CameraModeEnum.java b/src/main/java/com/dji/sdk/cloudapi/device/CameraModeEnum.java index 3f82d43..750279b 100644 --- a/src/main/java/com/dji/sdk/cloudapi/device/CameraModeEnum.java +++ b/src/main/java/com/dji/sdk/cloudapi/device/CameraModeEnum.java @@ -13,6 +13,8 @@ import java.util.Arrays; */ public enum CameraModeEnum { + //fix: Cannot construct instance of `com.dji.sdk.cloudapi.device.CameraModeEnum`, problem: com.dji.sdk.cloudapi.device.CameraModeEnum has unknown data: [-1] vincent @ 2023.12.07 + UNKNOWN(-1), PHOTO(0), VIDEO(1); From 9efb6d8a3a5d338ed4bd1344bd6ed051cabb044c Mon Sep 17 00:00:00 2001 From: Vincent Date: Fri, 8 Dec 2023 16:48:35 +0800 Subject: [PATCH 19/20] fix: * bug: Cannot deserialize value of type `com.dji.sdk.cloudapi.wayline.FlighttaskBreakReasonEnum` from number 1281: index value outside legal index range [0..-1] --- .../cloudapi/wayline/FlighttaskBreakPoint.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskBreakPoint.java b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskBreakPoint.java index fb8ee1e..45f50fe 100755 --- a/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskBreakPoint.java +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskBreakPoint.java @@ -24,10 +24,7 @@ public class FlighttaskBreakPoint { @NotNull private BreakpointStateEnum state; - /** - * Current wayline segment process - * bug: Cannot deserialize value of type `com.dji.sdk.cloudapi.wayline.FlighttaskBreakReasonEnum` from number 1281: index value outside legal index range [0..-1] mark by witcom 2023.11.09 - */ + // @NotNull // @Min(0) // @Max(1) @@ -38,10 +35,14 @@ public class FlighttaskBreakPoint { */ private Integer waylineID; + /** + * Current wayline segment process + * bug: Cannot deserialize value of type `com.dji.sdk.cloudapi.wayline.FlighttaskBreakReasonEnum` from number 1281: index value outside legal index range [0..-1] mark by witcom 2023.11.09 + */ /** * Break reason */ - private FlighttaskBreakReasonEnum breakReason; + private Integer breakReason; /** * Breakpoint latitude @@ -117,11 +118,11 @@ public class FlighttaskBreakPoint { return this; } - public FlighttaskBreakReasonEnum getBreakReason() { + public Integer getBreakReason() { return breakReason; } - public FlighttaskBreakPoint setBreakReason(FlighttaskBreakReasonEnum breakReason) { + public FlighttaskBreakPoint setBreakReason(Integer breakReason) { this.breakReason = breakReason; return this; } From 5c8030732ac0cc55d6314d40710e857862c2fe38 Mon Sep 17 00:00:00 2001 From: Vincent Date: Fri, 8 Dec 2023 17:56:39 +0800 Subject: [PATCH 20/20] bug report: some AliOss object need to close manually. otherwise will hang up main thread to wait available connection. --- .../sample/component/oss/service/impl/AliyunOssServiceImpl.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/dji/sample/component/oss/service/impl/AliyunOssServiceImpl.java b/src/main/java/com/dji/sample/component/oss/service/impl/AliyunOssServiceImpl.java index cf78637..a55cb85 100644 --- a/src/main/java/com/dji/sample/component/oss/service/impl/AliyunOssServiceImpl.java +++ b/src/main/java/com/dji/sample/component/oss/service/impl/AliyunOssServiceImpl.java @@ -86,6 +86,7 @@ public class AliyunOssServiceImpl implements IOssService { @Override public InputStream getObject(String bucket, String objectKey) { + //bug: ossClient.getObject -> OSSObject need to close manually. otherwise will hang up main thread to wait available connection. by witcom @2023.12.08 return ossClient.getObject(bucket, objectKey).getObjectContent(); } @@ -94,6 +95,7 @@ public class AliyunOssServiceImpl implements IOssService { if (ossClient.doesObjectExist(bucket, objectKey)) { throw new RuntimeException("The filename already exists."); } + //bug: PutObjectResult need to close manually. otherwise will hang up main thread to wait available connection. by witcom @2023.12.08 PutObjectResult objectResult = ossClient.putObject(new PutObjectRequest(bucket, objectKey, input, new ObjectMetadata())); log.info("Upload FlighttaskCreateFile: {}", objectResult.getETag()); }