sean.zhou
2 years ago
101 changed files with 21739 additions and 174 deletions
@ -0,0 +1,46 @@
@@ -0,0 +1,46 @@
|
||||
package com.dji.sample.component.mqtt.handler; |
||||
|
||||
import com.dji.sample.component.mqtt.model.*; |
||||
import com.dji.sample.manage.model.receiver.LogsFileUploadList; |
||||
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.ServiceActivator; |
||||
import org.springframework.messaging.Message; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
import java.io.IOException; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/9/9 |
||||
*/ |
||||
@Component |
||||
public class ServicesReplyHandler { |
||||
|
||||
@Autowired |
||||
private ObjectMapper mapper; |
||||
|
||||
/** |
||||
* Handle the reply message from the pilot side to the on-demand video. |
||||
* @param message reply message |
||||
* @throws IOException |
||||
*/ |
||||
@ServiceActivator(inputChannel = ChannelName.INBOUND_SERVICE_REPLY) |
||||
public void serviceReply(Message<?> message) throws IOException { |
||||
byte[] payload = (byte[])message.getPayload(); |
||||
|
||||
CommonTopicReceiver receiver = mapper.readValue(payload, new TypeReference<CommonTopicReceiver>() {}); |
||||
if (ServicesMethodEnum.FILE_UPLOAD_LIST.getMethod().equals(receiver.getMethod())) { |
||||
LogsFileUploadList list = mapper.convertValue(receiver.getData(), new TypeReference<LogsFileUploadList>() {}); |
||||
receiver.setData(list); |
||||
} else { |
||||
ServiceReply reply = mapper.convertValue(receiver.getData(), new TypeReference<ServiceReply>() {}); |
||||
receiver.setData(reply); |
||||
} |
||||
Chan<CommonTopicReceiver<?>> chan = Chan.getInstance(); |
||||
// Put the message to the chan object.
|
||||
chan.put(receiver); |
||||
} |
||||
} |
@ -0,0 +1,16 @@
@@ -0,0 +1,16 @@
|
||||
package com.dji.sample.component.mqtt.model; |
||||
|
||||
import lombok.Data; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/7/29 |
||||
*/ |
||||
@Data |
||||
public class EventsOutputReceiver { |
||||
|
||||
private String status; |
||||
|
||||
private OutputProgressReceiver progress; |
||||
} |
@ -0,0 +1,47 @@
@@ -0,0 +1,47 @@
|
||||
package com.dji.sample.component.mqtt.model; |
||||
|
||||
import lombok.Getter; |
||||
|
||||
import java.util.Arrays; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/8/17 |
||||
*/ |
||||
@Getter |
||||
public enum EventsResultStatusEnum { |
||||
|
||||
SENT("sent", false), |
||||
|
||||
IN_PROGRESS("in_progress", false), |
||||
|
||||
OK("ok", true), |
||||
|
||||
PAUSED("paused", false), |
||||
|
||||
REJECTED("rejected", true), |
||||
|
||||
FAILED("failed", true), |
||||
|
||||
CANCELED("canceled", true), |
||||
|
||||
TIMEOUT("timeout", true), |
||||
|
||||
UNKNOWN("unknown", false); |
||||
|
||||
String desc; |
||||
|
||||
Boolean end; |
||||
|
||||
EventsResultStatusEnum(String desc, Boolean end) { |
||||
this.desc = desc; |
||||
this.end = end; |
||||
} |
||||
|
||||
public static EventsResultStatusEnum find(String desc) { |
||||
return Arrays.stream(EventsResultStatusEnum.values()) |
||||
.filter(status -> status.desc.equals(desc)) |
||||
.findFirst().orElse(UNKNOWN); |
||||
} |
||||
} |
@ -0,0 +1,18 @@
@@ -0,0 +1,18 @@
|
||||
package com.dji.sample.component.mqtt.model; |
||||
|
||||
import lombok.Data; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/7/29 |
||||
*/ |
||||
@Data |
||||
public class OutputProgressReceiver { |
||||
|
||||
private Integer percent; |
||||
|
||||
private String stepKey; |
||||
|
||||
private Integer stepResult; |
||||
} |
@ -0,0 +1,33 @@
@@ -0,0 +1,33 @@
|
||||
package com.dji.sample.configuration.mvc; |
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.web.bind.WebDataBinder; |
||||
import org.springframework.web.context.request.NativeWebRequest; |
||||
import org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/9/16 |
||||
*/ |
||||
public class GetSnakeArgumentProcessor extends ServletModelAttributeMethodProcessor { |
||||
|
||||
@Autowired |
||||
private GetSnakeDataBinder snakeDataBinder; |
||||
|
||||
/** |
||||
* Class constructor. |
||||
* |
||||
* @param annotationNotRequired if "true", non-simple method arguments and |
||||
* return values are considered model attributes with or without a |
||||
* {@code @ModelAttribute} annotation |
||||
*/ |
||||
public GetSnakeArgumentProcessor(boolean annotationNotRequired) { |
||||
super(annotationNotRequired); |
||||
} |
||||
|
||||
@Override |
||||
protected void bindRequestParameters(WebDataBinder binder, NativeWebRequest request) { |
||||
super.bindRequestParameters(new GetSnakeDataBinder(binder.getTarget(), binder.getObjectName()), request); |
||||
} |
||||
} |
@ -0,0 +1,53 @@
@@ -0,0 +1,53 @@
|
||||
package com.dji.sample.configuration.mvc; |
||||
|
||||
import org.springframework.beans.MutablePropertyValues; |
||||
import org.springframework.beans.PropertyValue; |
||||
import org.springframework.web.servlet.mvc.method.annotation.ExtendedServletRequestDataBinder; |
||||
|
||||
import javax.servlet.ServletRequest; |
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/9/9 |
||||
*/ |
||||
public class GetSnakeDataBinder extends ExtendedServletRequestDataBinder { |
||||
|
||||
public GetSnakeDataBinder(Object target, String objectName) { |
||||
super(target, objectName); |
||||
} |
||||
|
||||
@Override |
||||
protected void addBindValues(MutablePropertyValues mpvs, ServletRequest request) { |
||||
List<PropertyValue> propertyValueList = mpvs.getPropertyValueList(); |
||||
List<PropertyValue> values = new ArrayList<>(propertyValueList); |
||||
for (PropertyValue property : values) { |
||||
String name = convertSnake(property.getName()); |
||||
if (!property.getName().equals(name)) { |
||||
mpvs.addPropertyValue(new PropertyValue(name, property.getValue())); |
||||
propertyValueList.remove(property); |
||||
} |
||||
} |
||||
super.addBindValues(mpvs, request); |
||||
} |
||||
|
||||
private String convertSnake(String key) { |
||||
StringBuilder sb = new StringBuilder(); |
||||
boolean isChange = false; |
||||
for (char c : key.toCharArray()) { |
||||
if (c == '_') { |
||||
isChange = true; |
||||
continue; |
||||
} |
||||
if (isChange) { |
||||
sb.append((char) (c - 32)); |
||||
isChange = false; |
||||
continue; |
||||
} |
||||
sb.append(c); |
||||
} |
||||
return sb.toString(); |
||||
} |
||||
} |
@ -0,0 +1,30 @@
@@ -0,0 +1,30 @@
|
||||
package com.dji.sample.control.controller; |
||||
|
||||
import com.dji.sample.common.model.ResponseResult; |
||||
import com.dji.sample.control.service.IControlService; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.web.bind.annotation.PathVariable; |
||||
import org.springframework.web.bind.annotation.PostMapping; |
||||
import org.springframework.web.bind.annotation.RequestMapping; |
||||
import org.springframework.web.bind.annotation.RestController; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/7/29 |
||||
*/ |
||||
@RestController |
||||
@Slf4j |
||||
@RequestMapping("${url.control.prefix}${url.control.version}/devices") |
||||
public class DockController { |
||||
|
||||
@Autowired |
||||
private IControlService controlService; |
||||
|
||||
@PostMapping("/{sn}/jobs/{service_identifier}") |
||||
public ResponseResult createControlJob(@PathVariable String sn, |
||||
@PathVariable("service_identifier") String serviceIdentifier) { |
||||
return controlService.controlDock(sn, serviceIdentifier); |
||||
} |
||||
} |
@ -0,0 +1,18 @@
@@ -0,0 +1,18 @@
|
||||
package com.dji.sample.control.service; |
||||
|
||||
import com.dji.sample.common.model.ResponseResult; |
||||
import com.dji.sample.component.mqtt.model.CommonTopicReceiver; |
||||
import org.springframework.messaging.MessageHeaders; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/7/29 |
||||
*/ |
||||
public interface IControlService { |
||||
|
||||
ResponseResult controlDock(String sn, String serviceIdentifier); |
||||
|
||||
void handleControlProgress(CommonTopicReceiver receiver, MessageHeaders headers); |
||||
|
||||
} |
@ -0,0 +1,133 @@
@@ -0,0 +1,133 @@
|
||||
package com.dji.sample.control.service.impl; |
||||
|
||||
import com.dji.sample.common.model.ResponseResult; |
||||
import com.dji.sample.component.mqtt.model.*; |
||||
import com.dji.sample.component.mqtt.service.IMessageSenderService; |
||||
import com.dji.sample.component.redis.RedisConst; |
||||
import com.dji.sample.component.redis.RedisOpsUtils; |
||||
import com.dji.sample.component.websocket.model.CustomWebSocketMessage; |
||||
import com.dji.sample.component.websocket.service.ISendMessageService; |
||||
import com.dji.sample.component.websocket.service.IWebSocketManageService; |
||||
import com.dji.sample.control.service.IControlService; |
||||
import com.dji.sample.manage.model.dto.DeviceDTO; |
||||
import com.dji.sample.manage.model.enums.UserTypeEnum; |
||||
import com.fasterxml.jackson.core.type.TypeReference; |
||||
import com.fasterxml.jackson.databind.ObjectMapper; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.integration.annotation.ServiceActivator; |
||||
import org.springframework.integration.mqtt.support.MqttHeaders; |
||||
import org.springframework.messaging.MessageHeaders; |
||||
import org.springframework.stereotype.Service; |
||||
|
||||
import java.util.Optional; |
||||
import java.util.UUID; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/7/29 |
||||
*/ |
||||
@Service |
||||
@Slf4j |
||||
public class ControlServiceImpl implements IControlService { |
||||
|
||||
@Autowired |
||||
private RedisOpsUtils redisOps; |
||||
|
||||
@Autowired |
||||
private IMessageSenderService messageSenderService; |
||||
|
||||
@Autowired |
||||
private ISendMessageService webSocketMessageService; |
||||
|
||||
@Autowired |
||||
private IWebSocketManageService webSocketManageService; |
||||
|
||||
@Autowired |
||||
private ObjectMapper mapper; |
||||
|
||||
@Override |
||||
public ResponseResult controlDock(String sn, String serviceIdentifier) { |
||||
ServicesMethodEnum servicesMethodEnum = ServicesMethodEnum.find(serviceIdentifier); |
||||
if (servicesMethodEnum == ServicesMethodEnum.UNKNOWN) { |
||||
return ResponseResult.error("The " + serviceIdentifier + " method does not exist."); |
||||
} |
||||
boolean isExist = redisOps.getExpire(RedisConst.DEVICE_ONLINE_PREFIX + sn) > 0; |
||||
if (!isExist) { |
||||
return ResponseResult.error("The dock is offline."); |
||||
} |
||||
String topic = TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + sn + TopicConst.SERVICES_SUF; |
||||
String bid = UUID.randomUUID().toString(); |
||||
Optional<ServiceReply> serviceReplyOpt = messageSenderService.publishWithReply( |
||||
topic, CommonTopicResponse.builder() |
||||
.tid(UUID.randomUUID().toString()) |
||||
.bid(bid) |
||||
.method(serviceIdentifier) |
||||
.timestamp(System.currentTimeMillis()) |
||||
.data("") |
||||
.build()); |
||||
if (serviceReplyOpt.isEmpty()) { |
||||
return ResponseResult.error("No message reply received."); |
||||
} |
||||
ServiceReply<EventsOutputReceiver> serviceReply = mapper.convertValue( |
||||
serviceReplyOpt.get(), new TypeReference<ServiceReply<EventsOutputReceiver>>() {}); |
||||
if (serviceReply.getResult() != ResponseResult.CODE_SUCCESS) { |
||||
return ResponseResult.error(serviceReply.getResult(), serviceReply.getOutput().getStatus()); |
||||
} |
||||
if (servicesMethodEnum.getProgress()) { |
||||
redisOps.setWithExpire(serviceIdentifier + RedisConst.DELIMITER + bid, sn, |
||||
RedisConst.DEVICE_ALIVE_SECOND * RedisConst.DEVICE_ALIVE_SECOND); |
||||
} |
||||
return ResponseResult.success(); |
||||
} |
||||
|
||||
@Override |
||||
@ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS, outputChannel = ChannelName.OUTBOUND) |
||||
public void handleControlProgress(CommonTopicReceiver receiver, MessageHeaders headers) { |
||||
String key = receiver.getMethod() + RedisConst.DELIMITER + receiver.getBid(); |
||||
if (redisOps.getExpire(key) <= 0) { |
||||
return; |
||||
} |
||||
String sn = redisOps.get(key).toString(); |
||||
|
||||
EventsReceiver<EventsOutputReceiver> eventsReceiver = mapper.convertValue(receiver.getData(), |
||||
new TypeReference<EventsReceiver<EventsOutputReceiver>>(){}); |
||||
eventsReceiver.setBid(receiver.getBid()); |
||||
eventsReceiver.setSn(sn); |
||||
|
||||
log.info("SN: {}, {} ===> Control progress: {}", |
||||
sn, receiver.getMethod(), eventsReceiver.getOutput().getProgress().toString()); |
||||
|
||||
if (eventsReceiver.getResult() != ResponseResult.CODE_SUCCESS) { |
||||
log.error("SN: {}, {} ===> Error code: {}", sn, receiver.getMethod(), eventsReceiver.getResult()); |
||||
} |
||||
|
||||
if (eventsReceiver.getOutput().getProgress().getPercent() == 100 || |
||||
EventsResultStatusEnum.find(eventsReceiver.getOutput().getStatus()).getEnd()) { |
||||
redisOps.del(key); |
||||
} |
||||
|
||||
DeviceDTO device = (DeviceDTO) redisOps.get(RedisConst.DEVICE_ONLINE_PREFIX + sn); |
||||
webSocketMessageService.sendBatch( |
||||
webSocketManageService.getValueWithWorkspaceAndUserType( |
||||
device.getWorkspaceId(), UserTypeEnum.WEB.getVal()), |
||||
CustomWebSocketMessage.builder() |
||||
.data(eventsReceiver) |
||||
.timestamp(System.currentTimeMillis()) |
||||
.bizCode(receiver.getMethod()) |
||||
.build()); |
||||
|
||||
if (receiver.getNeedReply() != null && receiver.getNeedReply() == 1) { |
||||
String topic = headers.get(MqttHeaders.RECEIVED_TOPIC) + TopicConst._REPLY_SUF; |
||||
messageSenderService.publish(topic, |
||||
CommonTopicResponse.builder() |
||||
.tid(receiver.getTid()) |
||||
.bid(receiver.getBid()) |
||||
.method(receiver.getMethod()) |
||||
.timestamp(System.currentTimeMillis()) |
||||
.data(ResponseResult.success()) |
||||
.build()); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,43 @@
@@ -0,0 +1,43 @@
|
||||
package com.dji.sample.manage.controller; |
||||
|
||||
import com.dji.sample.common.model.ResponseResult; |
||||
import com.dji.sample.manage.model.dto.DeviceFirmwareNoteDTO; |
||||
import com.dji.sample.manage.service.IDeviceFirmwareService; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.web.bind.annotation.GetMapping; |
||||
import org.springframework.web.bind.annotation.RequestMapping; |
||||
import org.springframework.web.bind.annotation.RequestParam; |
||||
import org.springframework.web.bind.annotation.RestController; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
import java.util.Optional; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/8/16 |
||||
*/ |
||||
@RestController |
||||
@RequestMapping("${url.manage.prefix}${url.manage.version}/workspaces") |
||||
public class DeviceFirmwareController { |
||||
|
||||
@Autowired |
||||
private IDeviceFirmwareService service; |
||||
|
||||
/** |
||||
* Get the latest firmware version information for this device model. |
||||
* @param deviceNames |
||||
* @return |
||||
*/ |
||||
@GetMapping("/firmware-release-notes/latest") |
||||
public ResponseResult<List<DeviceFirmwareNoteDTO>> getLatestFirmwareNote(@RequestParam("device_name") List<String> deviceNames) { |
||||
List<DeviceFirmwareNoteDTO> releaseNotes = new ArrayList<>(); |
||||
deviceNames.forEach(deviceName -> { |
||||
Optional<DeviceFirmwareNoteDTO> latestFirmware = service.getLatestFirmwareReleaseNote(deviceName); |
||||
latestFirmware.ifPresent(releaseNotes::add); |
||||
}); |
||||
return ResponseResult.success(releaseNotes); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,122 @@
@@ -0,0 +1,122 @@
|
||||
package com.dji.sample.manage.controller; |
||||
|
||||
import com.dji.sample.common.model.CustomClaim; |
||||
import com.dji.sample.common.model.PaginationData; |
||||
import com.dji.sample.common.model.ResponseResult; |
||||
import com.dji.sample.manage.model.dto.DeviceLogsDTO; |
||||
import com.dji.sample.manage.model.param.DeviceLogsCreateParam; |
||||
import com.dji.sample.manage.model.param.DeviceLogsQueryParam; |
||||
import com.dji.sample.manage.model.param.LogsFileUpdateParam; |
||||
import com.dji.sample.manage.service.IDeviceLogsService; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.web.bind.annotation.*; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.net.URL; |
||||
import java.util.List; |
||||
|
||||
import static com.dji.sample.component.AuthInterceptor.TOKEN_CLAIM; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/9/7 |
||||
*/ |
||||
@RestController |
||||
@Slf4j |
||||
@RequestMapping("${url.manage.prefix}${url.manage.version}/workspaces") |
||||
public class DeviceLogsController { |
||||
|
||||
@Autowired |
||||
private IDeviceLogsService deviceLogsService; |
||||
|
||||
/** |
||||
* Obtain the device upload log list by paging according to the query parameters. |
||||
* @param workspaceId |
||||
* @param deviceSn |
||||
* @param param |
||||
* @return |
||||
*/ |
||||
@GetMapping("/{workspace_id}/devices/{device_sn}/logs-uploaded") |
||||
public ResponseResult getUploadedLogs(DeviceLogsQueryParam param, @PathVariable("workspace_id") String workspaceId, |
||||
@PathVariable("device_sn") String deviceSn) { |
||||
PaginationData<DeviceLogsDTO> data = deviceLogsService.getUploadedLogs(deviceSn, param); |
||||
return ResponseResult.success(data); |
||||
} |
||||
|
||||
/** |
||||
* Get a list of log files that can be uploaded in real time. |
||||
* @param workspaceId |
||||
* @param deviceSn |
||||
* @param domainList |
||||
* @return |
||||
*/ |
||||
@GetMapping("/{workspace_id}/devices/{device_sn}/logs") |
||||
public ResponseResult getLogsBySn(@PathVariable("workspace_id") String workspaceId, |
||||
@PathVariable("device_sn") String deviceSn, |
||||
@RequestParam("domain_list") List<String> domainList) { |
||||
return deviceLogsService.getRealTimeLogs(deviceSn, domainList); |
||||
} |
||||
|
||||
/** |
||||
* Initiate a log upload request to the gateway. |
||||
* @return |
||||
*/ |
||||
@PostMapping("/{workspace_id}/devices/{device_sn}/logs") |
||||
public ResponseResult uploadLogs(@PathVariable("workspace_id") String workspaceId, |
||||
@PathVariable("device_sn") String deviceSn, |
||||
HttpServletRequest request, @RequestBody DeviceLogsCreateParam param) { |
||||
|
||||
CustomClaim customClaim = (CustomClaim)request.getAttribute(TOKEN_CLAIM); |
||||
|
||||
return deviceLogsService.pushFileUpload(customClaim.getUsername(), deviceSn, param); |
||||
} |
||||
|
||||
/** |
||||
* Cancel logs file upload. |
||||
* @return |
||||
*/ |
||||
@DeleteMapping("/{workspace_id}/devices/{device_sn}/logs") |
||||
public ResponseResult cancelUploadedLogs(@PathVariable("workspace_id") String workspaceId, |
||||
@PathVariable("device_sn") String deviceSn, |
||||
@RequestBody LogsFileUpdateParam param) { |
||||
|
||||
return deviceLogsService.pushUpdateFile(deviceSn, param); |
||||
} |
||||
|
||||
/** |
||||
* Delete upload history. |
||||
* @return |
||||
*/ |
||||
@DeleteMapping("/{workspace_id}/devices/{device_sn}/logs/{logs_id}") |
||||
public ResponseResult deleteUploadedLogs(@PathVariable("workspace_id") String workspaceId, |
||||
@PathVariable("device_sn") String deviceSn, |
||||
@PathVariable("logs_id") String logsId) { |
||||
deviceLogsService.deleteLogs(deviceSn, logsId); |
||||
return ResponseResult.success(); |
||||
} |
||||
/** |
||||
* Query the download address of the file according to the wayline file id, |
||||
* and redirect to this address directly for download. |
||||
* @param workspaceId |
||||
* @param fileId |
||||
* @param logsId |
||||
* @param response |
||||
*/ |
||||
@GetMapping("/{workspace_id}/logs/{logs_id}/url/{file_id}") |
||||
public ResponseResult getFileUrl(@PathVariable(name = "workspace_id") String workspaceId, |
||||
@PathVariable(name = "file_id") String fileId, |
||||
@PathVariable(name = "logs_id") String logsId, HttpServletResponse response) { |
||||
|
||||
try { |
||||
URL url = deviceLogsService.getLogsFileUrl(logsId, fileId); |
||||
return ResponseResult.success(url.toString()); |
||||
} catch (Exception e) { |
||||
log.error("Failed to get the logs file download address."); |
||||
e.printStackTrace(); |
||||
} |
||||
return ResponseResult.error("Failed to get the logs file download address."); |
||||
} |
||||
} |
@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
|
||||
package com.dji.sample.manage.dao; |
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
||||
import com.dji.sample.manage.model.entity.DeviceFirmwareEntity; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/8/16 |
||||
*/ |
||||
public interface IDeviceFirmwareMapper extends BaseMapper<DeviceFirmwareEntity> { |
||||
} |
@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
|
||||
package com.dji.sample.manage.dao; |
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
||||
import com.dji.sample.manage.model.entity.DeviceLogsEntity; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/9/7 |
||||
*/ |
||||
public interface IDeviceLogsMapper extends BaseMapper<DeviceLogsEntity> { |
||||
} |
@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
|
||||
package com.dji.sample.manage.dao; |
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
||||
import com.dji.sample.manage.model.entity.LogsFileIndexEntity; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/9/8 |
||||
*/ |
||||
public interface ILogsFileIndexMapper extends BaseMapper<LogsFileIndexEntity> { |
||||
} |
@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
|
||||
package com.dji.sample.manage.dao; |
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
||||
import com.dji.sample.manage.model.entity.LogsFileEntity; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/9/7 |
||||
*/ |
||||
public interface ILogsFileMapper extends BaseMapper<LogsFileEntity> { |
||||
} |
@ -0,0 +1,40 @@
@@ -0,0 +1,40 @@
|
||||
package com.dji.sample.manage.model.dto; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import java.time.LocalDate; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/8/16 |
||||
*/ |
||||
@Builder |
||||
@Data |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class DeviceFirmwareDTO { |
||||
|
||||
private String firmwareId; |
||||
|
||||
private String fileName; |
||||
|
||||
private String productVersion; |
||||
|
||||
private String fileUrl; |
||||
|
||||
private Long fileSize; |
||||
|
||||
private String fileMd5; |
||||
|
||||
private String deviceName; |
||||
|
||||
private String releaseNote; |
||||
|
||||
private LocalDate releasedTime; |
||||
|
||||
private Boolean firmwareStatus; |
||||
} |
@ -0,0 +1,28 @@
@@ -0,0 +1,28 @@
|
||||
package com.dji.sample.manage.model.dto; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import java.time.LocalDate; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/8/16 |
||||
*/ |
||||
@Data |
||||
@Builder |
||||
@NoArgsConstructor |
||||
@AllArgsConstructor |
||||
public class DeviceFirmwareNoteDTO { |
||||
|
||||
private String deviceName; |
||||
|
||||
private String productVersion; |
||||
|
||||
private String releaseNote; |
||||
|
||||
private LocalDate releasedTime; |
||||
} |
@ -0,0 +1,20 @@
@@ -0,0 +1,20 @@
|
||||
package com.dji.sample.manage.model.dto; |
||||
|
||||
import lombok.Data; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/8/16 |
||||
*/ |
||||
@Data |
||||
public class DeviceFirmwareUpgradeDTO { |
||||
|
||||
private String deviceName; |
||||
|
||||
private String sn; |
||||
|
||||
private String productVersion; |
||||
|
||||
private Integer firmwareUpgradeType; |
||||
} |
@ -0,0 +1,41 @@
@@ -0,0 +1,41 @@
|
||||
package com.dji.sample.manage.model.dto; |
||||
|
||||
import com.dji.sample.manage.model.receiver.LogsFileUploadList; |
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import java.time.LocalDateTime; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/9/7 |
||||
*/ |
||||
@Data |
||||
@Builder |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class DeviceLogsDTO { |
||||
|
||||
private String logsId; |
||||
|
||||
private LocalDateTime happenTime; |
||||
|
||||
private String userName; |
||||
|
||||
private String logsInformation; |
||||
|
||||
private LocalDateTime createTime; |
||||
|
||||
private Integer status; |
||||
|
||||
private TopologyDTO deviceTopo; |
||||
|
||||
private List<LogsProgressDTO> logsProgress; |
||||
|
||||
private LogsFileUploadList deviceLogs; |
||||
|
||||
} |
@ -0,0 +1,35 @@
@@ -0,0 +1,35 @@
|
||||
package com.dji.sample.manage.model.dto; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/9/9 |
||||
*/ |
||||
@Builder |
||||
@Data |
||||
@NoArgsConstructor |
||||
@AllArgsConstructor |
||||
public class LogsFileDTO { |
||||
|
||||
private String fileId; |
||||
|
||||
private String name; |
||||
|
||||
private Long size; |
||||
|
||||
private String logsId; |
||||
|
||||
private String deviceSn; |
||||
|
||||
private String fingerprint; |
||||
|
||||
private String objectKey; |
||||
|
||||
private Boolean status; |
||||
|
||||
} |
@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
|
||||
package com.dji.sample.manage.model.dto; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import java.util.List; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/9/9 |
||||
*/ |
||||
@Data |
||||
@Builder |
||||
@NoArgsConstructor |
||||
@AllArgsConstructor |
||||
public class LogsOutputProgressDTO { |
||||
|
||||
private String logsId; |
||||
|
||||
private String status; |
||||
|
||||
private List<LogsProgressDTO> files; |
||||
} |
@ -0,0 +1,31 @@
@@ -0,0 +1,31 @@
|
||||
package com.dji.sample.manage.model.dto; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/9/7 |
||||
*/ |
||||
@Data |
||||
@Builder |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class LogsProgressDTO { |
||||
|
||||
private String deviceSn; |
||||
|
||||
private String deviceModelDomain; |
||||
|
||||
private Integer progress; |
||||
|
||||
private Integer result; |
||||
|
||||
private Float uploadRate; |
||||
|
||||
private String status; |
||||
|
||||
} |
@ -0,0 +1,47 @@
@@ -0,0 +1,47 @@
|
||||
package com.dji.sample.manage.model.dto; |
||||
|
||||
import com.dji.sample.manage.model.receiver.LogsFileUploadList; |
||||
import com.dji.sample.media.model.CredentialsDTO; |
||||
import com.dji.sample.media.model.StsCredentialsDTO; |
||||
import com.fasterxml.jackson.annotation.JsonProperty; |
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/9/8 |
||||
*/ |
||||
@Data |
||||
@Builder |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class LogsUploadCredentialsDTO { |
||||
|
||||
private String bucket; |
||||
|
||||
private CredentialsDTO credentials; |
||||
|
||||
private String endpoint; |
||||
|
||||
@JsonProperty("file_store_dir") |
||||
private String objectKeyPrefix; |
||||
|
||||
private String provider; |
||||
|
||||
private String fileType = "text_log"; |
||||
|
||||
private LogsFileUploadList params; |
||||
|
||||
public LogsUploadCredentialsDTO(StsCredentialsDTO sts) { |
||||
this.bucket = sts.getBucket(); |
||||
Long expire = sts.getCredentials().getExpire(); |
||||
sts.getCredentials().setExpire(System.currentTimeMillis() + (expire - 60) * 1000); |
||||
this.credentials = sts.getCredentials(); |
||||
this.endpoint = sts.getEndpoint(); |
||||
this.objectKeyPrefix = sts.getObjectKeyPrefix(); |
||||
this.provider = sts.getProvider(); |
||||
} |
||||
} |
@ -0,0 +1,64 @@
@@ -0,0 +1,64 @@
|
||||
package com.dji.sample.manage.model.entity; |
||||
|
||||
import com.baomidou.mybatisplus.annotation.*; |
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/8/16 |
||||
*/ |
||||
@Data |
||||
@Builder |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
@TableName("manage_device_firmware") |
||||
public class DeviceFirmwareEntity implements Serializable { |
||||
|
||||
private static final long serialVersionUID = -12L; |
||||
|
||||
@TableId(type = IdType.AUTO) |
||||
private Long id; |
||||
|
||||
@TableField("firmware_id") |
||||
private String firmwareId; |
||||
|
||||
@TableField("file_name") |
||||
private String fileName; |
||||
|
||||
@TableField("firmware_version") |
||||
private String firmwareVersion; |
||||
|
||||
@TableField("file_url") |
||||
private String fileUrl; |
||||
|
||||
@TableField("file_size") |
||||
private Long fileSize; |
||||
|
||||
@TableField("file_md5") |
||||
private String fileMd5; |
||||
|
||||
@TableField("device_name") |
||||
private String deviceName; |
||||
|
||||
@TableField("release_note") |
||||
private String releaseNote; |
||||
|
||||
@TableField("release_date") |
||||
private Long releaseDate; |
||||
|
||||
@TableField("status") |
||||
private Boolean status; |
||||
|
||||
@TableField(value = "create_time", fill = FieldFill.INSERT) |
||||
private Long createTime; |
||||
|
||||
@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE) |
||||
private Long updateTime; |
||||
|
||||
} |
@ -0,0 +1,52 @@
@@ -0,0 +1,52 @@
|
||||
package com.dji.sample.manage.model.entity; |
||||
|
||||
import com.baomidou.mybatisplus.annotation.*; |
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/9/7 |
||||
*/ |
||||
@TableName("manage_device_logs") |
||||
@Data |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
@Builder |
||||
public class DeviceLogsEntity implements Serializable { |
||||
|
||||
private static final long serialVersionUID = -12L; |
||||
|
||||
@TableId(value = "id", type = IdType.AUTO) |
||||
private Long id; |
||||
|
||||
@TableField("logs_id") |
||||
private String logsId; |
||||
|
||||
@TableField("username") |
||||
private String username; |
||||
|
||||
@TableField("logs_info") |
||||
private String logsInfo; |
||||
|
||||
@TableField("device_sn") |
||||
private String deviceSn; |
||||
|
||||
@TableField("happen_time") |
||||
private Long happenTime; |
||||
|
||||
@TableField("status") |
||||
private Integer status; |
||||
|
||||
@TableField(value = "create_time", fill = FieldFill.INSERT) |
||||
private Long createTime; |
||||
|
||||
@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE) |
||||
private Long updateTime; |
||||
|
||||
} |
@ -0,0 +1,58 @@
@@ -0,0 +1,58 @@
|
||||
package com.dji.sample.manage.model.entity; |
||||
|
||||
import com.baomidou.mybatisplus.annotation.*; |
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/9/7 |
||||
*/ |
||||
@TableName("logs_file") |
||||
@Data |
||||
@Builder |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class LogsFileEntity implements Serializable { |
||||
|
||||
private static final long serialVersionUID = -12L; |
||||
|
||||
@TableId(value = "id", type = IdType.AUTO) |
||||
private Long id; |
||||
|
||||
@TableField("file_id") |
||||
private String fileId; |
||||
|
||||
@TableField("name") |
||||
private String name; |
||||
|
||||
@TableField("size") |
||||
private Long size; |
||||
|
||||
@TableField("logs_id") |
||||
private String logsId; |
||||
|
||||
@TableField("device_sn") |
||||
private String deviceSn; |
||||
|
||||
@TableField("fingerprint") |
||||
private String fingerprint; |
||||
|
||||
@TableField("object_key") |
||||
private String objectKey; |
||||
|
||||
@TableField("status") |
||||
private Boolean status; |
||||
|
||||
@TableField(value = "create_time", fill = FieldFill.INSERT) |
||||
private Long createTime; |
||||
|
||||
@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE) |
||||
private Long updateTime; |
||||
|
||||
} |
@ -0,0 +1,54 @@
@@ -0,0 +1,54 @@
|
||||
package com.dji.sample.manage.model.entity; |
||||
|
||||
import com.baomidou.mybatisplus.annotation.*; |
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/9/8 |
||||
*/ |
||||
@Data |
||||
@Builder |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
@TableName("logs_file_index") |
||||
public class LogsFileIndexEntity implements Serializable { |
||||
|
||||
private static final long serialVersionUID = -12L; |
||||
|
||||
@TableId(value = "id", type = IdType.AUTO) |
||||
private Long id; |
||||
|
||||
@TableField("boot_index") |
||||
private Integer bootIndex; |
||||
|
||||
@TableField("file_id") |
||||
private String fileId; |
||||
|
||||
@TableField("start_time") |
||||
private Long startTime; |
||||
|
||||
@TableField("end_time") |
||||
private Long endTime; |
||||
|
||||
@TableField("size") |
||||
private Long size; |
||||
|
||||
@TableField("device_sn") |
||||
private String deviceSn; |
||||
|
||||
@TableField("domain") |
||||
private Integer domain; |
||||
|
||||
@TableField(value = "create_time", fill = FieldFill.INSERT) |
||||
private Long createTime; |
||||
|
||||
@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE) |
||||
private Long updateTime; |
||||
} |
@ -0,0 +1,62 @@
@@ -0,0 +1,62 @@
|
||||
package com.dji.sample.manage.model.enums; |
||||
|
||||
import lombok.Getter; |
||||
|
||||
import java.util.Arrays; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/8/15 |
||||
*/ |
||||
@Getter |
||||
public enum DeviceFirmwareStatusEnum { |
||||
|
||||
/** |
||||
* no need to upgrade |
||||
*/ |
||||
NOT_UPGRADE(1), |
||||
|
||||
/** |
||||
* to upgraded |
||||
*/ |
||||
NORMAL_UPGRADE(2), |
||||
|
||||
/** |
||||
* A consistency upgrade is required. |
||||
*/ |
||||
CONSISTENT_UPGRADE(3), |
||||
|
||||
/** |
||||
* during upgrade |
||||
*/ |
||||
UPGRADING(4), |
||||
|
||||
UNKNOWN(-1); |
||||
|
||||
int val; |
||||
|
||||
DeviceFirmwareStatusEnum(int val) { |
||||
this.val = val; |
||||
} |
||||
|
||||
public static DeviceFirmwareStatusEnum find(int val) { |
||||
return Arrays.stream(DeviceFirmwareStatusEnum.values()) |
||||
.filter(firmwareStatus -> firmwareStatus.val == val) |
||||
.findFirst().orElse(UNKNOWN); |
||||
} |
||||
|
||||
@Getter |
||||
public enum CompatibleStatusEnum { |
||||
INCONSISTENT(1), |
||||
|
||||
CONSISTENT(0); |
||||
|
||||
int val; |
||||
|
||||
CompatibleStatusEnum(int val) { |
||||
this.val = val; |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,41 @@
@@ -0,0 +1,41 @@
|
||||
package com.dji.sample.manage.model.enums; |
||||
|
||||
import com.dji.sample.component.mqtt.model.EventsResultStatusEnum; |
||||
import lombok.Getter; |
||||
|
||||
import java.util.Arrays; |
||||
import java.util.Collections; |
||||
import java.util.HashSet; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/9/8 |
||||
*/ |
||||
@Getter |
||||
public enum DeviceLogsStatusEnum { |
||||
|
||||
UPLOADING(1, EventsResultStatusEnum.IN_PROGRESS), |
||||
|
||||
DONE(2, EventsResultStatusEnum.OK), |
||||
|
||||
CANCELED(3, EventsResultStatusEnum.CANCELED), |
||||
|
||||
FAILED(4, EventsResultStatusEnum.FAILED, EventsResultStatusEnum.REJECTED, EventsResultStatusEnum.TIMEOUT), |
||||
|
||||
UNKNOWN(-1); |
||||
|
||||
int val; |
||||
|
||||
HashSet<EventsResultStatusEnum> status; |
||||
|
||||
DeviceLogsStatusEnum(int val, EventsResultStatusEnum... status) { |
||||
this.status = new HashSet<>(); |
||||
Collections.addAll(this.status, status); |
||||
this.val = val; |
||||
} |
||||
|
||||
public static DeviceLogsStatusEnum find(EventsResultStatusEnum status) { |
||||
return Arrays.stream(DeviceLogsStatusEnum.values()).filter(element -> element.status.contains(status)).findAny().orElse(UNKNOWN); |
||||
} |
||||
} |
@ -0,0 +1,28 @@
@@ -0,0 +1,28 @@
|
||||
package com.dji.sample.manage.model.enums; |
||||
|
||||
import lombok.Getter; |
||||
|
||||
import java.util.Arrays; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/9/9 |
||||
*/ |
||||
@Getter |
||||
public enum LogsFileUpdateMethodEnum { |
||||
|
||||
CANCEL("cancel"), |
||||
|
||||
UNKNOWN("unknown"); |
||||
|
||||
String method; |
||||
|
||||
LogsFileUpdateMethodEnum(String method) { |
||||
this.method = method; |
||||
} |
||||
|
||||
public static LogsFileUpdateMethodEnum find(String method) { |
||||
return Arrays.stream(LogsFileUpdateMethodEnum.values()).filter(e -> e.method.equals(method)).findAny().orElse(UNKNOWN); |
||||
} |
||||
} |
@ -0,0 +1,21 @@
@@ -0,0 +1,21 @@
|
||||
package com.dji.sample.manage.model.param; |
||||
|
||||
import com.dji.sample.manage.model.receiver.LogsFileUpload; |
||||
import lombok.Data; |
||||
|
||||
import java.util.List; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/9/8 |
||||
*/ |
||||
@Data |
||||
public class DeviceLogsCreateParam { |
||||
|
||||
private String logsInformation; |
||||
|
||||
private Long happenTime; |
||||
|
||||
private List<LogsFileUpload> files; |
||||
} |
@ -0,0 +1,24 @@
@@ -0,0 +1,24 @@
|
||||
package com.dji.sample.manage.model.param; |
||||
|
||||
import lombok.Data; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/9/7 |
||||
*/ |
||||
@Data |
||||
public class DeviceLogsQueryParam { |
||||
|
||||
private Long page; |
||||
|
||||
private Long pageSize; |
||||
|
||||
private Integer status; |
||||
|
||||
private Long beginTime; |
||||
|
||||
private Long endTime; |
||||
|
||||
private String logsInformation; |
||||
} |
@ -0,0 +1,32 @@
@@ -0,0 +1,32 @@
|
||||
package com.dji.sample.manage.model.param; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/8/16 |
||||
*/ |
||||
@Data |
||||
@Builder |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class DeviceOtaCreateParam { |
||||
|
||||
private String sn; |
||||
|
||||
private String productVersion; |
||||
|
||||
private String fileUrl; |
||||
|
||||
private String md5; |
||||
|
||||
private Long fileSize; |
||||
|
||||
private Integer firmwareUpgradeType; |
||||
|
||||
private String fileName; |
||||
} |
@ -0,0 +1,21 @@
@@ -0,0 +1,21 @@
|
||||
package com.dji.sample.manage.model.param; |
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty; |
||||
import lombok.Data; |
||||
|
||||
import java.util.List; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/9/9 |
||||
*/ |
||||
@Data |
||||
public class LogsFileUpdateParam { |
||||
|
||||
private String status; |
||||
|
||||
@JsonProperty("module_list") |
||||
private List<String> deviceModelDomainList; |
||||
|
||||
} |
@ -0,0 +1,27 @@
@@ -0,0 +1,27 @@
|
||||
package com.dji.sample.manage.model.receiver; |
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty; |
||||
import lombok.Data; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/9/9 |
||||
*/ |
||||
@Data |
||||
public class LogsExtFileReceiver { |
||||
|
||||
@JsonProperty("module") |
||||
private String deviceModelDomain; |
||||
|
||||
private Long size; |
||||
|
||||
private String deviceSn; |
||||
|
||||
private String key; |
||||
|
||||
private String fingerprint; |
||||
|
||||
private LogsProgressReceiver progress; |
||||
|
||||
} |
@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
|
||||
package com.dji.sample.manage.model.receiver; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/9/7 |
||||
*/ |
||||
@Data |
||||
@Builder |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class LogsFile { |
||||
|
||||
private Integer bootIndex; |
||||
|
||||
private Long endTime; |
||||
|
||||
private Long startTime; |
||||
|
||||
private Long size; |
||||
} |
@ -0,0 +1,34 @@
@@ -0,0 +1,34 @@
|
||||
package com.dji.sample.manage.model.receiver; |
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty; |
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import java.util.List; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/9/7 |
||||
*/ |
||||
@Data |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
@Builder |
||||
public class LogsFileUpload { |
||||
|
||||
private String deviceSn; |
||||
|
||||
private List<LogsFile> list; |
||||
|
||||
@JsonProperty("module") |
||||
private String deviceModelDomain; |
||||
|
||||
private String objectKey; |
||||
|
||||
private Integer result; |
||||
|
||||
private String fileId; |
||||
} |
@ -0,0 +1,24 @@
@@ -0,0 +1,24 @@
|
||||
package com.dji.sample.manage.model.receiver; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import java.util.List; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/9/7 |
||||
*/ |
||||
@Data |
||||
@Builder |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class LogsFileUploadList { |
||||
|
||||
private List<LogsFileUpload> files; |
||||
|
||||
private Integer result; |
||||
} |
@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
|
||||
package com.dji.sample.manage.model.receiver; |
||||
|
||||
import lombok.Data; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/9/9 |
||||
*/ |
||||
@Data |
||||
public class LogsProgressReceiver { |
||||
|
||||
private Integer currentStep; |
||||
|
||||
private Integer totalStep; |
||||
|
||||
private Integer progress; |
||||
|
||||
private Long finishTime; |
||||
|
||||
private Float uploadRate; |
||||
|
||||
private String status; |
||||
|
||||
private Integer result; |
||||
} |
@ -0,0 +1,16 @@
@@ -0,0 +1,16 @@
|
||||
package com.dji.sample.manage.model.receiver; |
||||
|
||||
import lombok.Data; |
||||
|
||||
import java.util.List; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/9/9 |
||||
*/ |
||||
@Data |
||||
public class OutputLogsExtReceiver { |
||||
|
||||
private List<LogsExtFileReceiver> files; |
||||
} |
@ -0,0 +1,16 @@
@@ -0,0 +1,16 @@
|
||||
package com.dji.sample.manage.model.receiver; |
||||
|
||||
import lombok.Data; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/9/9 |
||||
*/ |
||||
@Data |
||||
public class OutputLogsProgressReceiver { |
||||
|
||||
private OutputLogsExtReceiver ext; |
||||
|
||||
private String status; |
||||
} |
@ -0,0 +1,48 @@
@@ -0,0 +1,48 @@
|
||||
package com.dji.sample.manage.service; |
||||
|
||||
import com.dji.sample.component.mqtt.model.CommonTopicReceiver; |
||||
import com.dji.sample.manage.model.dto.DeviceFirmwareDTO; |
||||
import com.dji.sample.manage.model.dto.DeviceFirmwareNoteDTO; |
||||
import com.dji.sample.manage.model.dto.DeviceFirmwareUpgradeDTO; |
||||
import com.dji.sample.manage.model.param.DeviceOtaCreateParam; |
||||
import org.springframework.messaging.MessageHeaders; |
||||
|
||||
import java.util.List; |
||||
import java.util.Optional; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/8/16 |
||||
*/ |
||||
public interface IDeviceFirmwareService { |
||||
|
||||
/** |
||||
* Query specific firmware information based on the device model and firmware version. |
||||
* @param deviceName |
||||
* @param version |
||||
* @return |
||||
*/ |
||||
Optional<DeviceFirmwareDTO> getFirmware(String deviceName, String version); |
||||
|
||||
/** |
||||
* Get the latest firmware release note for this device model. |
||||
* @param deviceName |
||||
* @return |
||||
*/ |
||||
Optional<DeviceFirmwareNoteDTO> getLatestFirmwareReleaseNote(String deviceName); |
||||
|
||||
/** |
||||
* Get the firmware information that the device needs to update. |
||||
* @param upgradeDTOS |
||||
* @return |
||||
*/ |
||||
List<DeviceOtaCreateParam> getDeviceOtaFirmware(List<DeviceFirmwareUpgradeDTO> upgradeDTOS); |
||||
|
||||
/** |
||||
* Interface to handle device firmware update progress. |
||||
* @param receiver |
||||
* @param headers |
||||
*/ |
||||
void handleOtaProgress(CommonTopicReceiver receiver, MessageHeaders headers); |
||||
} |
@ -0,0 +1,94 @@
@@ -0,0 +1,94 @@
|
||||
package com.dji.sample.manage.service; |
||||
|
||||
import com.dji.sample.common.model.PaginationData; |
||||
import com.dji.sample.common.model.ResponseResult; |
||||
import com.dji.sample.component.mqtt.model.CommonTopicReceiver; |
||||
import com.dji.sample.manage.model.dto.DeviceLogsDTO; |
||||
import com.dji.sample.manage.model.param.DeviceLogsCreateParam; |
||||
import com.dji.sample.manage.model.param.DeviceLogsQueryParam; |
||||
import com.dji.sample.manage.model.param.LogsFileUpdateParam; |
||||
import org.springframework.messaging.MessageHeaders; |
||||
|
||||
import java.net.URL; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/9/7 |
||||
*/ |
||||
public interface IDeviceLogsService { |
||||
|
||||
/** |
||||
* Obtain the device upload log list by paging according to the query parameters. |
||||
* @param deviceSn |
||||
* @param param |
||||
* @return |
||||
*/ |
||||
PaginationData<DeviceLogsDTO> getUploadedLogs(String deviceSn, DeviceLogsQueryParam param); |
||||
|
||||
/** |
||||
* Get a list of log files that can be uploaded in real time. |
||||
* @param deviceSn |
||||
* @param domainList |
||||
* @return |
||||
*/ |
||||
ResponseResult getRealTimeLogs(String deviceSn, List<String> domainList); |
||||
|
||||
/** |
||||
* Add device logs. |
||||
* |
||||
* @param bid |
||||
* @param username |
||||
* @param deviceSn |
||||
* @param param |
||||
* @return logs id |
||||
*/ |
||||
String insertDeviceLogs(String bid, String username, String deviceSn, DeviceLogsCreateParam param); |
||||
|
||||
/** |
||||
* Initiate a log upload request to the gateway. |
||||
* @param username |
||||
* @param deviceSn |
||||
* @param param |
||||
* @return |
||||
*/ |
||||
ResponseResult pushFileUpload(String username, String deviceSn, DeviceLogsCreateParam param); |
||||
|
||||
/** |
||||
* Push a request to modify the status of the logs file. |
||||
* @param deviceSn |
||||
* @param param |
||||
* @return |
||||
*/ |
||||
ResponseResult pushUpdateFile(String deviceSn, LogsFileUpdateParam param); |
||||
|
||||
/** |
||||
* Delete log records. |
||||
* @param deviceSn |
||||
* @param logsId |
||||
*/ |
||||
void deleteLogs(String deviceSn, String logsId); |
||||
|
||||
/** |
||||
* Handle logs file upload progress. |
||||
* @param receiver |
||||
* @param headers |
||||
*/ |
||||
void handleFileUploadProgress(CommonTopicReceiver receiver, MessageHeaders headers); |
||||
|
||||
/** |
||||
* Update status, which is updated when the logs upload succeeds or fails. |
||||
* @param logsId |
||||
* @param value |
||||
*/ |
||||
void updateLogsStatus(String logsId, Integer value); |
||||
|
||||
/** |
||||
* Get the file address. |
||||
* @param logsId |
||||
* @param fileId |
||||
* @return |
||||
*/ |
||||
URL getLogsFileUrl(String logsId, String fileId); |
||||
} |
@ -0,0 +1,46 @@
@@ -0,0 +1,46 @@
|
||||
package com.dji.sample.manage.service; |
||||
|
||||
import com.dji.sample.manage.model.dto.LogsFileDTO; |
||||
import com.dji.sample.manage.model.receiver.LogsFile; |
||||
import com.dji.sample.manage.model.receiver.LogsFileUpload; |
||||
|
||||
import java.util.List; |
||||
import java.util.Optional; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/9/8 |
||||
*/ |
||||
public interface ILogsFileIndexService { |
||||
|
||||
/** |
||||
* Insert the index of the device logs. |
||||
* @param file |
||||
* @param deviceSn |
||||
* @param domain |
||||
* @param fileId |
||||
* @return |
||||
*/ |
||||
Boolean insertFileIndex(LogsFile file, String deviceSn, Integer domain, String fileId); |
||||
|
||||
/** |
||||
* Query logs file upload information based on the file id. |
||||
* @param fileId |
||||
* @return |
||||
*/ |
||||
Optional<LogsFileUpload> getFileIndexByFileId(String fileId); |
||||
|
||||
/** |
||||
* Batch query logs file upload information. |
||||
* @param fileIds |
||||
* @return |
||||
*/ |
||||
List<LogsFileUpload> getFileIndexByFileIds(List<LogsFileDTO> fileIds); |
||||
|
||||
/** |
||||
* Delete log index data based on file id. |
||||
* @param fileIds |
||||
*/ |
||||
void deleteFileIndexByFileIds(List<String> fileIds); |
||||
} |
@ -0,0 +1,66 @@
@@ -0,0 +1,66 @@
|
||||
package com.dji.sample.manage.service; |
||||
|
||||
import com.dji.sample.manage.model.dto.LogsFileDTO; |
||||
import com.dji.sample.manage.model.receiver.LogsExtFileReceiver; |
||||
import com.dji.sample.manage.model.receiver.LogsFileUpload; |
||||
|
||||
import java.net.URL; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/9/7 |
||||
*/ |
||||
public interface ILogsFileService { |
||||
|
||||
/** |
||||
* Query the uploaded log file information based on the log id. |
||||
* @param logsId |
||||
* @return |
||||
*/ |
||||
List<LogsFileDTO> getLogsFileInfoByLogsId(String logsId); |
||||
|
||||
/** |
||||
* Query the uploaded log file structure information based on the log id. |
||||
* @param logsId |
||||
* @return |
||||
*/ |
||||
List<LogsFileUpload> getLogsFileByLogsId(String logsId); |
||||
|
||||
/** |
||||
* Added logs file. |
||||
* @param file |
||||
* @param logsId |
||||
* @return |
||||
*/ |
||||
Boolean insertFile(LogsFileUpload file, String logsId); |
||||
|
||||
/** |
||||
* Delete logs files. |
||||
* @param logsId |
||||
*/ |
||||
void deleteFileByLogsId(String logsId); |
||||
|
||||
/** |
||||
* Update file information. |
||||
* @param logsId |
||||
* @param fileReceiver |
||||
*/ |
||||
void updateFile(String logsId, LogsExtFileReceiver fileReceiver); |
||||
|
||||
/** |
||||
* Update file upload status. |
||||
* @param logsId |
||||
* @param isUploaded |
||||
*/ |
||||
void updateFileUploadStatus(String logsId, Boolean isUploaded); |
||||
|
||||
/** |
||||
* Get the file address. |
||||
* @param logsId |
||||
* @param fileId |
||||
* @return |
||||
*/ |
||||
URL getLogsFileUrl(String logsId, String fileId); |
||||
} |
@ -0,0 +1,218 @@
@@ -0,0 +1,218 @@
|
||||
package com.dji.sample.manage.service.impl; |
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
||||
import com.dji.sample.common.model.ResponseResult; |
||||
import com.dji.sample.component.mqtt.model.*; |
||||
import com.dji.sample.component.mqtt.service.impl.MessageSenderServiceImpl; |
||||
import com.dji.sample.component.redis.RedisConst; |
||||
import com.dji.sample.component.redis.RedisOpsUtils; |
||||
import com.dji.sample.component.websocket.model.CustomWebSocketMessage; |
||||
import com.dji.sample.component.websocket.service.IWebSocketManageService; |
||||
import com.dji.sample.component.websocket.service.impl.SendMessageServiceImpl; |
||||
import com.dji.sample.manage.dao.IDeviceFirmwareMapper; |
||||
import com.dji.sample.manage.model.dto.DeviceDTO; |
||||
import com.dji.sample.manage.model.dto.DeviceFirmwareDTO; |
||||
import com.dji.sample.manage.model.dto.DeviceFirmwareNoteDTO; |
||||
import com.dji.sample.manage.model.dto.DeviceFirmwareUpgradeDTO; |
||||
import com.dji.sample.manage.model.entity.DeviceFirmwareEntity; |
||||
import com.dji.sample.manage.model.enums.UserTypeEnum; |
||||
import com.dji.sample.manage.model.param.DeviceOtaCreateParam; |
||||
import com.dji.sample.manage.service.IDeviceFirmwareService; |
||||
import com.fasterxml.jackson.core.type.TypeReference; |
||||
import com.fasterxml.jackson.databind.ObjectMapper; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.integration.annotation.ServiceActivator; |
||||
import org.springframework.integration.mqtt.support.MqttHeaders; |
||||
import org.springframework.messaging.MessageHeaders; |
||||
import org.springframework.stereotype.Service; |
||||
|
||||
import java.time.Instant; |
||||
import java.time.LocalDate; |
||||
import java.time.ZoneId; |
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
import java.util.Optional; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/8/16 |
||||
*/ |
||||
@Service |
||||
@Slf4j |
||||
public class DeviceFirmwareServiceImpl implements IDeviceFirmwareService { |
||||
|
||||
@Autowired |
||||
private IDeviceFirmwareMapper mapper; |
||||
|
||||
@Autowired |
||||
private RedisOpsUtils redisOps; |
||||
|
||||
@Autowired |
||||
private MessageSenderServiceImpl messageSenderService; |
||||
|
||||
@Autowired |
||||
private ObjectMapper objectMapper; |
||||
|
||||
@Autowired |
||||
private SendMessageServiceImpl webSocketMessageService; |
||||
|
||||
@Autowired |
||||
private IWebSocketManageService webSocketManageService; |
||||
|
||||
@Override |
||||
public Optional<DeviceFirmwareDTO> getFirmware(String deviceName, String version) { |
||||
return Optional.ofNullable(entity2Dto(mapper.selectOne( |
||||
new LambdaQueryWrapper<DeviceFirmwareEntity>() |
||||
.eq(DeviceFirmwareEntity::getDeviceName, deviceName) |
||||
.eq(DeviceFirmwareEntity::getFirmwareVersion, version)))); |
||||
} |
||||
|
||||
@Override |
||||
public Optional<DeviceFirmwareNoteDTO> getLatestFirmwareReleaseNote(String deviceName) { |
||||
return Optional.ofNullable(entity2NoteDto(mapper.selectOne( |
||||
new LambdaQueryWrapper<DeviceFirmwareEntity>() |
||||
.eq(DeviceFirmwareEntity::getDeviceName, deviceName) |
||||
.eq(DeviceFirmwareEntity::getStatus, true) |
||||
.orderByDesc(DeviceFirmwareEntity::getReleaseDate) |
||||
.last(" limit 1 ")))); |
||||
} |
||||
|
||||
@Override |
||||
public List<DeviceOtaCreateParam> getDeviceOtaFirmware(List<DeviceFirmwareUpgradeDTO> upgradeDTOS) { |
||||
List<DeviceOtaCreateParam> deviceOtaList = new ArrayList<>(); |
||||
upgradeDTOS.forEach(upgradeDevice -> { |
||||
boolean exist = redisOps.getExpire(RedisConst.DEVICE_ONLINE_PREFIX + upgradeDevice.getSn()) > 0; |
||||
if (!exist) { |
||||
throw new IllegalArgumentException("Device is offline."); |
||||
} |
||||
Optional<DeviceFirmwareDTO> firmwareOpt = this.getFirmware( |
||||
upgradeDevice.getDeviceName(), upgradeDevice.getProductVersion()); |
||||
if (firmwareOpt.isEmpty()) { |
||||
throw new IllegalArgumentException("This firmware version does not exist."); |
||||
} |
||||
if (!firmwareOpt.get().getFirmwareStatus()) { |
||||
throw new IllegalArgumentException("This firmware version is not available."); |
||||
} |
||||
DeviceOtaCreateParam ota = dto2OtaCreateDto(firmwareOpt.get()); |
||||
ota.setSn(upgradeDevice.getSn()); |
||||
ota.setFirmwareUpgradeType(upgradeDevice.getFirmwareUpgradeType()); |
||||
deviceOtaList.add(ota); |
||||
}); |
||||
return deviceOtaList; |
||||
} |
||||
|
||||
@Override |
||||
@ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_OTA_PROGRESS, outputChannel = ChannelName.OUTBOUND) |
||||
public void handleOtaProgress(CommonTopicReceiver receiver, MessageHeaders headers) { |
||||
String topic = headers.get(MqttHeaders.RECEIVED_TOPIC).toString(); |
||||
String sn = topic.substring((TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT).length(), |
||||
topic.indexOf(TopicConst.EVENTS_SUF)); |
||||
|
||||
EventsReceiver<EventsOutputReceiver> eventsReceiver = objectMapper.convertValue(receiver.getData(), |
||||
new TypeReference<EventsReceiver<EventsOutputReceiver>>(){}); |
||||
eventsReceiver.setBid(receiver.getBid()); |
||||
eventsReceiver.setSn(sn); |
||||
|
||||
EventsOutputReceiver output = eventsReceiver.getOutput(); |
||||
log.info("SN: {}, {} ===> Upgrading progress: {}", |
||||
sn, receiver.getMethod(), output.getProgress().toString()); |
||||
|
||||
if (eventsReceiver.getResult() != ResponseResult.CODE_SUCCESS) { |
||||
log.error("SN: {}, {} ===> Error code: {}", sn, receiver.getMethod(), eventsReceiver.getResult()); |
||||
} |
||||
|
||||
DeviceDTO device = (DeviceDTO) redisOps.get(RedisConst.DEVICE_ONLINE_PREFIX + sn); |
||||
String childDeviceSn = device.getChildDeviceSn(); |
||||
boolean upgrade = redisOps.getExpire(RedisConst.FIRMWARE_UPGRADING_PREFIX + sn) > 0; |
||||
boolean childUpgrade = redisOps.getExpire(RedisConst.FIRMWARE_UPGRADING_PREFIX + childDeviceSn) > 0; |
||||
|
||||
// Determine whether it is the ending state, delete the update state key in redis after the job ends.
|
||||
EventsResultStatusEnum statusEnum = EventsResultStatusEnum.find(output.getStatus()); |
||||
if (upgrade) { |
||||
if (statusEnum.getEnd()) { |
||||
// Delete the cache after the update is complete.
|
||||
redisOps.del(RedisConst.FIRMWARE_UPGRADING_PREFIX + sn); |
||||
} else { |
||||
// Update the update progress of the dock in redis.
|
||||
redisOps.setWithExpire( |
||||
RedisConst.FIRMWARE_UPGRADING_PREFIX + sn, output.getProgress().getPercent(), |
||||
RedisConst.DEVICE_ALIVE_SECOND * RedisConst.DEVICE_ALIVE_SECOND); |
||||
} |
||||
} |
||||
if (childUpgrade) { |
||||
if (statusEnum.getEnd()) { |
||||
redisOps.del(RedisConst.FIRMWARE_UPGRADING_PREFIX + childDeviceSn); |
||||
} else { |
||||
// Update the update progress of the drone in redis.
|
||||
redisOps.setWithExpire( |
||||
RedisConst.FIRMWARE_UPGRADING_PREFIX + childDeviceSn, output.getProgress().getPercent(), |
||||
RedisConst.DEVICE_ALIVE_SECOND * RedisConst.DEVICE_ALIVE_SECOND); |
||||
} |
||||
} |
||||
|
||||
webSocketMessageService.sendBatch( |
||||
webSocketManageService.getValueWithWorkspaceAndUserType( |
||||
device.getWorkspaceId(), UserTypeEnum.WEB.getVal()), |
||||
CustomWebSocketMessage.builder() |
||||
.data(eventsReceiver) |
||||
.timestamp(System.currentTimeMillis()) |
||||
.bizCode(receiver.getMethod()) |
||||
.build()); |
||||
|
||||
if (receiver.getNeedReply() != null && receiver.getNeedReply() == 1) { |
||||
String replyTopic = headers.get(MqttHeaders.RECEIVED_TOPIC) + TopicConst._REPLY_SUF; |
||||
messageSenderService.publish(replyTopic, |
||||
CommonTopicResponse.builder() |
||||
.tid(receiver.getTid()) |
||||
.bid(receiver.getBid()) |
||||
.method(receiver.getMethod()) |
||||
.timestamp(System.currentTimeMillis()) |
||||
.data(ResponseResult.success()) |
||||
.build()); |
||||
} |
||||
} |
||||
|
||||
private DeviceFirmwareNoteDTO entity2NoteDto (DeviceFirmwareEntity entity) { |
||||
if (entity == null) { |
||||
return null; |
||||
} |
||||
return DeviceFirmwareNoteDTO.builder() |
||||
.deviceName(entity.getDeviceName()) |
||||
.productVersion(entity.getFirmwareVersion()) |
||||
.releasedTime(LocalDate.ofInstant(Instant.ofEpochMilli(entity.getReleaseDate()), ZoneId.systemDefault())) |
||||
.releaseNote(entity.getReleaseNote()) |
||||
.build(); |
||||
} |
||||
|
||||
private DeviceFirmwareDTO entity2Dto (DeviceFirmwareEntity entity) { |
||||
if (entity == null) { |
||||
return null; |
||||
} |
||||
return DeviceFirmwareDTO.builder() |
||||
.deviceName(entity.getDeviceName()) |
||||
.fileMd5(entity.getFileMd5()) |
||||
.fileSize(entity.getFileSize()) |
||||
.fileUrl(entity.getFileUrl()) |
||||
.firmwareId(entity.getFirmwareId()) |
||||
.fileName(entity.getFileName()) |
||||
.productVersion(entity.getFirmwareVersion()) |
||||
.releasedTime(LocalDate.ofInstant(Instant.ofEpochMilli(entity.getReleaseDate()), ZoneId.systemDefault())) |
||||
.firmwareStatus(entity.getStatus()) |
||||
.build(); |
||||
} |
||||
|
||||
private DeviceOtaCreateParam dto2OtaCreateDto(DeviceFirmwareDTO dto) { |
||||
if (dto == null) { |
||||
return null; |
||||
} |
||||
return DeviceOtaCreateParam.builder() |
||||
.fileSize(dto.getFileSize()) |
||||
.fileUrl(dto.getFileUrl()) |
||||
.fileName(dto.getFileName()) |
||||
.md5(dto.getFileMd5()) |
||||
.productVersion(dto.getProductVersion()) |
||||
.build(); |
||||
} |
||||
} |
@ -0,0 +1,376 @@
@@ -0,0 +1,376 @@
|
||||
package com.dji.sample.manage.service.impl; |
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
||||
import com.dji.sample.common.model.Pagination; |
||||
import com.dji.sample.common.model.PaginationData; |
||||
import com.dji.sample.common.model.ResponseResult; |
||||
import com.dji.sample.component.mqtt.model.*; |
||||
import com.dji.sample.component.mqtt.service.IMessageSenderService; |
||||
import com.dji.sample.component.redis.RedisConst; |
||||
import com.dji.sample.component.redis.RedisOpsUtils; |
||||
import com.dji.sample.component.websocket.model.CustomWebSocketMessage; |
||||
import com.dji.sample.component.websocket.service.ISendMessageService; |
||||
import com.dji.sample.component.websocket.service.IWebSocketManageService; |
||||
import com.dji.sample.manage.dao.IDeviceLogsMapper; |
||||
import com.dji.sample.manage.model.dto.*; |
||||
import com.dji.sample.manage.model.entity.DeviceLogsEntity; |
||||
import com.dji.sample.manage.model.enums.DeviceDomainEnum; |
||||
import com.dji.sample.manage.model.enums.DeviceLogsStatusEnum; |
||||
import com.dji.sample.manage.model.enums.LogsFileUpdateMethodEnum; |
||||
import com.dji.sample.manage.model.enums.UserTypeEnum; |
||||
import com.dji.sample.manage.model.param.DeviceLogsCreateParam; |
||||
import com.dji.sample.manage.model.param.DeviceLogsQueryParam; |
||||
import com.dji.sample.manage.model.param.LogsFileUpdateParam; |
||||
import com.dji.sample.manage.model.receiver.*; |
||||
import com.dji.sample.manage.service.IDeviceLogsService; |
||||
import com.dji.sample.manage.service.ILogsFileService; |
||||
import com.dji.sample.manage.service.ITopologyService; |
||||
import com.dji.sample.media.model.StsCredentialsDTO; |
||||
import com.dji.sample.storage.service.IStorageService; |
||||
import com.fasterxml.jackson.core.type.TypeReference; |
||||
import com.fasterxml.jackson.databind.ObjectMapper; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.integration.annotation.ServiceActivator; |
||||
import org.springframework.integration.mqtt.support.MqttHeaders; |
||||
import org.springframework.messaging.MessageHeaders; |
||||
import org.springframework.stereotype.Service; |
||||
import org.springframework.transaction.annotation.Transactional; |
||||
import org.springframework.util.CollectionUtils; |
||||
import org.springframework.util.StringUtils; |
||||
|
||||
import java.net.URL; |
||||
import java.time.Instant; |
||||
import java.time.LocalDateTime; |
||||
import java.time.ZoneId; |
||||
import java.util.*; |
||||
import java.util.stream.Collectors; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/9/7 |
||||
*/ |
||||
@Service |
||||
@Transactional |
||||
@Slf4j |
||||
public class DeviceLogsServiceImpl implements IDeviceLogsService { |
||||
|
||||
private static final String LOGS_FILE_SUFFIX = ".tar"; |
||||
|
||||
@Autowired |
||||
private IDeviceLogsMapper mapper; |
||||
|
||||
@Autowired |
||||
private ITopologyService topologyService; |
||||
|
||||
@Autowired |
||||
private IMessageSenderService messageSenderService; |
||||
|
||||
@Autowired |
||||
private ILogsFileService logsFileService; |
||||
|
||||
@Autowired |
||||
private RedisOpsUtils redisOpsUtils; |
||||
|
||||
@Autowired |
||||
private IStorageService storageService; |
||||
|
||||
@Autowired |
||||
private ObjectMapper objectMapper; |
||||
|
||||
@Autowired |
||||
private ISendMessageService webSocketMessageService; |
||||
|
||||
@Autowired |
||||
private IWebSocketManageService webSocketManageService; |
||||
|
||||
@Override |
||||
public PaginationData<DeviceLogsDTO> getUploadedLogs(String deviceSn, DeviceLogsQueryParam param) { |
||||
LambdaQueryWrapper<DeviceLogsEntity> queryWrapper = new LambdaQueryWrapper<DeviceLogsEntity>() |
||||
.eq(DeviceLogsEntity::getDeviceSn, deviceSn) |
||||
.between(Objects.nonNull(param.getBeginTime()) && Objects.nonNull(param.getEndTime()), |
||||
DeviceLogsEntity::getCreateTime, param.getBeginTime(), param.getEndTime()) |
||||
.eq(Objects.nonNull(param.getStatus()), DeviceLogsEntity::getStatus, param.getStatus()) |
||||
.like(StringUtils.hasText(param.getLogsInformation()), |
||||
DeviceLogsEntity::getLogsInfo, param.getLogsInformation()) |
||||
.orderByDesc(DeviceLogsEntity::getCreateTime); |
||||
|
||||
Page<DeviceLogsEntity> pagination = mapper.selectPage(new Page<>(param.getPage(), param.getPageSize()), queryWrapper); |
||||
|
||||
List<DeviceLogsDTO> deviceLogsList = pagination.getRecords().stream().map(this::entity2Dto).collect(Collectors.toList()); |
||||
|
||||
return new PaginationData<DeviceLogsDTO>(deviceLogsList, new Pagination(pagination)); |
||||
} |
||||
|
||||
@Override |
||||
public ResponseResult getRealTimeLogs(String deviceSn, List<String> domainList) { |
||||
boolean exist = redisOpsUtils.getExpire(RedisConst.DEVICE_ONLINE_PREFIX + deviceSn) > 0; |
||||
if (!exist) { |
||||
return ResponseResult.error("Device is offline."); |
||||
} |
||||
|
||||
String topic = TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + deviceSn + TopicConst.SERVICES_SUF; |
||||
Optional<LogsFileUploadList> serviceReplyOpt = messageSenderService.publishWithReply( |
||||
LogsFileUploadList.class, |
||||
topic, |
||||
CommonTopicResponse.builder() |
||||
.tid(UUID.randomUUID().toString()) |
||||
.bid(UUID.randomUUID().toString()) |
||||
.method(ServicesMethodEnum.FILE_UPLOAD_LIST.getMethod()) |
||||
.timestamp(System.currentTimeMillis()) |
||||
.data(Map.of(MapKeyConst.MODULE_LIST, domainList)) |
||||
.build(), 1); |
||||
if (serviceReplyOpt.isEmpty()) { |
||||
return ResponseResult.error("No message reply received."); |
||||
} |
||||
LogsFileUploadList data = serviceReplyOpt.get(); |
||||
for (LogsFileUpload file : data.getFiles()) { |
||||
if (file.getDeviceSn().isBlank()) { |
||||
file.setDeviceSn(deviceSn); |
||||
} |
||||
} |
||||
return ResponseResult.success(data); |
||||
} |
||||
|
||||
@Override |
||||
public String insertDeviceLogs(String bid, String username, String deviceSn, DeviceLogsCreateParam param) { |
||||
DeviceLogsEntity entity = DeviceLogsEntity.builder() |
||||
.deviceSn(deviceSn) |
||||
.username(username) |
||||
.happenTime(param.getHappenTime()) |
||||
.logsInfo(Objects.requireNonNullElse(param.getLogsInformation(), "")) |
||||
.logsId(bid) |
||||
.status(DeviceLogsStatusEnum.UPLOADING.getVal()) |
||||
.build(); |
||||
boolean insert = mapper.insert(entity) > 0; |
||||
if (!insert) { |
||||
return ""; |
||||
} |
||||
for (LogsFileUpload file : param.getFiles()) { |
||||
insert = logsFileService.insertFile(file, entity.getLogsId()); |
||||
if (!insert) { |
||||
return ""; |
||||
} |
||||
} |
||||
|
||||
return bid; |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public ResponseResult pushFileUpload(String username, String deviceSn, DeviceLogsCreateParam param) { |
||||
StsCredentialsDTO stsCredentials = storageService.getSTSCredentials(); |
||||
LogsUploadCredentialsDTO credentialsDTO = new LogsUploadCredentialsDTO(stsCredentials); |
||||
// Set the storage name of the file.
|
||||
List<LogsFileUpload> files = param.getFiles(); |
||||
files.forEach(file -> file.setObjectKey(credentialsDTO.getObjectKeyPrefix() + "/" + UUID.randomUUID().toString() + LOGS_FILE_SUFFIX)); |
||||
|
||||
credentialsDTO.setParams(LogsFileUploadList.builder().files(files).build()); |
||||
String bid = UUID.randomUUID().toString(); |
||||
Optional<ServiceReply> serviceReply = messageSenderService.publishWithReply( |
||||
TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + deviceSn + TopicConst.SERVICES_SUF, |
||||
CommonTopicResponse.<LogsUploadCredentialsDTO>builder() |
||||
.tid(UUID.randomUUID().toString()) |
||||
.bid(bid) |
||||
.timestamp(System.currentTimeMillis()) |
||||
.method(ServicesMethodEnum.FILE_UPLOAD_START.getMethod()) |
||||
.data(credentialsDTO) |
||||
.build()); |
||||
|
||||
if (serviceReply.isEmpty()) { |
||||
return ResponseResult.error("No message reply received."); |
||||
} |
||||
ServiceReply reply = serviceReply.get(); |
||||
if (ResponseResult.CODE_SUCCESS != reply.getResult()) { |
||||
return ResponseResult.error(String.valueOf(reply.getResult())); |
||||
} |
||||
|
||||
String logsId = this.insertDeviceLogs(bid, username, deviceSn, param); |
||||
if (!bid.equals(logsId)) { |
||||
return ResponseResult.error("Database insert failed."); |
||||
} |
||||
|
||||
// Save the status of the log upload.
|
||||
redisOpsUtils.hashSet(RedisConst.LOGS_FILE_PREFIX + deviceSn, bid, LogsOutputProgressDTO.builder().logsId(logsId).build()); |
||||
return ResponseResult.success(); |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public ResponseResult pushUpdateFile(String deviceSn, LogsFileUpdateParam param) { |
||||
LogsFileUpdateMethodEnum method = LogsFileUpdateMethodEnum.find(param.getStatus()); |
||||
if (LogsFileUpdateMethodEnum.UNKNOWN == method) { |
||||
return ResponseResult.error("Illegal param"); |
||||
} |
||||
String topic = TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + deviceSn + TopicConst.SERVICES_SUF; |
||||
String bid = UUID.randomUUID().toString(); |
||||
Optional<ServiceReply> serviceReply = messageSenderService.publishWithReply(topic, |
||||
CommonTopicResponse.<LogsFileUpdateParam>builder() |
||||
.tid(UUID.randomUUID().toString()) |
||||
.bid(bid) |
||||
.timestamp(System.currentTimeMillis()) |
||||
.method(ServicesMethodEnum.FILE_UPLOAD_UPDATE.getMethod()) |
||||
.data(param) |
||||
.build()); |
||||
|
||||
if (serviceReply.isEmpty()) { |
||||
return ResponseResult.error("No message reply received."); |
||||
} |
||||
ServiceReply reply = serviceReply.get(); |
||||
if (ResponseResult.CODE_SUCCESS != reply.getResult()) { |
||||
return ResponseResult.error("Error Code : " + reply.getResult()); |
||||
} |
||||
|
||||
return ResponseResult.success(); |
||||
} |
||||
|
||||
@Override |
||||
public void deleteLogs(String deviceSn, String logsId) { |
||||
mapper.delete(new LambdaUpdateWrapper<DeviceLogsEntity>() |
||||
.eq(DeviceLogsEntity::getLogsId, logsId).eq(DeviceLogsEntity::getDeviceSn, deviceSn)); |
||||
logsFileService.deleteFileByLogsId(logsId); |
||||
} |
||||
|
||||
@ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_FILE_UPLOAD_PROGRESS, outputChannel = ChannelName.OUTBOUND) |
||||
@Override |
||||
public void handleFileUploadProgress(CommonTopicReceiver receiver, MessageHeaders headers) { |
||||
String topic = headers.get(MqttHeaders.RECEIVED_TOPIC).toString(); |
||||
String sn = topic.substring((TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT).length(), |
||||
topic.indexOf(TopicConst.EVENTS_SUF)); |
||||
|
||||
if (receiver.getNeedReply() != null && receiver.getNeedReply() == 1) { |
||||
String replyTopic = headers.get(MqttHeaders.RECEIVED_TOPIC) + TopicConst._REPLY_SUF; |
||||
messageSenderService.publish(replyTopic, |
||||
CommonTopicResponse.builder() |
||||
.tid(receiver.getTid()) |
||||
.bid(receiver.getBid()) |
||||
.method(receiver.getMethod()) |
||||
.timestamp(System.currentTimeMillis()) |
||||
.data(ResponseResult.success()) |
||||
.build()); |
||||
} |
||||
|
||||
EventsReceiver<OutputLogsProgressReceiver> eventsReceiver = objectMapper.convertValue(receiver.getData(), |
||||
new TypeReference<EventsReceiver<OutputLogsProgressReceiver>>(){}); |
||||
|
||||
EventsReceiver<LogsOutputProgressDTO> webSocketData = new EventsReceiver<>(); |
||||
webSocketData.setBid(receiver.getBid()); |
||||
webSocketData.setSn(sn); |
||||
|
||||
DeviceDTO device = (DeviceDTO) redisOpsUtils.get(RedisConst.DEVICE_ONLINE_PREFIX + sn); |
||||
|
||||
try { |
||||
OutputLogsProgressReceiver output = eventsReceiver.getOutput(); |
||||
EventsResultStatusEnum statusEnum = EventsResultStatusEnum.find(output.getStatus()); |
||||
log.info("Logs upload progress: {}", output.toString()); |
||||
|
||||
String key = RedisConst.LOGS_FILE_PREFIX + sn; |
||||
LogsOutputProgressDTO progress; |
||||
boolean exist = redisOpsUtils.checkExist(key); |
||||
if (!exist && !statusEnum.getEnd()) { |
||||
progress = LogsOutputProgressDTO.builder().logsId(receiver.getBid()).build(); |
||||
redisOpsUtils.hashSet(key, receiver.getBid(), progress); |
||||
} else if (exist) { |
||||
progress = (LogsOutputProgressDTO) redisOpsUtils.hashGet(key, receiver.getBid()); |
||||
} else { |
||||
progress = LogsOutputProgressDTO.builder().build(); |
||||
} |
||||
progress.setStatus(output.getStatus()); |
||||
|
||||
// If the logs file is empty, delete the cache of this task.
|
||||
List<LogsExtFileReceiver> fileReceivers = output.getExt().getFiles(); |
||||
if (CollectionUtils.isEmpty(fileReceivers)) { |
||||
redisOpsUtils.del(RedisConst.LOGS_FILE_PREFIX + sn); |
||||
return; |
||||
} |
||||
|
||||
// refresh cache.
|
||||
List<LogsProgressDTO> fileProgressList = new ArrayList<>(); |
||||
fileReceivers.forEach(file -> { |
||||
LogsProgressReceiver logsProgress = file.getProgress(); |
||||
if (!StringUtils.hasText(file.getDeviceSn())) { |
||||
if (String.valueOf(DeviceDomainEnum.DOCK.getVal()).equals(file.getDeviceModelDomain())) { |
||||
file.setDeviceSn(sn); |
||||
} else if (String.valueOf(DeviceDomainEnum.SUB_DEVICE.getVal()).equals(file.getDeviceModelDomain())) { |
||||
file.setDeviceSn(device.getChildDeviceSn()); |
||||
} |
||||
} |
||||
|
||||
fileProgressList.add(LogsProgressDTO.builder() |
||||
.deviceSn(file.getDeviceSn()) |
||||
.deviceModelDomain(file.getDeviceModelDomain()) |
||||
.result(logsProgress.getResult()) |
||||
.status(logsProgress.getStatus()) |
||||
.uploadRate(logsProgress.getUploadRate()) |
||||
.progress(((logsProgress.getCurrentStep() - 1) * 100 + logsProgress.getProgress()) / logsProgress.getTotalStep()) |
||||
.build()); |
||||
}); |
||||
progress.setFiles(fileProgressList); |
||||
webSocketData.setOutput(progress); |
||||
redisOpsUtils.hashSet(RedisConst.LOGS_FILE_PREFIX + sn, receiver.getBid(), progress); |
||||
// Delete the cache at the end of the task.
|
||||
if (statusEnum.getEnd()) { |
||||
redisOpsUtils.del(RedisConst.LOGS_FILE_PREFIX + sn); |
||||
this.updateLogsStatus(receiver.getBid(), DeviceLogsStatusEnum.find(statusEnum).getVal()); |
||||
|
||||
fileReceivers.forEach(file -> logsFileService.updateFile(receiver.getBid(), file)); |
||||
} |
||||
} catch (NullPointerException e) { |
||||
this.updateLogsStatus(receiver.getBid(), DeviceLogsStatusEnum.FAILED.getVal()); |
||||
|
||||
redisOpsUtils.del(RedisConst.LOGS_FILE_PREFIX + sn); |
||||
} |
||||
|
||||
webSocketMessageService.sendBatch( |
||||
webSocketManageService.getValueWithWorkspaceAndUserType( |
||||
device.getWorkspaceId(), UserTypeEnum.WEB.getVal()), |
||||
CustomWebSocketMessage.builder() |
||||
.data(webSocketData) |
||||
.timestamp(System.currentTimeMillis()) |
||||
.bizCode(receiver.getMethod()) |
||||
.build()); |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public void updateLogsStatus(String logsId, Integer value) { |
||||
|
||||
mapper.update(DeviceLogsEntity.builder().status(value).build(), |
||||
new LambdaUpdateWrapper<DeviceLogsEntity>().eq(DeviceLogsEntity::getLogsId, logsId)); |
||||
if (DeviceLogsStatusEnum.DONE.getVal() == value) { |
||||
logsFileService.updateFileUploadStatus(logsId, true); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public URL getLogsFileUrl(String logsId, String fileId) { |
||||
return logsFileService.getLogsFileUrl(logsId, fileId); |
||||
} |
||||
|
||||
private DeviceLogsDTO entity2Dto(DeviceLogsEntity entity) { |
||||
if (Objects.isNull(entity)) { |
||||
return null; |
||||
} |
||||
String key = RedisConst.LOGS_FILE_PREFIX + entity.getDeviceSn(); |
||||
LogsOutputProgressDTO progress = new LogsOutputProgressDTO(); |
||||
if (redisOpsUtils.hashCheck(key, entity.getLogsId())) { |
||||
progress = (LogsOutputProgressDTO) redisOpsUtils.hashGet(key, entity.getLogsId()); |
||||
} |
||||
|
||||
return DeviceLogsDTO.builder() |
||||
.logsId(entity.getLogsId()) |
||||
.createTime(LocalDateTime.ofInstant(Instant.ofEpochMilli(entity.getCreateTime()), ZoneId.systemDefault())) |
||||
.happenTime(Objects.isNull(entity.getHappenTime()) ? |
||||
null : LocalDateTime.ofInstant(Instant.ofEpochMilli(entity.getHappenTime()), ZoneId.systemDefault())) |
||||
.status(entity.getStatus()) |
||||
.logsInformation(entity.getLogsInfo()) |
||||
.userName(entity.getUsername()) |
||||
.deviceLogs(LogsFileUploadList.builder().files(logsFileService.getLogsFileByLogsId(entity.getLogsId())).build()) |
||||
.logsProgress(progress.getFiles()) |
||||
.deviceTopo(topologyService.getDeviceTopologyByGatewaySn(entity.getDeviceSn()).orElse(null)) |
||||
.build(); |
||||
} |
||||
} |
@ -0,0 +1,108 @@
@@ -0,0 +1,108 @@
|
||||
package com.dji.sample.manage.service.impl; |
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
||||
import com.dji.sample.manage.dao.ILogsFileIndexMapper; |
||||
import com.dji.sample.manage.model.dto.LogsFileDTO; |
||||
import com.dji.sample.manage.model.entity.LogsFileIndexEntity; |
||||
import com.dji.sample.manage.model.receiver.LogsFile; |
||||
import com.dji.sample.manage.model.receiver.LogsFileUpload; |
||||
import com.dji.sample.manage.service.ILogsFileIndexService; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.stereotype.Service; |
||||
import org.springframework.transaction.annotation.Transactional; |
||||
import org.springframework.util.CollectionUtils; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
import java.util.Objects; |
||||
import java.util.Optional; |
||||
import java.util.stream.Collectors; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/9/8 |
||||
*/ |
||||
@Service |
||||
@Transactional |
||||
public class LogsFileIndexServiceImpl implements ILogsFileIndexService { |
||||
|
||||
@Autowired |
||||
private ILogsFileIndexMapper mapper; |
||||
|
||||
@Override |
||||
public Boolean insertFileIndex(LogsFile file, String deviceSn, Integer domain, String fileId) { |
||||
if (Objects.isNull(file)) { |
||||
return false; |
||||
} |
||||
LogsFileIndexEntity entity = this.logsFile2Entity(file); |
||||
entity.setDomain(domain); |
||||
entity.setDeviceSn(deviceSn); |
||||
entity.setFileId(fileId); |
||||
|
||||
return mapper.insert(entity) > 0; |
||||
} |
||||
|
||||
@Override |
||||
public List<LogsFileUpload> getFileIndexByFileIds(List<LogsFileDTO> files) { |
||||
List<LogsFileUpload> list = new ArrayList<>(); |
||||
files.forEach(file -> { |
||||
Optional<LogsFileUpload> fileOpt = this.getFileIndexByFileId(file.getFileId()); |
||||
fileOpt.ifPresent(fileUpload -> { |
||||
fileUpload.setObjectKey(file.getStatus() ? file.getObjectKey() : ""); |
||||
list.add(fileUpload); |
||||
}); |
||||
}); |
||||
return list; |
||||
} |
||||
|
||||
@Override |
||||
public void deleteFileIndexByFileIds(List<String> fileIds) { |
||||
mapper.delete(new LambdaUpdateWrapper<LogsFileIndexEntity>() |
||||
.or(wrapper -> fileIds.forEach(fileId -> wrapper.eq(LogsFileIndexEntity::getFileId, fileId)))); |
||||
} |
||||
|
||||
@Override |
||||
public Optional<LogsFileUpload> getFileIndexByFileId(String fileId) { |
||||
List<LogsFileIndexEntity> logsFileIndexList = mapper.selectList( |
||||
new LambdaQueryWrapper<LogsFileIndexEntity>().eq(LogsFileIndexEntity::getFileId, fileId)); |
||||
if (CollectionUtils.isEmpty(logsFileIndexList)) { |
||||
return Optional.empty(); |
||||
} |
||||
LogsFileIndexEntity entity = logsFileIndexList.get(0); |
||||
List<LogsFile> logsFileList = logsFileIndexList.stream().map(this::entity2LogsFile).collect(Collectors.toList()); |
||||
return Optional.of(LogsFileUpload.builder() |
||||
.deviceSn(entity.getDeviceSn()) |
||||
.deviceModelDomain(String.valueOf(entity.getDomain())) |
||||
.list(logsFileList) |
||||
.fileId(fileId) |
||||
.build()); |
||||
|
||||
} |
||||
|
||||
private LogsFile entity2LogsFile(LogsFileIndexEntity entity) { |
||||
if (Objects.isNull(entity)) { |
||||
return null; |
||||
} |
||||
return LogsFile.builder() |
||||
.bootIndex(entity.getBootIndex()) |
||||
.startTime(entity.getStartTime()) |
||||
.endTime(entity.getEndTime()) |
||||
.size(entity.getSize()) |
||||
.build(); |
||||
|
||||
} |
||||
|
||||
private LogsFileIndexEntity logsFile2Entity(LogsFile file) { |
||||
if (Objects.isNull(file)) { |
||||
return null; |
||||
} |
||||
return LogsFileIndexEntity.builder() |
||||
.bootIndex(file.getBootIndex()) |
||||
.size(file.getSize()) |
||||
.startTime(file.getStartTime()) |
||||
.endTime(file.getEndTime()) |
||||
.build(); |
||||
} |
||||
} |
@ -0,0 +1,163 @@
@@ -0,0 +1,163 @@
|
||||
package com.dji.sample.manage.service.impl; |
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
||||
import com.dji.sample.component.mqtt.model.EventsResultStatusEnum; |
||||
import com.dji.sample.component.oss.model.OssConfiguration; |
||||
import com.dji.sample.component.oss.service.impl.OssServiceContext; |
||||
import com.dji.sample.manage.dao.ILogsFileMapper; |
||||
import com.dji.sample.manage.model.dto.LogsFileDTO; |
||||
import com.dji.sample.manage.model.entity.LogsFileEntity; |
||||
import com.dji.sample.manage.model.receiver.LogsExtFileReceiver; |
||||
import com.dji.sample.manage.model.receiver.LogsFile; |
||||
import com.dji.sample.manage.model.receiver.LogsFileUpload; |
||||
import com.dji.sample.manage.service.ILogsFileIndexService; |
||||
import com.dji.sample.manage.service.ILogsFileService; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.stereotype.Service; |
||||
import org.springframework.transaction.annotation.Transactional; |
||||
import org.springframework.util.CollectionUtils; |
||||
|
||||
import java.net.URL; |
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
import java.util.Objects; |
||||
import java.util.UUID; |
||||
import java.util.stream.Collectors; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.2 |
||||
* @date 2022/9/7 |
||||
*/ |
||||
@Service |
||||
@Transactional |
||||
public class LogsFileServiceImpl implements ILogsFileService { |
||||
|
||||
@Autowired |
||||
private ILogsFileMapper mapper; |
||||
|
||||
@Autowired |
||||
private ILogsFileIndexService logsFileIndexService; |
||||
|
||||
@Autowired |
||||
private OssServiceContext ossService; |
||||
|
||||
@Autowired |
||||
private OssConfiguration configuration; |
||||
|
||||
@Autowired |
||||
private OssServiceContext ossServiceContext; |
||||
|
||||
@Override |
||||
public List<LogsFileDTO> getLogsFileInfoByLogsId(String logsId) { |
||||
return mapper.selectList( |
||||
new LambdaQueryWrapper<LogsFileEntity>() |
||||
.eq(LogsFileEntity::getLogsId, logsId)).stream() |
||||
.map(this::entity2Dto).collect(Collectors.toList()); |
||||
} |
||||
|
||||
private LogsFileDTO entity2Dto(LogsFileEntity entity) { |
||||
if (Objects.isNull(entity)) { |
||||
return null; |
||||
} |
||||
return LogsFileDTO.builder() |
||||
.deviceSn(entity.getDeviceSn()) |
||||
.fileId(entity.getFileId()) |
||||
.fingerprint(entity.getFingerprint()) |
||||
.logsId(entity.getLogsId()) |
||||
.name(entity.getName()) |
||||
.objectKey(entity.getObjectKey()) |
||||
.size(entity.getSize()) |
||||
.status(entity.getStatus()) |
||||
.build(); |
||||
} |
||||
|
||||
@Override |
||||
public List<LogsFileUpload> getLogsFileByLogsId(String logsId) { |
||||
List<LogsFileDTO> logsFiles = this.getLogsFileInfoByLogsId(logsId); |
||||
if (CollectionUtils.isEmpty(logsFiles)) { |
||||
return new ArrayList<>(); |
||||
} |
||||
return logsFileIndexService.getFileIndexByFileIds(logsFiles); |
||||
} |
||||
|
||||
@Override |
||||
public Boolean insertFile(LogsFileUpload file, String logsId) { |
||||
LogsFileEntity entity = LogsFileEntity.builder() |
||||
.logsId(logsId) |
||||
.fileId(UUID.randomUUID().toString()) |
||||
.objectKey(file.getObjectKey()) |
||||
.status(false) |
||||
.deviceSn(file.getDeviceSn()) |
||||
.build(); |
||||
boolean insert = mapper.insert(entity) > 0; |
||||
if (!insert) { |
||||
return false; |
||||
} |
||||
for (LogsFile logsFile : file.getList()) { |
||||
insert = logsFileIndexService.insertFileIndex(logsFile, file.getDeviceSn(), Integer.valueOf(file.getDeviceModelDomain()), entity.getFileId()); |
||||
if (!insert) { |
||||
return false; |
||||
} |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
@Override |
||||
public void deleteFileByLogsId(String logsId) { |
||||
List<LogsFileDTO> logsFiles = this.getLogsFileInfoByLogsId(logsId); |
||||
if (CollectionUtils.isEmpty(logsFiles)) { |
||||
return; |
||||
} |
||||
mapper.delete(new LambdaUpdateWrapper<LogsFileEntity>().eq(LogsFileEntity::getLogsId, logsId)); |
||||
List<String> fileIds = new ArrayList<>(); |
||||
logsFiles.forEach(file -> { |
||||
if (file.getStatus()) { |
||||
ossService.deleteObject(configuration.getBucket(), file.getObjectKey()); |
||||
} |
||||
fileIds.add(file.getFileId()); |
||||
}); |
||||
|
||||
logsFileIndexService.deleteFileIndexByFileIds(fileIds); |
||||
} |
||||
|
||||
@Override |
||||
public void updateFile(String logsId, LogsExtFileReceiver fileReceiver) { |
||||
List<LogsFileDTO> logsFiles = this.getLogsFileInfoByLogsId(logsId); |
||||
if (CollectionUtils.isEmpty(logsFiles)) { |
||||
return; |
||||
} |
||||
mapper.update(receiver2Entity(fileReceiver), |
||||
new LambdaUpdateWrapper<LogsFileEntity>().eq(LogsFileEntity::getLogsId, logsId) |
||||
.eq(LogsFileEntity::getDeviceSn, fileReceiver.getDeviceSn())); |
||||
} |
||||
|
||||
@Override |
||||
public void updateFileUploadStatus(String logsId, Boolean isUploaded) { |
||||
mapper.update(LogsFileEntity.builder().status(isUploaded).build(), |
||||
new LambdaUpdateWrapper<LogsFileEntity>().eq(LogsFileEntity::getLogsId, logsId)); |
||||
} |
||||
|
||||
@Override |
||||
public URL getLogsFileUrl(String logsId, String fileId) { |
||||
LogsFileEntity logsFile = mapper.selectOne(new LambdaQueryWrapper<LogsFileEntity>() |
||||
.eq(LogsFileEntity::getLogsId, logsId).eq(LogsFileEntity::getFileId, fileId)); |
||||
if (Objects.isNull(logsFile)) { |
||||
return null; |
||||
} |
||||
return ossService.getObjectUrl(configuration.getBucket(), logsFile.getObjectKey()); |
||||
} |
||||
|
||||
private LogsFileEntity receiver2Entity(LogsExtFileReceiver receiver) { |
||||
if (Objects.isNull(receiver)) { |
||||
return null; |
||||
} |
||||
return LogsFileEntity.builder() |
||||
.fingerprint(receiver.getFingerprint()) |
||||
.size(receiver.getSize()) |
||||
.status(Objects.nonNull(receiver.getProgress()) && |
||||
EventsResultStatusEnum.OK.getDesc().equals(receiver.getProgress().getStatus())) |
||||
.name(receiver.getKey().substring(receiver.getKey().lastIndexOf("/") + 1)).build(); |
||||
} |
||||
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue