sean.zhou
3 years ago
173 changed files with 6123 additions and 998 deletions
@ -0,0 +1,38 @@ |
|||||||
|
package com.dji.sample.common.error; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 1.0 |
||||||
|
* @date 2022/5/25 |
||||||
|
*/ |
||||||
|
public enum StorageErrorEnum implements IErrorInfo { |
||||||
|
|
||||||
|
GENERATE_CREDENTIALS_ERROR(217001, "Failed to generate temporary credentials."), |
||||||
|
|
||||||
|
NO_BUCKET(217002, "The bucket does not exist."), |
||||||
|
|
||||||
|
ILLEGAL_PATH_FORMAT(217006, "Illegal path format."), |
||||||
|
|
||||||
|
FILE_CREATION_FAILED(217007, "File creation failed."), |
||||||
|
|
||||||
|
DIR_CREATION_FAILED(217008, "Directory creation failed"); |
||||||
|
|
||||||
|
private String msg; |
||||||
|
|
||||||
|
private int code; |
||||||
|
|
||||||
|
StorageErrorEnum(int code, String msg) { |
||||||
|
this.msg = msg; |
||||||
|
this.code = code; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getErrorMsg() { |
||||||
|
return msg; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Integer getErrorCode() { |
||||||
|
return code; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,39 @@ |
|||||||
|
package com.dji.sample.component.mqtt.handler; |
||||||
|
|
||||||
|
import com.dji.sample.component.mqtt.model.CommonTopicReceiver; |
||||||
|
import com.dji.sample.component.redis.RedisOpsUtils; |
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException; |
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
|
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 0.3 |
||||||
|
* @date 2022/2/21 |
||||||
|
*/ |
||||||
|
public abstract class AbstractStateTopicHandler { |
||||||
|
|
||||||
|
protected AbstractStateTopicHandler handler; |
||||||
|
|
||||||
|
@Autowired |
||||||
|
protected ObjectMapper mapper; |
||||||
|
|
||||||
|
@Autowired |
||||||
|
protected RedisOpsUtils redisOps; |
||||||
|
|
||||||
|
protected AbstractStateTopicHandler(AbstractStateTopicHandler handler) { |
||||||
|
this.handler = handler; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Passing dataNode data, using different processing methods depending on the data selection. |
||||||
|
* @param dataNode |
||||||
|
* @param stateReceiver |
||||||
|
* @param sn |
||||||
|
* @return |
||||||
|
* @throws JsonProcessingException |
||||||
|
*/ |
||||||
|
public abstract CommonTopicReceiver handleState(Map<String, Object> dataNode, CommonTopicReceiver stateReceiver, String sn) throws JsonProcessingException; |
||||||
|
} |
@ -0,0 +1,48 @@ |
|||||||
|
package com.dji.sample.component.mqtt.handler; |
||||||
|
|
||||||
|
import com.dji.sample.component.mqtt.model.ChannelName; |
||||||
|
import com.dji.sample.component.mqtt.model.CommonTopicReceiver; |
||||||
|
import com.dji.sample.component.mqtt.model.EventsMethodEnum; |
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.context.annotation.Bean; |
||||||
|
import org.springframework.context.annotation.Configuration; |
||||||
|
import org.springframework.integration.dsl.IntegrationFlow; |
||||||
|
import org.springframework.integration.dsl.IntegrationFlows; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 1.1 |
||||||
|
* @date 2022/6/1 |
||||||
|
*/ |
||||||
|
@Configuration |
||||||
|
public class EventsRouter { |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private ObjectMapper mapper; |
||||||
|
|
||||||
|
@Bean |
||||||
|
public IntegrationFlow eventsMethodRouterFlow() { |
||||||
|
return IntegrationFlows |
||||||
|
.from(ChannelName.INBOUND_EVENTS) |
||||||
|
.<byte[], CommonTopicReceiver>transform(payload -> { |
||||||
|
try { |
||||||
|
return mapper.readValue(payload, CommonTopicReceiver.class); |
||||||
|
} catch (IOException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
return new CommonTopicReceiver(); |
||||||
|
}) |
||||||
|
.<CommonTopicReceiver, EventsMethodEnum>route( |
||||||
|
receiver -> EventsMethodEnum.find(receiver.getMethod()), |
||||||
|
mapping -> { |
||||||
|
mapping.channelMapping(EventsMethodEnum.FILE_UPLOAD_CALLBACK, ChannelName.INBOUND_EVENTS_FILE_UPLOAD_CALLBACK); |
||||||
|
mapping.channelMapping(EventsMethodEnum.FLIGHT_TASK_PROGRESS, ChannelName.INBOUND_EVENTS_FLIGHT_TASK_PROGRESS); |
||||||
|
mapping.channelMapping(EventsMethodEnum.HMS, ChannelName.INBOUND_EVENTS_HMS); |
||||||
|
mapping.channelMapping(EventsMethodEnum.UNKNOWN, ChannelName.DEFAULT); |
||||||
|
}) |
||||||
|
.get(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,118 @@ |
|||||||
|
package com.dji.sample.component.mqtt.handler; |
||||||
|
|
||||||
|
import com.dji.sample.component.mqtt.model.ChannelName; |
||||||
|
import lombok.extern.slf4j.Slf4j; |
||||||
|
import org.springframework.integration.annotation.Router; |
||||||
|
import org.springframework.integration.mqtt.support.MqttHeaders; |
||||||
|
import org.springframework.integration.router.AbstractMessageRouter; |
||||||
|
import org.springframework.messaging.Message; |
||||||
|
import org.springframework.messaging.MessageChannel; |
||||||
|
import org.springframework.messaging.MessageHeaders; |
||||||
|
import org.springframework.stereotype.Component; |
||||||
|
|
||||||
|
import javax.annotation.Resource; |
||||||
|
import java.util.Collection; |
||||||
|
import java.util.Collections; |
||||||
|
import java.util.regex.Pattern; |
||||||
|
|
||||||
|
import static com.dji.sample.component.mqtt.model.TopicConst.*; |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @author sean.zhou |
||||||
|
* @date 2021/11/10 |
||||||
|
* @version 0.1 |
||||||
|
*/ |
||||||
|
@Component |
||||||
|
@Slf4j |
||||||
|
public class InboundMessageRouter extends AbstractMessageRouter { |
||||||
|
|
||||||
|
@Resource(name = ChannelName.INBOUND) |
||||||
|
private MessageChannel inboundChannel; |
||||||
|
|
||||||
|
@Resource(name = ChannelName.INBOUND_STATUS) |
||||||
|
private MessageChannel statusChannel; |
||||||
|
|
||||||
|
@Resource(name = ChannelName.INBOUND_STATE) |
||||||
|
private MessageChannel stateChannel; |
||||||
|
|
||||||
|
@Resource(name = ChannelName.DEFAULT) |
||||||
|
private MessageChannel defaultChannel; |
||||||
|
|
||||||
|
@Resource(name = ChannelName.INBOUND_SERVICE_REPLY) |
||||||
|
private MessageChannel serviceReplyChannel; |
||||||
|
|
||||||
|
@Resource(name = ChannelName.INBOUND_OSD) |
||||||
|
private MessageChannel osdChannel; |
||||||
|
|
||||||
|
@Resource(name = ChannelName.INBOUND_REQUESTS) |
||||||
|
private MessageChannel requestsChannel; |
||||||
|
|
||||||
|
@Resource(name = ChannelName.INBOUND_EVENTS) |
||||||
|
private MessageChannel eventsChannel; |
||||||
|
|
||||||
|
private static final Pattern PATTERN_TOPIC_STATUS = |
||||||
|
Pattern.compile("^" + BASIC_PRE + PRODUCT + REGEX_SN + STATUS_SUF + "$"); |
||||||
|
|
||||||
|
private static final Pattern PATTERN_TOPIC_STATE = |
||||||
|
Pattern.compile("^" + THING_MODEL_PRE + PRODUCT + REGEX_SN + STATE_SUF + "$"); |
||||||
|
|
||||||
|
private static final Pattern PATTERN_TOPIC_SERVICE_REPLY = |
||||||
|
Pattern.compile("^" + THING_MODEL_PRE + PRODUCT + REGEX_SN + SERVICES_SUF + _REPLY_SUF + "$"); |
||||||
|
|
||||||
|
private static final Pattern PATTERN_TOPIC_OSD = |
||||||
|
Pattern.compile("^" + THING_MODEL_PRE + PRODUCT + REGEX_SN + OSD_SUF + "$"); |
||||||
|
|
||||||
|
private static final Pattern PATTERN_TOPIC_REQUESTS = |
||||||
|
Pattern.compile("^" + THING_MODEL_PRE + PRODUCT + REGEX_SN + REQUESTS_SUF + "$"); |
||||||
|
|
||||||
|
private static final Pattern PATTERN_TOPIC_EVENTS = |
||||||
|
Pattern.compile("^" + THING_MODEL_PRE + PRODUCT + REGEX_SN + EVENTS_SUF + "$"); |
||||||
|
|
||||||
|
/** |
||||||
|
* All mqtt broker messages will arrive here before distributing them to different channels. |
||||||
|
* @param message message from mqtt broker |
||||||
|
* @return channel |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
@Router(inputChannel = ChannelName.INBOUND) |
||||||
|
protected Collection<MessageChannel> determineTargetChannels(Message<?> message) { |
||||||
|
MessageHeaders headers = message.getHeaders(); |
||||||
|
String topic = headers.get(MqttHeaders.RECEIVED_TOPIC).toString(); |
||||||
|
byte[] payload = (byte[])message.getPayload(); |
||||||
|
|
||||||
|
// osd
|
||||||
|
if (PATTERN_TOPIC_OSD.matcher(topic).matches()) { |
||||||
|
return Collections.singleton(osdChannel); |
||||||
|
} |
||||||
|
|
||||||
|
log.debug("received topic :{} \t payload :{}", topic, new String(payload)); |
||||||
|
|
||||||
|
// status
|
||||||
|
if (PATTERN_TOPIC_STATUS.matcher(topic).matches()) { |
||||||
|
return Collections.singleton(statusChannel); |
||||||
|
} |
||||||
|
|
||||||
|
// state
|
||||||
|
if (PATTERN_TOPIC_STATE.matcher(topic).matches()) { |
||||||
|
return Collections.singleton(stateChannel); |
||||||
|
} |
||||||
|
|
||||||
|
// services_reply
|
||||||
|
if (PATTERN_TOPIC_SERVICE_REPLY.matcher(topic).matches()) { |
||||||
|
return Collections.singleton(serviceReplyChannel); |
||||||
|
} |
||||||
|
|
||||||
|
// requests
|
||||||
|
if (PATTERN_TOPIC_REQUESTS.matcher(topic).matches()) { |
||||||
|
return Collections.singleton(requestsChannel); |
||||||
|
} |
||||||
|
|
||||||
|
// events
|
||||||
|
if (PATTERN_TOPIC_EVENTS.matcher(topic).matches()) { |
||||||
|
return Collections.singleton(eventsChannel); |
||||||
|
} |
||||||
|
|
||||||
|
return Collections.singleton(defaultChannel); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,49 @@ |
|||||||
|
package com.dji.sample.component.mqtt.handler; |
||||||
|
|
||||||
|
import com.dji.sample.component.mqtt.model.ChannelName; |
||||||
|
import com.dji.sample.component.mqtt.model.CommonTopicReceiver; |
||||||
|
import com.dji.sample.component.mqtt.model.RequestsMethodEnum; |
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.context.annotation.Bean; |
||||||
|
import org.springframework.context.annotation.Configuration; |
||||||
|
import org.springframework.integration.dsl.IntegrationFlow; |
||||||
|
import org.springframework.integration.dsl.IntegrationFlows; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 1.0 |
||||||
|
* @date 2022/5/25 |
||||||
|
*/ |
||||||
|
@Configuration |
||||||
|
public class RequestsRouter { |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private ObjectMapper mapper; |
||||||
|
|
||||||
|
@Bean |
||||||
|
public IntegrationFlow requestsMethodRouterFlow() { |
||||||
|
return IntegrationFlows |
||||||
|
.from(ChannelName.INBOUND_REQUESTS) |
||||||
|
.<byte[], CommonTopicReceiver>transform(payload -> { |
||||||
|
try { |
||||||
|
return mapper.readValue(payload, CommonTopicReceiver.class); |
||||||
|
} catch (IOException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
return new CommonTopicReceiver(); |
||||||
|
}) |
||||||
|
.<CommonTopicReceiver, RequestsMethodEnum>route( |
||||||
|
receiver -> RequestsMethodEnum.find(receiver.getMethod()), |
||||||
|
mapping -> { |
||||||
|
mapping.channelMapping(RequestsMethodEnum.STORAGE_CONFIG_GET, ChannelName.INBOUND_REQUESTS_STORAGE_CONFIG_GET); |
||||||
|
mapping.channelMapping(RequestsMethodEnum.AIRPORT_BIND_STATUS, ChannelName.INBOUND_REQUESTS_AIRPORT_BIND_STATUS); |
||||||
|
mapping.channelMapping(RequestsMethodEnum.AIRPORT_ORGANIZATION_GET, ChannelName.INBOUND_REQUESTS_AIRPORT_ORGANIZATION_GET); |
||||||
|
mapping.channelMapping(RequestsMethodEnum.AIRPORT_ORGANIZATION_BIND, ChannelName.INBOUND_REQUESTS_AIRPORT_ORGANIZATION_BIND); |
||||||
|
mapping.channelMapping(RequestsMethodEnum.UNKNOWN, ChannelName.DEFAULT); |
||||||
|
}) |
||||||
|
.get(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,26 @@ |
|||||||
|
package com.dji.sample.component.mqtt.handler; |
||||||
|
|
||||||
|
import com.dji.sample.component.mqtt.model.CommonTopicReceiver; |
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException; |
||||||
|
import org.springframework.stereotype.Service; |
||||||
|
|
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 0.3 |
||||||
|
* @date 2022/3/21 |
||||||
|
*/ |
||||||
|
@Service |
||||||
|
public class StateDefaultHandler extends AbstractStateTopicHandler { |
||||||
|
|
||||||
|
protected StateDefaultHandler() { |
||||||
|
super(null); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public CommonTopicReceiver handleState(Map<String, Object> dataNode, CommonTopicReceiver stateReceiver, String sn) throws JsonProcessingException { |
||||||
|
// If no suitable handler is found for the data, it is not processed.
|
||||||
|
return stateReceiver; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,38 @@ |
|||||||
|
package com.dji.sample.component.mqtt.handler; |
||||||
|
|
||||||
|
import com.dji.sample.component.mqtt.model.CommonTopicReceiver; |
||||||
|
import com.dji.sample.component.mqtt.model.StateDataEnum; |
||||||
|
import com.dji.sample.manage.model.receiver.DeviceBasicReceiver; |
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.beans.factory.annotation.Qualifier; |
||||||
|
import org.springframework.stereotype.Service; |
||||||
|
|
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 0.3 |
||||||
|
* @date 2022/2/21 |
||||||
|
*/ |
||||||
|
@Service |
||||||
|
public class StateDeviceBasicHandler extends AbstractStateTopicHandler { |
||||||
|
|
||||||
|
public StateDeviceBasicHandler(@Autowired @Qualifier("stateLiveCapacityHandler") AbstractStateTopicHandler handler) { |
||||||
|
super(handler); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public CommonTopicReceiver handleState(Map<String, Object> dataNode, CommonTopicReceiver stateReceiver, String sn) throws JsonProcessingException { |
||||||
|
// handle device basic data
|
||||||
|
if (dataNode.containsKey(StateDataEnum.PAYLOADS.getDesc())) { |
||||||
|
DeviceBasicReceiver data = mapper.convertValue(stateReceiver.getData(), DeviceBasicReceiver.class); |
||||||
|
data.setDeviceSn(sn); |
||||||
|
data.getPayloads().forEach(payload -> payload.setDeviceSn(sn)); |
||||||
|
|
||||||
|
stateReceiver.setData(data); |
||||||
|
return stateReceiver; |
||||||
|
} |
||||||
|
return handler.handleState(dataNode, stateReceiver, sn); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,62 @@ |
|||||||
|
package com.dji.sample.component.mqtt.handler; |
||||||
|
|
||||||
|
import com.dji.sample.component.mqtt.model.CommonTopicReceiver; |
||||||
|
import com.dji.sample.component.mqtt.model.StateDataEnum; |
||||||
|
import com.dji.sample.manage.model.enums.DeviceDomainEnum; |
||||||
|
import com.dji.sample.manage.model.enums.PayloadModelEnum; |
||||||
|
import com.dji.sample.manage.model.receiver.FirmwareVersionReceiver; |
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.beans.factory.annotation.Qualifier; |
||||||
|
import org.springframework.stereotype.Service; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 0.3 |
||||||
|
* @date 2022/2/21 |
||||||
|
*/ |
||||||
|
@Service |
||||||
|
public class StateFirmwareVersionHandler extends AbstractStateTopicHandler { |
||||||
|
|
||||||
|
protected StateFirmwareVersionHandler(@Autowired @Qualifier("stateDefaultHandler") AbstractStateTopicHandler handler) { |
||||||
|
super(handler); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public CommonTopicReceiver handleState(Map<String, Object> dataNode, CommonTopicReceiver stateReceiver, String sn) throws JsonProcessingException { |
||||||
|
// Parse the firmware version of the device.
|
||||||
|
if (dataNode.containsKey(StateDataEnum.FIRMWARE_VERSION.getDesc())) { |
||||||
|
FirmwareVersionReceiver firmware = mapper.convertValue(dataNode, FirmwareVersionReceiver.class); |
||||||
|
firmware.setSn(sn); |
||||||
|
firmware.setDomain(DeviceDomainEnum.SUB_DEVICE); |
||||||
|
stateReceiver.setData(firmware); |
||||||
|
return stateReceiver; |
||||||
|
} |
||||||
|
|
||||||
|
// Parse the firmware version of the payload.
|
||||||
|
List<String> payloads = PayloadModelEnum.getAllModel(); |
||||||
|
long count = dataNode.keySet() |
||||||
|
.stream() |
||||||
|
.map(key -> { |
||||||
|
int end = key.indexOf("-"); |
||||||
|
return end == -1 ? key : key.substring(0, end); |
||||||
|
}) |
||||||
|
.filter(payloads::contains) |
||||||
|
.count(); |
||||||
|
if (count > 0) { |
||||||
|
FirmwareVersionReceiver firmware = FirmwareVersionReceiver.builder() |
||||||
|
.firmwareVersion(((Map<String, String>)(dataNode.values().iterator().next())) |
||||||
|
.get(StateDataEnum.FIRMWARE_VERSION.getDesc())) |
||||||
|
.sn(sn) |
||||||
|
.domain(DeviceDomainEnum.PAYLOAD) |
||||||
|
.build(); |
||||||
|
stateReceiver.setData(firmware); |
||||||
|
return stateReceiver; |
||||||
|
} |
||||||
|
|
||||||
|
return handler.handleState(dataNode, stateReceiver, sn); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,39 @@ |
|||||||
|
package com.dji.sample.component.mqtt.handler; |
||||||
|
|
||||||
|
import com.dji.sample.component.mqtt.model.CommonTopicReceiver; |
||||||
|
import com.dji.sample.component.mqtt.model.StateDataEnum; |
||||||
|
import com.dji.sample.manage.model.receiver.LiveCapacityReceiver; |
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException; |
||||||
|
import lombok.extern.slf4j.Slf4j; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.beans.factory.annotation.Qualifier; |
||||||
|
import org.springframework.stereotype.Service; |
||||||
|
|
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 0.3 |
||||||
|
* @date 2022/2/21 |
||||||
|
*/ |
||||||
|
@Service |
||||||
|
@Slf4j |
||||||
|
public class StateLiveCapacityHandler extends AbstractStateTopicHandler { |
||||||
|
|
||||||
|
protected StateLiveCapacityHandler(@Autowired @Qualifier("stateFirmwareVersionHandler") AbstractStateTopicHandler handler) { |
||||||
|
super(handler); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public CommonTopicReceiver handleState(Map<String, Object> dataNode, CommonTopicReceiver stateReceiver, String sn) throws JsonProcessingException { |
||||||
|
// Determine if it is live capacity data based on name.
|
||||||
|
if (dataNode.containsKey(StateDataEnum.LIVE_CAPACITY.getDesc())) { |
||||||
|
stateReceiver.setData(mapper.convertValue( |
||||||
|
dataNode.get(StateDataEnum.LIVE_CAPACITY.getDesc()), |
||||||
|
LiveCapacityReceiver.class)); |
||||||
|
log.info("Analyze live stream capabilities."); |
||||||
|
return stateReceiver; |
||||||
|
} |
||||||
|
return handler.handleState(dataNode, stateReceiver, sn); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,104 @@ |
|||||||
|
package com.dji.sample.component.mqtt.handler; |
||||||
|
|
||||||
|
import com.dji.sample.component.mqtt.model.ChannelName; |
||||||
|
import com.dji.sample.component.mqtt.model.CommonTopicReceiver; |
||||||
|
import com.dji.sample.manage.model.receiver.DeviceBasicReceiver; |
||||||
|
import com.dji.sample.manage.model.receiver.FirmwareVersionReceiver; |
||||||
|
import com.dji.sample.manage.model.receiver.LiveCapacityReceiver; |
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper; |
||||||
|
import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException; |
||||||
|
import lombok.extern.slf4j.Slf4j; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.context.annotation.Bean; |
||||||
|
import org.springframework.context.annotation.Configuration; |
||||||
|
import org.springframework.integration.annotation.MessageEndpoint; |
||||||
|
import org.springframework.integration.annotation.Router; |
||||||
|
import org.springframework.integration.annotation.ServiceActivator; |
||||||
|
import org.springframework.integration.annotation.Splitter; |
||||||
|
import org.springframework.integration.mqtt.support.MqttHeaders; |
||||||
|
import org.springframework.integration.router.MessageRouter; |
||||||
|
import org.springframework.integration.router.PayloadTypeRouter; |
||||||
|
import org.springframework.messaging.Message; |
||||||
|
|
||||||
|
import javax.annotation.Resource; |
||||||
|
import java.io.IOException; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.Collection; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
import static com.dji.sample.component.mqtt.model.TopicConst.*; |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @author sean.zhou |
||||||
|
* @date 2021/11/17 |
||||||
|
* @version 0.1 |
||||||
|
*/ |
||||||
|
@MessageEndpoint |
||||||
|
@Slf4j |
||||||
|
@Configuration |
||||||
|
public class StateRouter { |
||||||
|
|
||||||
|
@Resource(name = "stateDeviceBasicHandler") |
||||||
|
private AbstractStateTopicHandler handler; |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private ObjectMapper mapper; |
||||||
|
|
||||||
|
/** |
||||||
|
* Handles the routing of state topic messages. Depending on the data, it is assigned to different channels for handling. |
||||||
|
* @param message |
||||||
|
* @return |
||||||
|
* @throws IOException |
||||||
|
*/ |
||||||
|
@ServiceActivator(inputChannel = ChannelName.INBOUND_STATE, outputChannel = ChannelName.INBOUND_STATE_SPLITTER) |
||||||
|
public CommonTopicReceiver<?> resolveStateData(Message<?> message) throws IOException { |
||||||
|
byte[] payload = (byte[])message.getPayload(); |
||||||
|
String topic = message.getHeaders().get(MqttHeaders.RECEIVED_TOPIC).toString(); |
||||||
|
|
||||||
|
CommonTopicReceiver stateReceiver = mapper.readValue(payload, CommonTopicReceiver.class); |
||||||
|
// Get the sn of the topic source.
|
||||||
|
String from = topic.substring((THING_MODEL_PRE + PRODUCT).length(), |
||||||
|
topic.indexOf(STATE_SUF)); |
||||||
|
|
||||||
|
try { |
||||||
|
Map<String, Object> data = (Map<String, Object>) (stateReceiver.getData()); |
||||||
|
|
||||||
|
return handler.handleState(data, stateReceiver, from); |
||||||
|
|
||||||
|
} catch (UnrecognizedPropertyException e) { |
||||||
|
log.info("The {} data is not processed.", e.getPropertyName()); |
||||||
|
} |
||||||
|
return stateReceiver; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Split the state message data to different channels for handling according to their different types. |
||||||
|
* @param receiver state message |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
@Splitter(inputChannel = ChannelName.INBOUND_STATE_SPLITTER, outputChannel = ChannelName.INBOUND_STATE_ROUTER) |
||||||
|
public Collection<Object> splitState(CommonTopicReceiver receiver) { |
||||||
|
ArrayList<Object> type = new ArrayList<>(); |
||||||
|
type.add(receiver.getData()); |
||||||
|
return type; |
||||||
|
} |
||||||
|
|
||||||
|
@Bean |
||||||
|
@Router(inputChannel = ChannelName.INBOUND_STATE_ROUTER) |
||||||
|
public MessageRouter resolveStateRouter() { |
||||||
|
PayloadTypeRouter router = new PayloadTypeRouter(); |
||||||
|
// Channel mapping for basic data.
|
||||||
|
router.setChannelMapping(DeviceBasicReceiver.class.getName(), |
||||||
|
ChannelName.INBOUND_STATE_BASIC); |
||||||
|
// Channel mapping for live streaming capabilities.
|
||||||
|
router.setChannelMapping(LiveCapacityReceiver.class.getName(), |
||||||
|
ChannelName.INBOUND_STATE_CAPACITY); |
||||||
|
router.setChannelMapping(FirmwareVersionReceiver.class.getName(), |
||||||
|
ChannelName.INBOUND_STATE_FIRMWARE_VERSION); |
||||||
|
router.setChannelMapping(Map.class.getName(), |
||||||
|
ChannelName.DEFAULT); |
||||||
|
return router; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,67 @@ |
|||||||
|
package com.dji.sample.component.mqtt.handler; |
||||||
|
|
||||||
|
import com.dji.sample.component.mqtt.model.ChannelName; |
||||||
|
import com.dji.sample.component.mqtt.model.CommonTopicReceiver; |
||||||
|
import com.dji.sample.manage.model.receiver.StatusGatewayReceiver; |
||||||
|
import com.fasterxml.jackson.core.type.TypeReference; |
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.integration.annotation.MessageEndpoint; |
||||||
|
import org.springframework.integration.annotation.Router; |
||||||
|
import org.springframework.integration.annotation.ServiceActivator; |
||||||
|
import org.springframework.integration.mqtt.support.MqttHeaders; |
||||||
|
import org.springframework.messaging.Message; |
||||||
|
import org.springframework.util.CollectionUtils; |
||||||
|
|
||||||
|
import static com.dji.sample.component.mqtt.model.TopicConst.*; |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @author sean.zhou |
||||||
|
* @date 2021/11/12 |
||||||
|
* @version 0.1 |
||||||
|
*/ |
||||||
|
@MessageEndpoint |
||||||
|
public class StatusRouter { |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private ObjectMapper mapper; |
||||||
|
|
||||||
|
/** |
||||||
|
* Converts the status data sent by the gateway device into an object. |
||||||
|
* @param message |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
@ServiceActivator(inputChannel = ChannelName.INBOUND_STATUS, outputChannel = ChannelName.INBOUND_STATUS_ROUTER) |
||||||
|
public CommonTopicReceiver<StatusGatewayReceiver> resolveStatus(Message<?> message) { |
||||||
|
CommonTopicReceiver<StatusGatewayReceiver> statusReceiver = new CommonTopicReceiver<>(); |
||||||
|
try { |
||||||
|
statusReceiver = mapper.readValue( |
||||||
|
(byte[])message.getPayload(), |
||||||
|
new TypeReference<CommonTopicReceiver<StatusGatewayReceiver>>() {}); |
||||||
|
|
||||||
|
String topic = message.getHeaders().get(MqttHeaders.RECEIVED_TOPIC).toString(); |
||||||
|
|
||||||
|
// set gateway's sn
|
||||||
|
statusReceiver.getData().setSn( |
||||||
|
topic.substring((BASIC_PRE + PRODUCT).length(), |
||||||
|
topic.indexOf(STATUS_SUF))); |
||||||
|
} catch (Exception e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
return statusReceiver; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Handles the routing of status topic messages. Depending on the data, it is assigned to different channels for handling. |
||||||
|
* @param receiver |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
@Router(inputChannel = ChannelName.INBOUND_STATUS_ROUTER) |
||||||
|
public String resolveStatusRouter(CommonTopicReceiver<StatusGatewayReceiver> receiver) { |
||||||
|
// Determine whether the drone is online or offline according to whether the data of the sub-device is empty.
|
||||||
|
return CollectionUtils.isEmpty(receiver.getData().getSubDevices()) ? |
||||||
|
ChannelName.INBOUND_STATUS_OFFLINE : ChannelName.INBOUND_STATUS_ONLINE; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,45 @@ |
|||||||
|
package com.dji.sample.component.mqtt.model; |
||||||
|
|
||||||
|
import java.util.concurrent.locks.LockSupport; |
||||||
|
|
||||||
|
/** |
||||||
|
* The demo is only for functional closure, which is not recommended. |
||||||
|
* @author sean.zhou |
||||||
|
* @date 2021/11/22 |
||||||
|
* @version 0.1 |
||||||
|
*/ |
||||||
|
public class Chan<T> { |
||||||
|
|
||||||
|
private static final long THREAD_WAIT_TIME = 1000_000 * 2000; |
||||||
|
|
||||||
|
private volatile T data; |
||||||
|
|
||||||
|
private volatile Thread t; |
||||||
|
|
||||||
|
private Chan () { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public static Chan getInstance() { |
||||||
|
return ChanSingleton.INSTANCE; |
||||||
|
} |
||||||
|
|
||||||
|
public T get(Object blocker) { |
||||||
|
this.t = Thread.currentThread(); |
||||||
|
LockSupport.parkNanos(blocker, THREAD_WAIT_TIME); |
||||||
|
this.t = null; |
||||||
|
return data; |
||||||
|
} |
||||||
|
|
||||||
|
public void put(T data) { |
||||||
|
this.data = data; |
||||||
|
if (t == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
LockSupport.unpark(t); |
||||||
|
} |
||||||
|
|
||||||
|
private static class ChanSingleton { |
||||||
|
private static final Chan<?> INSTANCE = new Chan<>(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,23 @@ |
|||||||
|
package com.dji.sample.component.mqtt.model; |
||||||
|
|
||||||
|
import com.dji.sample.common.model.ResponseResult; |
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import lombok.Data; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 1.1 |
||||||
|
* @date 2022/6/14 |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
@AllArgsConstructor |
||||||
|
public class ErrorInfoReply { |
||||||
|
|
||||||
|
private String sn; |
||||||
|
|
||||||
|
private Integer errCode; |
||||||
|
|
||||||
|
public static ErrorInfoReply success(String sn) { |
||||||
|
return new ErrorInfoReply(sn, ResponseResult.CODE_SUCCESS); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,36 @@ |
|||||||
|
package com.dji.sample.component.mqtt.model; |
||||||
|
|
||||||
|
import java.util.Arrays; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 1.1 |
||||||
|
* @date 2022/6/1 |
||||||
|
*/ |
||||||
|
public enum EventsMethodEnum { |
||||||
|
|
||||||
|
FLIGHT_TASK_PROGRESS("flighttask_progress"), |
||||||
|
|
||||||
|
FILE_UPLOAD_CALLBACK("file_upload_callback"), |
||||||
|
|
||||||
|
HMS("hms"), |
||||||
|
|
||||||
|
UNKNOWN("Unknown"); |
||||||
|
|
||||||
|
private String method; |
||||||
|
|
||||||
|
EventsMethodEnum(String method) { |
||||||
|
this.method = method; |
||||||
|
} |
||||||
|
|
||||||
|
public String getMethod() { |
||||||
|
return method; |
||||||
|
} |
||||||
|
|
||||||
|
public static EventsMethodEnum find(String method) { |
||||||
|
return Arrays.stream(EventsMethodEnum.values()) |
||||||
|
.filter(methodEnum -> methodEnum.method.equals(method)) |
||||||
|
.findAny() |
||||||
|
.orElse(UNKNOWN); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,21 @@ |
|||||||
|
package com.dji.sample.component.mqtt.model; |
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; |
||||||
|
import lombok.Data; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 1.1 |
||||||
|
* @date 2022/6/9 |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true) |
||||||
|
public class EventsReceiver<T> { |
||||||
|
|
||||||
|
private Integer result; |
||||||
|
|
||||||
|
private T output; |
||||||
|
|
||||||
|
private String bid; |
||||||
|
|
||||||
|
} |
@ -0,0 +1,29 @@ |
|||||||
|
package com.dji.sample.component.mqtt.model; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 1.1 |
||||||
|
* @date 2022/6/14 |
||||||
|
*/ |
||||||
|
public final class MapKeyConst { |
||||||
|
|
||||||
|
private MapKeyConst(){ |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public static final String ORGANIZATION_NAME = "organization_name"; |
||||||
|
|
||||||
|
public static final String DEVICES = "devices"; |
||||||
|
|
||||||
|
public static final String SN = "sn"; |
||||||
|
|
||||||
|
public static final String BIND_DEVICES = "bind_devices"; |
||||||
|
|
||||||
|
public static final String ERR_INFOS = "err_infos"; |
||||||
|
|
||||||
|
public static final String TINY_FINGERPRINTS = "tiny_fingerprints"; |
||||||
|
|
||||||
|
public static final String BIND_STATUS = "bind_status"; |
||||||
|
|
||||||
|
public static final String LIST = "list"; |
||||||
|
} |
@ -0,0 +1,38 @@ |
|||||||
|
package com.dji.sample.component.mqtt.model; |
||||||
|
|
||||||
|
import java.util.Arrays; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 1.0 |
||||||
|
* @date 2022/5/25 |
||||||
|
*/ |
||||||
|
public enum RequestsMethodEnum { |
||||||
|
|
||||||
|
STORAGE_CONFIG_GET("storage_config_get"), |
||||||
|
|
||||||
|
AIRPORT_BIND_STATUS("airport_bind_status"), |
||||||
|
|
||||||
|
AIRPORT_ORGANIZATION_BIND("airport_organization_bind"), |
||||||
|
|
||||||
|
AIRPORT_ORGANIZATION_GET("airport_organization_get"), |
||||||
|
|
||||||
|
UNKNOWN("Unknown"); |
||||||
|
|
||||||
|
private String method; |
||||||
|
|
||||||
|
RequestsMethodEnum(String method) { |
||||||
|
this.method = method; |
||||||
|
} |
||||||
|
|
||||||
|
public String getMethod() { |
||||||
|
return method; |
||||||
|
} |
||||||
|
|
||||||
|
public static RequestsMethodEnum find(String method) { |
||||||
|
return Arrays.stream(RequestsMethodEnum.values()) |
||||||
|
.filter(methodEnum -> methodEnum.method.equals(method)) |
||||||
|
.findAny() |
||||||
|
.orElse(UNKNOWN); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,44 @@ |
|||||||
|
package com.dji.sample.component.mqtt.model; |
||||||
|
|
||||||
|
import com.dji.sample.common.error.IErrorInfo; |
||||||
|
import com.dji.sample.common.model.ResponseResult; |
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import lombok.Builder; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.NoArgsConstructor; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 1.1 |
||||||
|
* @date 2022/6/13 |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
@Builder |
||||||
|
@AllArgsConstructor |
||||||
|
@NoArgsConstructor |
||||||
|
public class RequestsReply<T> { |
||||||
|
|
||||||
|
private Integer result; |
||||||
|
|
||||||
|
private T output; |
||||||
|
|
||||||
|
|
||||||
|
public static RequestsReply error(IErrorInfo errorInfo) { |
||||||
|
return RequestsReply.builder() |
||||||
|
.result(errorInfo.getErrorCode()) |
||||||
|
.output(errorInfo.getErrorMsg()) |
||||||
|
.build(); |
||||||
|
} |
||||||
|
|
||||||
|
public static <T> RequestsReply success(T data) { |
||||||
|
return RequestsReply.builder() |
||||||
|
.result(ResponseResult.CODE_SUCCESS) |
||||||
|
.output(data) |
||||||
|
.build(); |
||||||
|
} |
||||||
|
public static RequestsReply success() { |
||||||
|
return RequestsReply.builder() |
||||||
|
.result(ResponseResult.CODE_SUCCESS) |
||||||
|
.build(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,20 @@ |
|||||||
|
package com.dji.sample.component.mqtt.model; |
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; |
||||||
|
import lombok.Data; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean.zhou |
||||||
|
* @version 0.1 |
||||||
|
* @date 2021/11/22 |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true) |
||||||
|
public class ServiceReply<T> { |
||||||
|
|
||||||
|
private Integer result; |
||||||
|
|
||||||
|
private T info; |
||||||
|
|
||||||
|
private T output; |
||||||
|
} |
@ -0,0 +1,29 @@ |
|||||||
|
package com.dji.sample.component.mqtt.model; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean.zhou |
||||||
|
* @date 2021/11/22 |
||||||
|
* @version 0.1 |
||||||
|
*/ |
||||||
|
public enum ServicesMethodEnum { |
||||||
|
|
||||||
|
LIVE_START_PUSH("live_start_push"), |
||||||
|
|
||||||
|
LIVE_STOP_PUSH("live_stop_push"), |
||||||
|
|
||||||
|
LIVE_SET_QUALITY("live_set_quality"), |
||||||
|
|
||||||
|
FLIGHTTASK_CREATE("flighttask_create"), |
||||||
|
|
||||||
|
UNKNOWN("unknown"); |
||||||
|
|
||||||
|
private String method; |
||||||
|
|
||||||
|
ServicesMethodEnum(String method) { |
||||||
|
this.method = method; |
||||||
|
} |
||||||
|
|
||||||
|
public String getMethod() { |
||||||
|
return method; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,26 @@ |
|||||||
|
package com.dji.sample.component.mqtt.model; |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @author sean.zhou |
||||||
|
* @date 2021/11/18 |
||||||
|
* @version 0.1 |
||||||
|
*/ |
||||||
|
public enum StateDataEnum { |
||||||
|
|
||||||
|
FIRMWARE_VERSION("firmware_version"), |
||||||
|
|
||||||
|
LIVE_CAPACITY("live_capacity"), |
||||||
|
|
||||||
|
PAYLOADS("payloads"); |
||||||
|
|
||||||
|
private String desc; |
||||||
|
|
||||||
|
StateDataEnum(String desc) { |
||||||
|
this.desc = desc; |
||||||
|
} |
||||||
|
|
||||||
|
public String getDesc() { |
||||||
|
return this.desc; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,94 @@ |
|||||||
|
package com.dji.sample.component.oss.model; |
||||||
|
|
||||||
|
import lombok.Data; |
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties; |
||||||
|
import org.springframework.stereotype.Component; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 0.2 |
||||||
|
* @date 2021/12/9 |
||||||
|
*/ |
||||||
|
@ConfigurationProperties(prefix = "oss") |
||||||
|
@Component |
||||||
|
@Data |
||||||
|
public class OssConfiguration { |
||||||
|
|
||||||
|
/** |
||||||
|
* @see com.dji.sample.component.oss.model.enums.OssTypeEnum |
||||||
|
*/ |
||||||
|
private String provider; |
||||||
|
|
||||||
|
/** |
||||||
|
* Whether to use the object storage service. |
||||||
|
*/ |
||||||
|
private boolean enable; |
||||||
|
|
||||||
|
/** |
||||||
|
* The protocol needs to be included at the beginning of the address. |
||||||
|
*/ |
||||||
|
private String endpoint; |
||||||
|
|
||||||
|
private String accessKey; |
||||||
|
|
||||||
|
private String secretKey; |
||||||
|
|
||||||
|
private String region; |
||||||
|
|
||||||
|
private Long expire; |
||||||
|
|
||||||
|
private String roleSessionName; |
||||||
|
|
||||||
|
private String roleArn; |
||||||
|
|
||||||
|
private String bucket; |
||||||
|
|
||||||
|
private String objectDirPrefix; |
||||||
|
|
||||||
|
public void setProvider(String provider) { |
||||||
|
this.provider = provider; |
||||||
|
} |
||||||
|
|
||||||
|
public void setEnable(boolean enable) { |
||||||
|
this.enable = enable; |
||||||
|
} |
||||||
|
|
||||||
|
public void setEndpoint(String endpoint) { |
||||||
|
this.endpoint = endpoint; |
||||||
|
} |
||||||
|
|
||||||
|
public void setAccessKey(String accessKey) { |
||||||
|
this.accessKey = accessKey; |
||||||
|
} |
||||||
|
|
||||||
|
public void setSecretKey(String secretKey) { |
||||||
|
this.secretKey = secretKey; |
||||||
|
} |
||||||
|
|
||||||
|
public void setRegion(String region) { |
||||||
|
this.region = region; |
||||||
|
} |
||||||
|
|
||||||
|
public void setExpire(Long expire) { |
||||||
|
this.expire = expire; |
||||||
|
} |
||||||
|
|
||||||
|
public void setRoleSessionName(String roleSessionName) { |
||||||
|
this.roleSessionName = roleSessionName; |
||||||
|
} |
||||||
|
|
||||||
|
public void setRoleArn(String roleArn) { |
||||||
|
this.roleArn = roleArn; |
||||||
|
} |
||||||
|
|
||||||
|
public void setBucket(String bucket) { |
||||||
|
this.bucket = bucket; |
||||||
|
} |
||||||
|
|
||||||
|
public void setObjectDirPrefix(String objectDirPrefix) { |
||||||
|
this.objectDirPrefix = objectDirPrefix; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,28 @@ |
|||||||
|
package com.dji.sample.component.oss.model.enums; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 1.0 |
||||||
|
* @date 2022/5/30 |
||||||
|
*/ |
||||||
|
public enum OssTypeEnum { |
||||||
|
|
||||||
|
ALIYUN("ali"), |
||||||
|
|
||||||
|
AWS("aws"), |
||||||
|
|
||||||
|
/* |
||||||
|
* MinIO is temporarily unavailable. |
||||||
|
*/ |
||||||
|
MINIO("minio"); |
||||||
|
|
||||||
|
private String type; |
||||||
|
|
||||||
|
OssTypeEnum(String type) { |
||||||
|
this.type = type; |
||||||
|
} |
||||||
|
|
||||||
|
public String getType() { |
||||||
|
return type; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,135 @@ |
|||||||
|
package com.dji.sample.component.oss.service.impl; |
||||||
|
|
||||||
|
import com.amazonaws.HttpMethod; |
||||||
|
import com.amazonaws.auth.AWSStaticCredentialsProvider; |
||||||
|
import com.amazonaws.auth.BasicAWSCredentials; |
||||||
|
import com.amazonaws.services.s3.AmazonS3; |
||||||
|
import com.amazonaws.services.s3.AmazonS3ClientBuilder; |
||||||
|
import com.amazonaws.services.s3.model.BucketCrossOriginConfiguration; |
||||||
|
import com.amazonaws.services.s3.model.CORSRule; |
||||||
|
import com.amazonaws.services.s3.model.S3Object; |
||||||
|
import com.amazonaws.services.securitytoken.AWSSecurityTokenService; |
||||||
|
import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClientBuilder; |
||||||
|
import com.amazonaws.services.securitytoken.model.AssumeRoleRequest; |
||||||
|
import com.amazonaws.services.securitytoken.model.AssumeRoleResult; |
||||||
|
import com.amazonaws.services.securitytoken.model.Credentials; |
||||||
|
import com.dji.sample.component.AuthInterceptor; |
||||||
|
import com.dji.sample.component.oss.model.OssConfiguration; |
||||||
|
import com.dji.sample.component.oss.model.enums.OssTypeEnum; |
||||||
|
import com.dji.sample.component.oss.service.IOssService; |
||||||
|
import com.dji.sample.media.model.CredentialsDTO; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.stereotype.Service; |
||||||
|
|
||||||
|
import javax.annotation.PostConstruct; |
||||||
|
import java.io.IOException; |
||||||
|
import java.io.InputStream; |
||||||
|
import java.net.URL; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.Date; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 1.0 |
||||||
|
* @date 2022/4/27 |
||||||
|
*/ |
||||||
|
@Service |
||||||
|
public class AmazonS3ServiceImpl implements IOssService { |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private OssConfiguration configuration; |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getOssType() { |
||||||
|
return OssTypeEnum.AWS.getType(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public CredentialsDTO getCredentials() { |
||||||
|
AWSSecurityTokenService stsClient = AWSSecurityTokenServiceClientBuilder.standard() |
||||||
|
.withCredentials(new AWSStaticCredentialsProvider( |
||||||
|
new BasicAWSCredentials(configuration.getAccessKey(), configuration.getSecretKey()))) |
||||||
|
.withRegion(configuration.getRegion()).build(); |
||||||
|
|
||||||
|
AssumeRoleRequest request = new AssumeRoleRequest() |
||||||
|
.withRoleArn(configuration.getRoleArn()) |
||||||
|
.withRoleSessionName(configuration.getRoleSessionName()) |
||||||
|
.withDurationSeconds(Math.toIntExact(configuration.getExpire())); |
||||||
|
AssumeRoleResult result = stsClient.assumeRole(request); |
||||||
|
Credentials credentials = result.getCredentials(); |
||||||
|
stsClient.shutdown(); |
||||||
|
return new CredentialsDTO(credentials); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public URL getObjectUrl(String bucket, String objectKey) { |
||||||
|
AmazonS3 client = this.createClient(); |
||||||
|
URL url = client.generatePresignedUrl(bucket, objectKey, |
||||||
|
new Date(System.currentTimeMillis() + configuration.getExpire() * 1000), HttpMethod.GET); |
||||||
|
client.shutdown(); |
||||||
|
return url; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Boolean deleteObject(String bucket, String objectKey) { |
||||||
|
AmazonS3 client = this.createClient(); |
||||||
|
client.deleteObject(bucket, objectKey); |
||||||
|
client.shutdown(); |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
public byte[] getObject(String bucket, String objectKey) { |
||||||
|
AmazonS3 client = this.createClient(); |
||||||
|
S3Object object = client.getObject(bucket, objectKey); |
||||||
|
InputStream stream = object.getObjectContent().getDelegateStream(); |
||||||
|
try { |
||||||
|
return stream.readAllBytes(); |
||||||
|
} catch (IOException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} finally { |
||||||
|
try { |
||||||
|
stream.close(); |
||||||
|
client.shutdown(); |
||||||
|
} catch (IOException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
} |
||||||
|
return new byte[0]; |
||||||
|
} |
||||||
|
|
||||||
|
private AmazonS3 createClient() { |
||||||
|
return AmazonS3ClientBuilder.standard() |
||||||
|
.withCredentials( |
||||||
|
new AWSStaticCredentialsProvider( |
||||||
|
new BasicAWSCredentials(configuration.getAccessKey(), configuration.getSecretKey()))) |
||||||
|
.withRegion(configuration.getRegion()) |
||||||
|
.build(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Configuring cross-origin resource sharing |
||||||
|
*/ |
||||||
|
@PostConstruct |
||||||
|
private void configCORS() { |
||||||
|
if (!configuration.isEnable() || !OssTypeEnum.AWS.getType().equals(configuration.getProvider())) { |
||||||
|
return; |
||||||
|
} |
||||||
|
List<CORSRule.AllowedMethods> allowedMethods = new ArrayList<>(); |
||||||
|
allowedMethods.add(CORSRule.AllowedMethods.GET); |
||||||
|
allowedMethods.add(CORSRule.AllowedMethods.POST); |
||||||
|
allowedMethods.add(CORSRule.AllowedMethods.DELETE); |
||||||
|
|
||||||
|
CORSRule rule = new CORSRule() |
||||||
|
.withId("CORSAccessRule") |
||||||
|
.withAllowedOrigins(List.of("*")) |
||||||
|
.withAllowedHeaders(List.of(AuthInterceptor.PARAM_TOKEN)) |
||||||
|
.withAllowedMethods(allowedMethods); |
||||||
|
|
||||||
|
AmazonS3 client = this.createClient(); |
||||||
|
|
||||||
|
client.setBucketCrossOriginConfiguration(this.configuration.getBucket(), |
||||||
|
new BucketCrossOriginConfiguration().withRules(rule)); |
||||||
|
client.shutdown(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,33 @@ |
|||||||
|
package com.dji.sample.component.oss.service.impl; |
||||||
|
|
||||||
|
import com.dji.sample.component.oss.model.OssConfiguration; |
||||||
|
import org.aspectj.lang.annotation.Aspect; |
||||||
|
import org.aspectj.lang.annotation.Before; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.stereotype.Component; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 1.1 |
||||||
|
* @date 2022/6/20 |
||||||
|
*/ |
||||||
|
@Component |
||||||
|
@Aspect |
||||||
|
public class OssAspectHandler { |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private OssServiceContext ossServiceContext; |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private OssConfiguration configuration; |
||||||
|
|
||||||
|
@Before("execution(public * com.dji.sample.component.oss.service.impl.OssServiceContext.*(..))") |
||||||
|
public void before() { |
||||||
|
if (!this.configuration.isEnable()) { |
||||||
|
throw new IllegalArgumentException("Please enable OssConfiguration."); |
||||||
|
} |
||||||
|
if (this.ossServiceContext.getOssService() == null) { |
||||||
|
throw new IllegalArgumentException("Please check the OssConfiguration configuration."); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,58 @@ |
|||||||
|
package com.dji.sample.component.oss.service.impl; |
||||||
|
|
||||||
|
import com.dji.sample.component.oss.model.OssConfiguration; |
||||||
|
import com.dji.sample.component.oss.model.enums.OssTypeEnum; |
||||||
|
import com.dji.sample.component.oss.service.IOssService; |
||||||
|
import com.dji.sample.media.model.CredentialsDTO; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.stereotype.Service; |
||||||
|
|
||||||
|
import java.net.URL; |
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 1.0 |
||||||
|
* @date 2022/5/30 |
||||||
|
*/ |
||||||
|
@Service |
||||||
|
public class OssServiceContext { |
||||||
|
|
||||||
|
private IOssService ossService; |
||||||
|
|
||||||
|
private OssConfiguration configuration; |
||||||
|
|
||||||
|
@Autowired |
||||||
|
public OssServiceContext(List<IOssService> ossServices, OssConfiguration configuration) { |
||||||
|
this.configuration = configuration; |
||||||
|
if (!configuration.isEnable()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
this.ossService = ossServices.stream() |
||||||
|
.filter(ossService -> ossService.getOssType().equals(configuration.getProvider())) |
||||||
|
.findFirst() |
||||||
|
.orElseThrow(() -> new IllegalArgumentException("Oss provider is illegal. Optional: " + |
||||||
|
Arrays.toString(Arrays.stream(OssTypeEnum.values()).map(OssTypeEnum::getType).toArray()))); |
||||||
|
} |
||||||
|
|
||||||
|
IOssService getOssService() { |
||||||
|
return this.ossService; |
||||||
|
} |
||||||
|
|
||||||
|
public CredentialsDTO getCredentials() { |
||||||
|
return this.ossService.getCredentials(); |
||||||
|
} |
||||||
|
|
||||||
|
public URL getObjectUrl(String bucket, String objectKey) { |
||||||
|
return this.ossService.getObjectUrl(bucket, objectKey); |
||||||
|
} |
||||||
|
|
||||||
|
public Boolean deleteObject(String bucket, String objectKey) { |
||||||
|
return this.ossService.deleteObject(bucket, objectKey); |
||||||
|
} |
||||||
|
|
||||||
|
public byte[] getObject(String bucket, String objectKey) { |
||||||
|
return this.ossService.getObject(bucket, objectKey); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,63 @@ |
|||||||
|
package com.dji.sample.component.redis; |
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude; |
||||||
|
import com.fasterxml.jackson.annotation.JsonTypeInfo; |
||||||
|
import com.fasterxml.jackson.databind.MapperFeature; |
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper; |
||||||
|
import com.fasterxml.jackson.databind.PropertyNamingStrategy; |
||||||
|
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; |
||||||
|
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; |
||||||
|
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; |
||||||
|
import org.springframework.context.annotation.Bean; |
||||||
|
import org.springframework.context.annotation.Configuration; |
||||||
|
import org.springframework.data.redis.connection.RedisConnectionFactory; |
||||||
|
import org.springframework.data.redis.core.RedisTemplate; |
||||||
|
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories; |
||||||
|
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; |
||||||
|
import org.springframework.data.redis.serializer.StringRedisSerializer; |
||||||
|
|
||||||
|
import java.time.LocalDateTime; |
||||||
|
import java.time.format.DateTimeFormatter; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 1.0 |
||||||
|
* @date 2022/4/19 |
||||||
|
*/ |
||||||
|
@Configuration |
||||||
|
@EnableRedisRepositories |
||||||
|
public class RedisConfiguration { |
||||||
|
|
||||||
|
@Bean |
||||||
|
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { |
||||||
|
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); |
||||||
|
redisTemplate.setConnectionFactory(factory); |
||||||
|
|
||||||
|
ObjectMapper objectMapper = new ObjectMapper(); |
||||||
|
JavaTimeModule timeModule = new JavaTimeModule(); |
||||||
|
timeModule.addDeserializer(LocalDateTime.class, |
||||||
|
new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); |
||||||
|
timeModule.addSerializer(LocalDateTime.class, |
||||||
|
new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); |
||||||
|
objectMapper.disable(MapperFeature.IGNORE_DUPLICATE_MODULE_REGISTRATIONS); |
||||||
|
objectMapper.registerModules(timeModule); |
||||||
|
objectMapper.activateDefaultTyping(objectMapper.getPolymorphicTypeValidator(), |
||||||
|
ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY); |
||||||
|
|
||||||
|
objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE); |
||||||
|
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY); |
||||||
|
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); |
||||||
|
|
||||||
|
|
||||||
|
StringRedisSerializer serializer = new StringRedisSerializer(); |
||||||
|
redisTemplate.setKeySerializer(serializer); |
||||||
|
redisTemplate.setHashKeySerializer(serializer); |
||||||
|
|
||||||
|
GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer(objectMapper); |
||||||
|
redisTemplate.setValueSerializer(jsonRedisSerializer); |
||||||
|
redisTemplate.setHashValueSerializer(jsonRedisSerializer); |
||||||
|
redisTemplate.afterPropertiesSet(); |
||||||
|
return redisTemplate; |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,29 @@ |
|||||||
|
package com.dji.sample.component.redis; |
||||||
|
|
||||||
|
import com.dji.sample.manage.model.enums.DeviceDomainEnum; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 1.0 |
||||||
|
* @date 2022/4/21 |
||||||
|
*/ |
||||||
|
public final class RedisConst { |
||||||
|
|
||||||
|
private RedisConst() { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public static final Integer DEVICE_ALIVE_SECOND = 60; |
||||||
|
|
||||||
|
public static final Integer WEBSOCKET_ALIVE_SECOND = 60 * 60 * 24; |
||||||
|
|
||||||
|
public static final String ONLINE_PREFIX = "online:"; |
||||||
|
|
||||||
|
public static final String DEVICE_ONLINE_PREFIX = ONLINE_PREFIX + DeviceDomainEnum.SUB_DEVICE + ":"; |
||||||
|
|
||||||
|
public static final String WEBSOCKET_PREFIX = "webSocket:"; |
||||||
|
|
||||||
|
public static final String WEBSOCKET_ALL = "webSocket:all"; |
||||||
|
|
||||||
|
public static final String HMS_PREFIX = "hms:"; |
||||||
|
} |
@ -0,0 +1,187 @@ |
|||||||
|
package com.dji.sample.component.redis; |
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.data.redis.core.RedisTemplate; |
||||||
|
import org.springframework.stereotype.Component; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
import java.util.Set; |
||||||
|
import java.util.concurrent.TimeUnit; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 1.0 |
||||||
|
* @date 2022/4/19 |
||||||
|
*/ |
||||||
|
@Component |
||||||
|
public class RedisOpsUtils { |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private RedisTemplate<String, Object> redisTemplate; |
||||||
|
|
||||||
|
/** |
||||||
|
* HSET |
||||||
|
* @param key |
||||||
|
* @param field |
||||||
|
* @param value |
||||||
|
*/ |
||||||
|
public void hashSet(String key, String field, Object value) { |
||||||
|
redisTemplate.opsForHash().put(key, field, value); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* HGET |
||||||
|
* @param key |
||||||
|
* @param field |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Object hashGet(String key, String field) { |
||||||
|
return redisTemplate.opsForHash().get(key, field); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* HKEYS |
||||||
|
* @param key |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Set<Object> hashKeys(String key) { |
||||||
|
return redisTemplate.opsForHash().keys(key); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* HEXISTS |
||||||
|
* @param key |
||||||
|
* @param field |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public boolean hashCheck(String key, String field) { |
||||||
|
return redisTemplate.opsForHash().hasKey(key, field); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* HDEL |
||||||
|
* @param key |
||||||
|
* @param fields |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public boolean hashDel(String key, Object[] fields) { |
||||||
|
return redisTemplate.opsForHash().delete(key, fields) > 0; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* EXPIRE |
||||||
|
* @param key |
||||||
|
* @param timeout |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public boolean expireKey(String key, long timeout) { |
||||||
|
return redisTemplate.expire(key, timeout, TimeUnit.SECONDS); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* SET |
||||||
|
* @param key |
||||||
|
* @param value |
||||||
|
*/ |
||||||
|
public void set(String key, Object value) { |
||||||
|
redisTemplate.opsForValue().set(key, value); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* GET |
||||||
|
* @param key |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Object get(String key) { |
||||||
|
return redisTemplate.opsForValue().get(key); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* SETEX |
||||||
|
* @param key |
||||||
|
* @param value |
||||||
|
* @param expire |
||||||
|
*/ |
||||||
|
public void setWithExpire(String key, Object value, long expire) { |
||||||
|
redisTemplate.opsForValue().set(key, value, expire, TimeUnit.SECONDS); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* TTL |
||||||
|
* @param key |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public long getExpire(String key) { |
||||||
|
return redisTemplate.getExpire(key, TimeUnit.SECONDS); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* EXISTS |
||||||
|
* @param key |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public boolean checkExist(String key) { |
||||||
|
return redisTemplate.hasKey(key); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* DEL |
||||||
|
* @param key |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public boolean del(String key) { |
||||||
|
return this.checkExist(key) && redisTemplate.delete(key); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* KEYS |
||||||
|
* @param pattern |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Set<String> getAllKeys(String pattern) { |
||||||
|
return redisTemplate.keys(pattern); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* RPUSH |
||||||
|
* @param key |
||||||
|
* @param value |
||||||
|
*/ |
||||||
|
public void listRPush(String key, Object... value) { |
||||||
|
if (value.length == 0) { |
||||||
|
return; |
||||||
|
} |
||||||
|
for (Object val : value) { |
||||||
|
redisTemplate.opsForList().rightPush(key, val); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* LRANGE |
||||||
|
* @param key |
||||||
|
* @param start |
||||||
|
* @param end |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public List<Object> listGet(String key, long start, long end) { |
||||||
|
return redisTemplate.opsForList().range(key, start, end); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* LRANGE |
||||||
|
* @param key |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public List<Object> listGetAll(String key) { |
||||||
|
return redisTemplate.opsForList().range(key, 0, -1); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* LLen |
||||||
|
* @param key |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Long listLen(String key) { |
||||||
|
return redisTemplate.opsForList().size(key); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,23 @@ |
|||||||
|
package com.dji.sample.component.websocket.service; |
||||||
|
|
||||||
|
import com.dji.sample.component.websocket.config.ConcurrentWebSocketSession; |
||||||
|
|
||||||
|
import java.util.Collection; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 1.0 |
||||||
|
* @date 2022/4/25 |
||||||
|
*/ |
||||||
|
public interface IWebSocketManageService { |
||||||
|
|
||||||
|
void put(String key, ConcurrentWebSocketSession val); |
||||||
|
|
||||||
|
void remove(String key, String sessionId); |
||||||
|
|
||||||
|
Collection<ConcurrentWebSocketSession> getValueWithWorkspace(String workspaceId); |
||||||
|
|
||||||
|
Collection<ConcurrentWebSocketSession> getValueWithWorkspaceAndUserType(String workspaceId, Integer userType); |
||||||
|
|
||||||
|
Long getConnectedCount(); |
||||||
|
} |
@ -0,0 +1,90 @@ |
|||||||
|
package com.dji.sample.component.websocket.service.impl; |
||||||
|
|
||||||
|
import com.dji.sample.component.redis.RedisConst; |
||||||
|
import com.dji.sample.component.redis.RedisOpsUtils; |
||||||
|
import com.dji.sample.component.websocket.config.ConcurrentWebSocketSession; |
||||||
|
import com.dji.sample.component.websocket.service.IWebSocketManageService; |
||||||
|
import com.dji.sample.manage.model.enums.UserTypeEnum; |
||||||
|
import lombok.extern.slf4j.Slf4j; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.stereotype.Service; |
||||||
|
import org.springframework.util.StringUtils; |
||||||
|
|
||||||
|
import java.util.Collection; |
||||||
|
import java.util.Collections; |
||||||
|
import java.util.Objects; |
||||||
|
import java.util.concurrent.ConcurrentHashMap; |
||||||
|
import java.util.stream.Collectors; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 1.0 |
||||||
|
* @date 2022/4/25 |
||||||
|
*/ |
||||||
|
@Slf4j |
||||||
|
@Service |
||||||
|
public class WebSocketManageServiceImpl implements IWebSocketManageService { |
||||||
|
|
||||||
|
private static final ConcurrentHashMap<String, ConcurrentWebSocketSession> SESSIONS = new ConcurrentHashMap<>(16); |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private RedisOpsUtils redisOps; |
||||||
|
|
||||||
|
@Override |
||||||
|
public void put(String key, ConcurrentWebSocketSession val) { |
||||||
|
String[] name = key.split("/"); |
||||||
|
if (name.length != 3) { |
||||||
|
log.debug("The key is out of format. [{workspaceId}/{userType}/{userId}]"); |
||||||
|
return; |
||||||
|
} |
||||||
|
String sessionId = val.getId(); |
||||||
|
String workspaceKey = RedisConst.WEBSOCKET_PREFIX + name[0]; |
||||||
|
String userTypeKey = RedisConst.WEBSOCKET_PREFIX + UserTypeEnum.find(Integer.parseInt(name[1])).getDesc(); |
||||||
|
redisOps.hashSet(workspaceKey, sessionId, name[2]); |
||||||
|
redisOps.hashSet(userTypeKey, sessionId, name[2]); |
||||||
|
SESSIONS.put(sessionId, val); |
||||||
|
redisOps.expireKey(workspaceKey, RedisConst.WEBSOCKET_ALIVE_SECOND); |
||||||
|
redisOps.expireKey(userTypeKey, RedisConst.WEBSOCKET_ALIVE_SECOND); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void remove(String key, String sessionId) { |
||||||
|
String[] name = key.split("/"); |
||||||
|
if (name.length != 3) { |
||||||
|
log.debug("The key is out of format. [{workspaceId}/{userType}/{userId}]"); |
||||||
|
return; |
||||||
|
} |
||||||
|
redisOps.hashDel(RedisConst.WEBSOCKET_PREFIX + name[0], new String[] {sessionId}); |
||||||
|
redisOps.hashDel(RedisConst.WEBSOCKET_PREFIX + UserTypeEnum.find(Integer.parseInt(name[1])), new String[] {sessionId}); |
||||||
|
SESSIONS.remove(sessionId); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Collection<ConcurrentWebSocketSession> getValueWithWorkspace(String workspaceId) { |
||||||
|
if (!StringUtils.hasText(workspaceId)) { |
||||||
|
return Collections.emptySet(); |
||||||
|
} |
||||||
|
String key = RedisConst.WEBSOCKET_PREFIX + workspaceId; |
||||||
|
|
||||||
|
return redisOps.hashKeys(key) |
||||||
|
.stream() |
||||||
|
.map(SESSIONS::get) |
||||||
|
.filter(Objects::nonNull) |
||||||
|
.collect(Collectors.toSet()); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Collection<ConcurrentWebSocketSession> getValueWithWorkspaceAndUserType(String workspaceId, Integer userType) { |
||||||
|
String key = RedisConst.WEBSOCKET_PREFIX + UserTypeEnum.find(userType).getDesc(); |
||||||
|
return redisOps.hashKeys(key) |
||||||
|
.stream() |
||||||
|
.map(SESSIONS::get) |
||||||
|
.filter(Objects::nonNull) |
||||||
|
.collect(Collectors.toSet()); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Long getConnectedCount() { |
||||||
|
return SESSIONS.mappingCount(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,49 @@ |
|||||||
|
package com.dji.sample.configuration; |
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude; |
||||||
|
import com.fasterxml.jackson.core.JsonGenerator; |
||||||
|
import com.fasterxml.jackson.core.JsonParser; |
||||||
|
import com.fasterxml.jackson.databind.*; |
||||||
|
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; |
||||||
|
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; |
||||||
|
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; |
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; |
||||||
|
import org.springframework.context.annotation.Bean; |
||||||
|
import org.springframework.context.annotation.Configuration; |
||||||
|
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
import java.time.LocalDateTime; |
||||||
|
import java.time.format.DateTimeFormatter; |
||||||
|
|
||||||
|
@Configuration |
||||||
|
public class SpringBeanConfiguration { |
||||||
|
|
||||||
|
@Bean |
||||||
|
@ConditionalOnMissingBean(ObjectMapper.class) |
||||||
|
public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) { |
||||||
|
ObjectMapper objectMapper = builder.createXmlMapper(false).build(); |
||||||
|
objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE); |
||||||
|
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY); |
||||||
|
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); |
||||||
|
|
||||||
|
JavaTimeModule timeModule = new JavaTimeModule(); |
||||||
|
timeModule.addDeserializer(LocalDateTime.class, |
||||||
|
new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); |
||||||
|
timeModule.addSerializer(LocalDateTime.class, |
||||||
|
new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); |
||||||
|
|
||||||
|
objectMapper.disable(MapperFeature.IGNORE_DUPLICATE_MODULE_REGISTRATIONS); |
||||||
|
objectMapper.registerModules(timeModule); |
||||||
|
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); |
||||||
|
objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true); |
||||||
|
objectMapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true); |
||||||
|
objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() { |
||||||
|
@Override |
||||||
|
public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException { |
||||||
|
gen.writeString(""); |
||||||
|
} |
||||||
|
}); |
||||||
|
return objectMapper; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,53 @@ |
|||||||
|
package com.dji.sample.manage.controller; |
||||||
|
|
||||||
|
import com.dji.sample.common.model.PaginationData; |
||||||
|
import com.dji.sample.common.model.ResponseResult; |
||||||
|
import com.dji.sample.manage.model.dto.DeviceHmsDTO; |
||||||
|
import com.dji.sample.manage.model.param.DeviceHmsQueryParam; |
||||||
|
import com.dji.sample.manage.service.IDeviceHmsService; |
||||||
|
import lombok.extern.slf4j.Slf4j; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.web.bind.annotation.*; |
||||||
|
|
||||||
|
import java.util.HashSet; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Set; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 1.1 |
||||||
|
* @date 2022/7/7 |
||||||
|
*/ |
||||||
|
|
||||||
|
@RestController |
||||||
|
@Slf4j |
||||||
|
@RequestMapping("${url.manage.prefix}${url.manage.version}/devices") |
||||||
|
public class DeviceHmsController { |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private IDeviceHmsService deviceHmsService; |
||||||
|
|
||||||
|
@GetMapping("/{workspace_id}/devices/hms") |
||||||
|
public ResponseResult<PaginationData<DeviceHmsDTO>> getBoundDevicesWithDomain(DeviceHmsQueryParam param, |
||||||
|
@PathVariable("workspace_id") String workspaceId) { |
||||||
|
PaginationData<DeviceHmsDTO> devices = deviceHmsService.getDeviceHmsByParam(param); |
||||||
|
|
||||||
|
return ResponseResult.success(devices); |
||||||
|
} |
||||||
|
|
||||||
|
@PutMapping("/{workspace_id}/devices/hms/{device_sn}") |
||||||
|
public ResponseResult updateReadHmsByDeviceSn(@PathVariable("device_sn") String deviceSn) { |
||||||
|
deviceHmsService.updateUnreadHms(deviceSn); |
||||||
|
return ResponseResult.success(); |
||||||
|
} |
||||||
|
|
||||||
|
@GetMapping("/{workspace_id}/devices/hms/{device_sn}") |
||||||
|
public ResponseResult<List<DeviceHmsDTO>> getUnreadHmsByDeviceSn(@PathVariable("device_sn") String deviceSn) { |
||||||
|
PaginationData<DeviceHmsDTO> paginationData = deviceHmsService.getDeviceHmsByParam( |
||||||
|
DeviceHmsQueryParam.builder() |
||||||
|
.deviceSn(new HashSet<>(Set.of(deviceSn))) |
||||||
|
.updateTime(0L) |
||||||
|
.build()); |
||||||
|
return ResponseResult.success(paginationData.getList()); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,12 @@ |
|||||||
|
package com.dji.sample.manage.dao; |
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
||||||
|
import com.dji.sample.manage.model.entity.DeviceHmsEntity; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 1.1 |
||||||
|
* @date 2022/7/6 |
||||||
|
*/ |
||||||
|
public interface IDeviceHmsMapper extends BaseMapper<DeviceHmsEntity> { |
||||||
|
} |
@ -0,0 +1,49 @@ |
|||||||
|
package com.dji.sample.manage.model.common; |
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode; |
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper; |
||||||
|
import lombok.extern.slf4j.Slf4j; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.core.io.ClassPathResource; |
||||||
|
import org.springframework.stereotype.Component; |
||||||
|
|
||||||
|
import javax.annotation.PostConstruct; |
||||||
|
import java.io.IOException; |
||||||
|
import java.io.InputStream; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 1.1 |
||||||
|
* @date 2022/7/7 |
||||||
|
*/ |
||||||
|
@Slf4j |
||||||
|
@Component |
||||||
|
public class HmsJsonUtil { |
||||||
|
|
||||||
|
private static ObjectMapper mapper; |
||||||
|
|
||||||
|
@Autowired |
||||||
|
public void setMapper(ObjectMapper mapper) { |
||||||
|
HmsJsonUtil.mapper = mapper; |
||||||
|
} |
||||||
|
|
||||||
|
private static JsonNode nodes; |
||||||
|
|
||||||
|
private HmsJsonUtil(){ |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@PostConstruct |
||||||
|
private void loadJsonFile() { |
||||||
|
try (InputStream inputStream = new ClassPathResource("hms.json").getInputStream()){ |
||||||
|
nodes = mapper.readTree(inputStream); |
||||||
|
} catch (IOException e) { |
||||||
|
log.error("hms.json failed to load."); |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static HmsMessage get(String key) { |
||||||
|
return mapper.convertValue(nodes.get(key), HmsMessage.class); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,16 @@ |
|||||||
|
package com.dji.sample.manage.model.common; |
||||||
|
|
||||||
|
import lombok.Data; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 1.1 |
||||||
|
* @date 2022/7/7 |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
public class HmsMessage { |
||||||
|
|
||||||
|
private String zh; |
||||||
|
|
||||||
|
private String en; |
||||||
|
} |
@ -0,0 +1,57 @@ |
|||||||
|
package com.dji.sample.manage.model.dto; |
||||||
|
|
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import lombok.Builder; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.NoArgsConstructor; |
||||||
|
|
||||||
|
import java.time.LocalDateTime; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 1.1 |
||||||
|
* @date 2022/7/8 |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
@AllArgsConstructor |
||||||
|
@NoArgsConstructor |
||||||
|
@Builder |
||||||
|
public class DeviceHmsDTO implements Cloneable { |
||||||
|
|
||||||
|
private String hmsId; |
||||||
|
|
||||||
|
private String tid; |
||||||
|
|
||||||
|
private String bid; |
||||||
|
|
||||||
|
private String sn; |
||||||
|
|
||||||
|
private Integer level; |
||||||
|
|
||||||
|
private Integer module; |
||||||
|
|
||||||
|
private String key; |
||||||
|
|
||||||
|
private String messageZh; |
||||||
|
|
||||||
|
private String messageEn; |
||||||
|
|
||||||
|
private LocalDateTime createTime; |
||||||
|
|
||||||
|
private LocalDateTime updateTime; |
||||||
|
|
||||||
|
@Override |
||||||
|
public DeviceHmsDTO clone() { |
||||||
|
try { |
||||||
|
return (DeviceHmsDTO) super.clone(); |
||||||
|
} catch (CloneNotSupportedException e) { |
||||||
|
return DeviceHmsDTO.builder() |
||||||
|
.sn(this.sn) |
||||||
|
.bid(this.bid) |
||||||
|
.tid(this.tid) |
||||||
|
.createTime(this.createTime) |
||||||
|
.updateTime(this.updateTime) |
||||||
|
.build(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,34 @@ |
|||||||
|
package com.dji.sample.manage.model.dto; |
||||||
|
|
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import lombok.Builder; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.NoArgsConstructor; |
||||||
|
|
||||||
|
import java.time.LocalDateTime; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 1.0 |
||||||
|
* @date 2022/4/18 |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
@Builder |
||||||
|
@AllArgsConstructor |
||||||
|
@NoArgsConstructor |
||||||
|
public class UserListDTO { |
||||||
|
|
||||||
|
private String userId; |
||||||
|
|
||||||
|
private String username; |
||||||
|
|
||||||
|
private String workspaceName; |
||||||
|
|
||||||
|
private String userType; |
||||||
|
|
||||||
|
private String mqttUsername; |
||||||
|
|
||||||
|
private String mqttPassword; |
||||||
|
|
||||||
|
private LocalDateTime createTime; |
||||||
|
} |
@ -0,0 +1,76 @@ |
|||||||
|
package com.dji.sample.manage.model.entity; |
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType; |
||||||
|
import com.baomidou.mybatisplus.annotation.TableField; |
||||||
|
import com.baomidou.mybatisplus.annotation.TableId; |
||||||
|
import com.baomidou.mybatisplus.annotation.TableName; |
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import lombok.Builder; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.NoArgsConstructor; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 1.1 |
||||||
|
* @date 2022/7/6 |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
@Builder |
||||||
|
@NoArgsConstructor |
||||||
|
@AllArgsConstructor |
||||||
|
@TableName(value = "manage_device_hms") |
||||||
|
public class DeviceHmsEntity implements Serializable, Cloneable { |
||||||
|
|
||||||
|
@TableId(value = "id", type = IdType.AUTO) |
||||||
|
private Long id; |
||||||
|
|
||||||
|
@TableField("hms_id") |
||||||
|
private String hmsId; |
||||||
|
|
||||||
|
@TableField("tid") |
||||||
|
private String tid; |
||||||
|
|
||||||
|
@TableField("bid") |
||||||
|
private String bid; |
||||||
|
|
||||||
|
@TableField("sn") |
||||||
|
private String sn; |
||||||
|
|
||||||
|
@TableField("level") |
||||||
|
private Integer level; |
||||||
|
|
||||||
|
@TableField("module") |
||||||
|
private Integer module; |
||||||
|
|
||||||
|
@TableField("hms_key") |
||||||
|
private String hmsKey; |
||||||
|
|
||||||
|
@TableField("message_zh") |
||||||
|
private String messageZh; |
||||||
|
|
||||||
|
@TableField("message_en") |
||||||
|
private String messageEn; |
||||||
|
|
||||||
|
@TableField("create_time") |
||||||
|
private Long createTime; |
||||||
|
|
||||||
|
@TableField("update_time") |
||||||
|
private Long updateTime; |
||||||
|
|
||||||
|
@Override |
||||||
|
public DeviceHmsEntity clone() { |
||||||
|
try { |
||||||
|
return (DeviceHmsEntity) super.clone(); |
||||||
|
} catch (CloneNotSupportedException e) { |
||||||
|
return DeviceHmsEntity.builder() |
||||||
|
.bid(this.getBid()) |
||||||
|
.tid(this.getTid()) |
||||||
|
.createTime(this.getCreateTime()) |
||||||
|
.updateTime(this.getUpdateTime()) |
||||||
|
.sn(this.getSn()) |
||||||
|
.build(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,155 @@ |
|||||||
|
package com.dji.sample.manage.model.enums; |
||||||
|
|
||||||
|
import lombok.Getter; |
||||||
|
|
||||||
|
import java.util.Arrays; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 1.1 |
||||||
|
* @date 2022/7/7 |
||||||
|
*/ |
||||||
|
@Getter |
||||||
|
public enum HmsEnum { |
||||||
|
|
||||||
|
IN_THE_SKY("_in_the_sky", 1); |
||||||
|
|
||||||
|
private int val; |
||||||
|
|
||||||
|
private String text; |
||||||
|
|
||||||
|
HmsEnum(String text, int val) { |
||||||
|
this.text = text; |
||||||
|
this.val = val; |
||||||
|
} |
||||||
|
|
||||||
|
@Getter |
||||||
|
public enum MessageLanguage { |
||||||
|
|
||||||
|
EN("en"), |
||||||
|
|
||||||
|
ZH("zh"); |
||||||
|
|
||||||
|
String language; |
||||||
|
|
||||||
|
MessageLanguage(String language) { |
||||||
|
this.language = language; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Getter |
||||||
|
public enum DomainType { |
||||||
|
DRONE_NEST("drone_nest"), |
||||||
|
|
||||||
|
DRONE("drone"); |
||||||
|
|
||||||
|
private String domain; |
||||||
|
|
||||||
|
DomainType(String domain) { |
||||||
|
this.domain = domain; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Getter |
||||||
|
public enum HmsFaqIdEnum { |
||||||
|
|
||||||
|
FPV_TIP("fpv_tip_"); |
||||||
|
|
||||||
|
private String text; |
||||||
|
|
||||||
|
HmsFaqIdEnum(String text) { |
||||||
|
this.text = text; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Getter |
||||||
|
public enum HmsBatteryIndexEnum { |
||||||
|
LEFT(0, "left", "左"), |
||||||
|
|
||||||
|
RIGHT(1, "right", "右"), |
||||||
|
|
||||||
|
UNKNOWN(-1, "unknown", "未知"); |
||||||
|
|
||||||
|
private int val; |
||||||
|
|
||||||
|
private String en; |
||||||
|
|
||||||
|
private String zh; |
||||||
|
|
||||||
|
HmsBatteryIndexEnum(int val, String en, String zh) { |
||||||
|
this.val = val; |
||||||
|
this.en = en; |
||||||
|
this.zh = zh; |
||||||
|
} |
||||||
|
|
||||||
|
public static HmsBatteryIndexEnum find(int val) { |
||||||
|
return Arrays.stream(HmsBatteryIndexEnum.values()) |
||||||
|
.filter(battery -> battery.val == val) |
||||||
|
.findAny() |
||||||
|
.orElse(UNKNOWN); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Getter |
||||||
|
public enum HmsDockCoverIndexEnum { |
||||||
|
LEFT(0, "left", "左"), |
||||||
|
|
||||||
|
RIGHT(1, "right", "右"), |
||||||
|
|
||||||
|
UNKNOWN(-1, "unknown", "未知"); |
||||||
|
|
||||||
|
private int val; |
||||||
|
|
||||||
|
private String en; |
||||||
|
|
||||||
|
private String zh; |
||||||
|
|
||||||
|
HmsDockCoverIndexEnum(int val, String en, String zh) { |
||||||
|
this.val = val; |
||||||
|
this.en = en; |
||||||
|
this.zh = zh; |
||||||
|
} |
||||||
|
|
||||||
|
public static HmsDockCoverIndexEnum find(int val) { |
||||||
|
return Arrays.stream(HmsDockCoverIndexEnum.values()) |
||||||
|
.filter(dockCover -> dockCover.val == val) |
||||||
|
.findAny() |
||||||
|
.orElse(UNKNOWN); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Getter |
||||||
|
public enum HmsChargingRodIndexEnum { |
||||||
|
|
||||||
|
FRONT(0, "front", "前"), |
||||||
|
|
||||||
|
BACK(1, "back", "后"), |
||||||
|
|
||||||
|
LEFT(2, "left", "左"), |
||||||
|
|
||||||
|
RIGHT(3, "right", "右"), |
||||||
|
|
||||||
|
UNKNOWN(-1, "unknown", "未知"); |
||||||
|
|
||||||
|
private int val; |
||||||
|
|
||||||
|
private String en; |
||||||
|
|
||||||
|
private String zh; |
||||||
|
|
||||||
|
HmsChargingRodIndexEnum(int val, String en, String zh) { |
||||||
|
this.val = val; |
||||||
|
this.en = en; |
||||||
|
this.zh = zh; |
||||||
|
} |
||||||
|
|
||||||
|
public static HmsChargingRodIndexEnum find(int val) { |
||||||
|
return Arrays.stream(HmsChargingRodIndexEnum.values()) |
||||||
|
.filter(rod -> rod.val == val) |
||||||
|
.findAny() |
||||||
|
.orElse(UNKNOWN); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,61 @@ |
|||||||
|
package com.dji.sample.manage.model.enums; |
||||||
|
|
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.List; |
||||||
|
import java.util.stream.Collectors; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 1.0 |
||||||
|
* @date 2022/4/29 |
||||||
|
*/ |
||||||
|
public enum PayloadModelEnum { |
||||||
|
|
||||||
|
Z30("Z30", "20-0"), |
||||||
|
|
||||||
|
XT2("XT2", "26-0"), |
||||||
|
|
||||||
|
XTS("XTS", "41-0"), |
||||||
|
|
||||||
|
H20("H20", "42-0"), |
||||||
|
|
||||||
|
H20T("H20T", "43-0"), |
||||||
|
|
||||||
|
P1("P1", "50-65535"), |
||||||
|
|
||||||
|
M30("M30", "52-0"), |
||||||
|
|
||||||
|
M30T("M30T", "53-0"), |
||||||
|
|
||||||
|
H20N("H20N", "61-0"), |
||||||
|
|
||||||
|
DOCK("DOCK", "165-0"), |
||||||
|
|
||||||
|
L1("L1", "90742-0"); |
||||||
|
|
||||||
|
private String model; |
||||||
|
|
||||||
|
private String index; |
||||||
|
|
||||||
|
PayloadModelEnum(String model, String index) { |
||||||
|
this.model = model; |
||||||
|
this.index = index; |
||||||
|
} |
||||||
|
|
||||||
|
public String getModel() { |
||||||
|
return model; |
||||||
|
} |
||||||
|
|
||||||
|
public String getIndex() { |
||||||
|
return index; |
||||||
|
} |
||||||
|
|
||||||
|
public static List<String> getAllModel() { |
||||||
|
return Arrays.stream(PayloadModelEnum.values()).map(PayloadModelEnum::getModel).collect(Collectors.toList()); |
||||||
|
} |
||||||
|
|
||||||
|
public static List<String> getAllIndex() { |
||||||
|
return Arrays.stream(PayloadModelEnum.values()).map(PayloadModelEnum::getIndex).collect(Collectors.toList()); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,45 @@ |
|||||||
|
package com.dji.sample.manage.model.param; |
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty; |
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import lombok.Builder; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.NoArgsConstructor; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
import java.util.Set; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 1.1 |
||||||
|
* @date 2022/7/8 |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
@Builder |
||||||
|
@AllArgsConstructor |
||||||
|
@NoArgsConstructor |
||||||
|
public class DeviceHmsQueryParam implements Serializable { |
||||||
|
|
||||||
|
@JsonProperty("device_sn") |
||||||
|
private Set<String> deviceSn; |
||||||
|
|
||||||
|
@JsonProperty("begin_time") |
||||||
|
private Long beginTime; |
||||||
|
|
||||||
|
@JsonProperty("end_time") |
||||||
|
private Long endTime; |
||||||
|
|
||||||
|
private String language; |
||||||
|
|
||||||
|
private String message; |
||||||
|
|
||||||
|
private Long page; |
||||||
|
|
||||||
|
@JsonProperty("page_size") |
||||||
|
private Long pageSize; |
||||||
|
|
||||||
|
private Integer level; |
||||||
|
|
||||||
|
@JsonProperty("update_time") |
||||||
|
private Long updateTime; |
||||||
|
} |
@ -0,0 +1,18 @@ |
|||||||
|
package com.dji.sample.manage.model.receiver; |
||||||
|
|
||||||
|
import lombok.Data; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 1.0 |
||||||
|
* @date 2022/5/11 |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
public class AlternateLandPointReceiver { |
||||||
|
|
||||||
|
private Double latitude; |
||||||
|
|
||||||
|
private Double longitude; |
||||||
|
|
||||||
|
private Double safeLandHeight; |
||||||
|
} |
@ -0,0 +1,22 @@ |
|||||||
|
package com.dji.sample.manage.model.receiver; |
||||||
|
|
||||||
|
import lombok.Data; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 1.1 |
||||||
|
* @date 2022/6/13 |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
public class BindDeviceReceiver { |
||||||
|
|
||||||
|
private String deviceBindingCode; |
||||||
|
|
||||||
|
private String organizationId; |
||||||
|
|
||||||
|
private String deviceCallsign; |
||||||
|
|
||||||
|
private String sn; |
||||||
|
|
||||||
|
private String deviceModelKey; |
||||||
|
} |
@ -0,0 +1,30 @@ |
|||||||
|
package com.dji.sample.manage.model.receiver; |
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude; |
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import lombok.Builder; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.NoArgsConstructor; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 1.1 |
||||||
|
* @date 2022/6/14 |
||||||
|
*/ |
||||||
|
@Builder |
||||||
|
@Data |
||||||
|
@AllArgsConstructor |
||||||
|
@NoArgsConstructor |
||||||
|
@JsonInclude |
||||||
|
public class BindStatusReceiver { |
||||||
|
|
||||||
|
private String sn; |
||||||
|
|
||||||
|
private Boolean isDeviceBindOrganization; |
||||||
|
|
||||||
|
private String organizationId; |
||||||
|
|
||||||
|
private String organizationName; |
||||||
|
|
||||||
|
private String deviceCallsign; |
||||||
|
} |
@ -0,0 +1,28 @@ |
|||||||
|
package com.dji.sample.manage.model.receiver; |
||||||
|
|
||||||
|
import lombok.Data; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 1.1 |
||||||
|
* @date 2022/7/6 |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
public class DeviceHmsReceiver { |
||||||
|
|
||||||
|
private String code; |
||||||
|
|
||||||
|
private String deviceType; |
||||||
|
|
||||||
|
private String domainType; |
||||||
|
|
||||||
|
private Integer imminent; |
||||||
|
|
||||||
|
private Integer inTheSky; |
||||||
|
|
||||||
|
private Integer level; |
||||||
|
|
||||||
|
private Integer module; |
||||||
|
|
||||||
|
private HmsArgsReceiver args; |
||||||
|
} |
@ -0,0 +1,14 @@ |
|||||||
|
package com.dji.sample.manage.model.receiver; |
||||||
|
|
||||||
|
import lombok.Data; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 1.1 |
||||||
|
* @date 2022/6/17 |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
public class DockMediaFileDetailReceiver { |
||||||
|
|
||||||
|
private Integer remainUpload; |
||||||
|
} |
@ -0,0 +1,18 @@ |
|||||||
|
package com.dji.sample.manage.model.receiver; |
||||||
|
|
||||||
|
import lombok.Data; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 1.1 |
||||||
|
* @date 2022/6/17 |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
public class DockSdrReceiver { |
||||||
|
|
||||||
|
private Integer downQuality; |
||||||
|
|
||||||
|
private Double frequencyBand; |
||||||
|
|
||||||
|
private Integer upQuality; |
||||||
|
} |
@ -0,0 +1,20 @@ |
|||||||
|
package com.dji.sample.manage.model.receiver; |
||||||
|
|
||||||
|
import lombok.Data; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 1.0 |
||||||
|
* @date 2022/5/11 |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
public class DockSubDeviceReceiver { |
||||||
|
|
||||||
|
private String deviceSn; |
||||||
|
|
||||||
|
private Integer deviceOnlineStatus; |
||||||
|
|
||||||
|
private Integer devicePaired; |
||||||
|
|
||||||
|
private String deviceModelKey; |
||||||
|
} |
@ -0,0 +1,16 @@ |
|||||||
|
package com.dji.sample.manage.model.receiver; |
||||||
|
|
||||||
|
import lombok.Data; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 1.0 |
||||||
|
* @date 2022/5/11 |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
public class DroneChargeStateReceiver { |
||||||
|
|
||||||
|
private Integer state; |
||||||
|
|
||||||
|
private Integer capacityPercent; |
||||||
|
} |
@ -0,0 +1,29 @@ |
|||||||
|
package com.dji.sample.manage.model.receiver; |
||||||
|
|
||||||
|
import com.dji.sample.manage.model.enums.DeviceDomainEnum; |
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import lombok.Builder; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.NoArgsConstructor; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 1.0 |
||||||
|
* @date 2022/4/28 |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
@Builder |
||||||
|
@AllArgsConstructor |
||||||
|
@NoArgsConstructor |
||||||
|
public class FirmwareVersionReceiver { |
||||||
|
|
||||||
|
private String firmwareVersion; |
||||||
|
|
||||||
|
private Integer compatibleStatus; |
||||||
|
|
||||||
|
private Integer firmwareUpgradeStatus; |
||||||
|
|
||||||
|
private String sn; |
||||||
|
|
||||||
|
private DeviceDomainEnum domain; |
||||||
|
} |
@ -0,0 +1,18 @@ |
|||||||
|
package com.dji.sample.manage.model.receiver; |
||||||
|
|
||||||
|
import lombok.Data; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author sean |
||||||
|
* @version 1.1 |
||||||
|
* @date 2022/7/6 |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
public class HmsArgsReceiver { |
||||||
|
|
||||||
|
private Long componentIndex; |
||||||
|
|
||||||
|
private Integer sensorIndex; |
||||||
|
|
||||||
|
private Integer alarmId; |
||||||
|
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue