| | |
| | | */ |
| | | public enum CommonErrorEnum implements IErrorInfo { |
| | | |
| | | ILLEGAL_ARGUMENT(200001, "illegal argument"), |
| | | ILLEGAL_ARGUMENT(200001, "非法参数"), |
| | | |
| | | REDIS_DATA_NOT_FOUND(201404, "Redis data does not exist."), |
| | | REDIS_DATA_NOT_FOUND(201404, "Redis数据不存在."), |
| | | |
| | | DEVICE_OFFLINE(212015, "Device is offline."), |
| | | DEVICE_OFFLINE(212015, "设备离线"), |
| | | |
| | | GET_ORGANIZATION_FAILED(210230, "Failed to get organization."), |
| | | GET_ORGANIZATION_FAILED(210230, "获取组织失败"), |
| | | |
| | | DEVICE_BINDING_FAILED(210231, "Failed to bind device."), |
| | | DEVICE_BINDING_FAILED(210231, "设备绑定失败"), |
| | | |
| | | NON_REPEATABLE_BINDING(210232, "The device has been bound to another organization and can't be bound repeatedly."), |
| | | NON_REPEATABLE_BINDING(210232, "设备已绑定到其他组织,不能重复绑定"), |
| | | |
| | | GET_DEVICE_BINDING_STATUS_FAILED(210233, "Failed to get device binding status."), |
| | | GET_DEVICE_BINDING_STATUS_FAILED(210233, "获取设备绑定状态失败"), |
| | | |
| | | SYSTEM_ERROR(600500, "system error"), |
| | | SYSTEM_ERROR(600500, "系统错误"), |
| | | |
| | | SECRET_INVALID(600100, "secret invalid"), |
| | | SECRET_INVALID(600100, "密钥无效"), |
| | | |
| | | NO_TOKEN(600101, "token is null"), |
| | | NO_TOKEN(600101, "token为空"), |
| | | |
| | | TOKEN_EXPIRED(600102, "token is expired"), |
| | | TOKEN_EXPIRED(600102, "token过期"), |
| | | |
| | | TOKEN_INVALID(600103, "token invalid"), |
| | | TOKEN_INVALID(600103, "token失效"), |
| | | |
| | | SIGN_INVALID(600104, "sign invalid"); |
| | | SIGN_INVALID(600104, "签名失效"); |
| | | |
| | | private String msg; |
| | | |
| | |
| | | @ExceptionHandler(NullPointerException.class) |
| | | public ResponseResult nullPointerExceptionHandler(NullPointerException e) { |
| | | e.printStackTrace(); |
| | | return ResponseResult.error("A null object appeared."); |
| | | return ResponseResult.error("出现空对象"); |
| | | } |
| | | |
| | | @ExceptionHandler({MethodArgumentNotValidException.class, BindException.class}) |
| | |
| | | */ |
| | | static MqttClientOptions getBasicClientOptions() { |
| | | if (!mqtt.containsKey(MqttUseEnum.BASIC)) { |
| | | throw new Error("Please configure the basic mqtt connection parameters first, otherwise application cannot be started."); |
| | | throw new Error("请先配置基本的mqtt连接参数,否则应用程序无法启动。"); |
| | | } |
| | | return mqtt.get(MqttUseEnum.BASIC); |
| | | } |
| | |
| | | public class AliyunOssServiceImpl implements IOssService { |
| | | |
| | | private OSS ossClient; |
| | | |
| | | |
| | | @Override |
| | | public String getOssType() { |
| | | return OssTypeEnum.ALIYUN.getType(); |
| | |
| | | // First check if the object can be fetched. |
| | | boolean isExist = ossClient.doesObjectExist(bucket, objectKey); |
| | | if (!isExist) { |
| | | throw new OSSException("The object does not exist."); |
| | | throw new OSSException("对象不存在"); |
| | | } |
| | | |
| | | return ossClient.generatePresignedUrl(bucket, objectKey, |
| | |
| | | @Override |
| | | public void putObject(String bucket, String objectKey, InputStream input) { |
| | | if (ossClient.doesObjectExist(bucket, objectKey)) { |
| | | throw new RuntimeException("The filename already exists."); |
| | | throw new RuntimeException("文件已存在"); |
| | | } |
| | | PutObjectResult objectResult = ossClient.putObject(new PutObjectRequest(bucket, objectKey, input, new ObjectMetadata())); |
| | | log.info("Upload File: {}", objectResult.getETag()); |
| | |
| | | public class AmazonS3ServiceImpl implements IOssService { |
| | | |
| | | private AmazonS3 client; |
| | | |
| | | |
| | | @Override |
| | | public String getOssType() { |
| | | return OssTypeEnum.AWS.getType(); |
| | |
| | | @Override |
| | | public void putObject(String bucket, String objectKey, InputStream input) { |
| | | if (client.doesObjectExist(bucket, objectKey)) { |
| | | throw new RuntimeException("The filename already exists."); |
| | | throw new RuntimeException("文件名已存在"); |
| | | } |
| | | PutObjectResult objectResult = client.putObject(new PutObjectRequest(bucket, objectKey, input, new ObjectMetadata())); |
| | | log.info("Upload File: {}", objectResult.toString()); |
| | |
| | | |
| | | client.setBucketCrossOriginConfiguration(OssConfiguration.bucket, |
| | | new BucketCrossOriginConfiguration().withRules(rule)); |
| | | |
| | | |
| | | } |
| | | } |
| | |
| | | public class MinIOServiceImpl implements IOssService { |
| | | |
| | | private MinioClient client; |
| | | |
| | | |
| | | @Override |
| | | public String getOssType() { |
| | | return OssTypeEnum.MINIO.getType(); |
| | |
| | | } catch (ErrorResponseException | InsufficientDataException | InternalException | |
| | | InvalidKeyException | InvalidResponseException | IOException | |
| | | NoSuchAlgorithmException | XmlParserException | ServerException e) { |
| | | throw new RuntimeException("The file does not exist on the OssConfiguration."); |
| | | throw new RuntimeException("OssConfiguration上不存在该文件."); |
| | | } |
| | | } |
| | | |
| | |
| | | public void putObject(String bucket, String objectKey, InputStream input) { |
| | | try { |
| | | client.statObject(StatObjectArgs.builder().bucket(bucket).object(objectKey).build()); |
| | | throw new RuntimeException("The filename already exists."); |
| | | throw new RuntimeException("文件名已存在"); |
| | | } catch (MinioException | InvalidKeyException | IOException | NoSuchAlgorithmException e) { |
| | | log.info("The file does not exist, start uploading."); |
| | | log.info("文件不存在,开始上传。"); |
| | | try { |
| | | ObjectWriteResponse response = client.putObject( |
| | | PutObjectArgs.builder().bucket(bucket).object(objectKey).stream(input, input.available(), 0).build()); |
| | |
| | | @Before("execution(public * com.dji.sample.component.oss.service.impl.OssServiceContext.*(..))") |
| | | public void before() { |
| | | if (!OssConfiguration.enable) { |
| | | throw new IllegalArgumentException("Please enable OssConfiguration."); |
| | | throw new IllegalArgumentException("请启用OssConfiguration"); |
| | | } |
| | | if (this.ossServiceContext.getOssService() == null) { |
| | | throw new IllegalArgumentException("Please check the OssConfiguration configuration."); |
| | | throw new IllegalArgumentException("请检查OssConfiguration配置"); |
| | | } |
| | | this.ossServiceContext.createClient(); |
| | | } |
| | |
| | | @Override |
| | | public void sendBatch(String workspaceId, Integer userType, String bizCode, Object data) { |
| | | if (!StringUtils.hasText(workspaceId)) { |
| | | throw new RuntimeException("项目id不存在;Workspace ID does not exist."); |
| | | throw new RuntimeException("项目id不存在:"+workspaceId); |
| | | } |
| | | Collection<ConcurrentWebSocketSession> sessions = Objects.isNull(userType) ? |
| | | webSocketManageService.getValueWithWorkspace(workspaceId) : |
| | |
| | | Optional<DeviceDTO> deviceOpt = deviceRedisService.getDeviceOnline(sn); |
| | | |
| | | if (deviceOpt.isEmpty()) { |
| | | throw new RuntimeException("The device is offline."); |
| | | throw new RuntimeException("设备离线."); |
| | | } |
| | | |
| | | DeviceDTO device = deviceOpt.get(); |
| | |
| | | // TODO 设备固件版本不兼容情况 |
| | | Optional<DeviceDTO> dockOpt = deviceRedisService.getDeviceOnline(dockSn); |
| | | if (dockOpt.isEmpty()) { |
| | | throw new RuntimeException("The dock is offline, please restart the dock."); |
| | | throw new RuntimeException("机场离线请重启机场"); |
| | | } |
| | | |
| | | DeviceModeCodeEnum deviceMode = deviceService.getDeviceMode(dockOpt.get().getChildDeviceSn()); |
| | | if (DeviceModeCodeEnum.MANUAL != deviceMode) { |
| | | throw new RuntimeException("The current state of the drone does not support this function, please try again later."); |
| | | throw new RuntimeException("无人机当前状态不支持此功能,请稍后再试"); |
| | | } |
| | | |
| | | ResponseResult result = seizeAuthority(dockSn, DroneAuthorityEnum.FLIGHT, null); |
| | |
| | | param.setFlyToId(UUID.randomUUID().toString()); |
| | | ServiceReply reply = messageSenderService.publishServicesTopic(sn, DroneControlMethodEnum.FLY_TO_POINT.getMethod(), param, param.getFlyToId()); |
| | | return ResponseResult.CODE_SUCCESS != reply.getResult() ? |
| | | ResponseResult.error("Flying to the target point failed." + reply.getResult()) |
| | | ResponseResult.error("飞向目标点失败。" + reply.getResult()) |
| | | : ResponseResult.success(); |
| | | } |
| | | |
| | |
| | | public ResponseResult flyToPointStop(String sn) { |
| | | ServiceReply reply = messageSenderService.publishServicesTopic(sn, DroneControlMethodEnum.FLY_TO_POINT_STOP.getMethod(), null); |
| | | return ResponseResult.CODE_SUCCESS != reply.getResult() ? |
| | | ResponseResult.error("The drone flying to the target point failed to stop. " + reply.getResult()) |
| | | ResponseResult.error("飞向目标点的无人机停止失败" + reply.getResult()) |
| | | : ResponseResult.success(); |
| | | } |
| | | |
| | |
| | | |
| | | Optional<DeviceDTO> deviceOpt = deviceRedisService.getDeviceOnline(dockSn); |
| | | if (deviceOpt.isEmpty()) { |
| | | log.error("The dock is offline."); |
| | | log.error("机场离线"); |
| | | return null; |
| | | } |
| | | |
| | |
| | | private void checkTakeoffCondition(String dockSn) { |
| | | Optional<DeviceDTO> dockOpt = deviceRedisService.getDeviceOnline(dockSn); |
| | | if (dockOpt.isEmpty() || DockModeCodeEnum.IDLE != deviceService.getDockMode(dockSn)) { |
| | | throw new RuntimeException("The current state does not support takeoff."); |
| | | throw new RuntimeException("当前状态不支持起飞"); |
| | | } |
| | | |
| | | ResponseResult result = seizeAuthority(dockSn, DroneAuthorityEnum.FLIGHT, null); |
| | |
| | | param.setFlightId(UUID.randomUUID().toString()); |
| | | ServiceReply reply = messageSenderService.publishServicesTopic(sn, DroneControlMethodEnum.TAKE_OFF_TO_POINT.getMethod(), param, param.getFlightId()); |
| | | return ResponseResult.CODE_SUCCESS != reply.getResult() ? |
| | | ResponseResult.error("The drone failed to take off. " + reply.getResult()) |
| | | ResponseResult.error("无人机起飞失败 " + reply.getResult()) |
| | | : ResponseResult.success(); |
| | | } |
| | | |
| | |
| | | |
| | | Optional<DeviceDTO> deviceOpt = deviceRedisService.getDeviceOnline(dockSn); |
| | | if (deviceOpt.isEmpty()) { |
| | | log.error("The dock is offline."); |
| | | log.error("机场离线"); |
| | | return null; |
| | | } |
| | | TakeoffProgressReceiver eventsReceiver = mapper.convertValue(receiver.getData(), new TypeReference<TakeoffProgressReceiver>(){}); |
| | |
| | | } |
| | | ServiceReply serviceReply = messageSenderService.publishServicesTopic(sn, method, param); |
| | | return ResponseResult.CODE_SUCCESS != serviceReply.getResult() ? |
| | | ResponseResult.error(serviceReply.getResult(), "Method: " + method + " Error Code:" + serviceReply.getResult()) |
| | | ResponseResult.error(serviceReply.getResult(), "方法: " + method + " 错误码:" + serviceReply.getResult()) |
| | | : ResponseResult.success(); |
| | | } |
| | | |
| | | private Boolean checkPayloadAuthority(String sn, String payloadIndex) { |
| | | Optional<DeviceDTO> dockOpt = deviceRedisService.getDeviceOnline(sn); |
| | | if (dockOpt.isEmpty()) { |
| | | throw new RuntimeException("The dock is offline, please restart the dock."); |
| | | throw new RuntimeException("机场离线请重启机场"); |
| | | } |
| | | return devicePayloadService.checkAuthorityPayload(dockOpt.get().getChildDeviceSn(), payloadIndex); |
| | | } |
| | |
| | | |
| | | ServiceReply serviceReply = messageSenderService.publishServicesTopic(param.getSn(), param.getCmd().getCmd(), param.getData()); |
| | | return ResponseResult.CODE_SUCCESS != serviceReply.getResult() ? |
| | | ResponseResult.error(serviceReply.getResult(), " Error Code:" + serviceReply.getResult()) |
| | | ResponseResult.error(serviceReply.getResult(), "错误码:" + serviceReply.getResult()) |
| | | : ResponseResult.success(); |
| | | } |
| | | |
| | |
| | | public ResponseResult requestsConfig(String sn,String method, RequestsParam param) { |
| | | ServiceReply serviceReply = messageSenderService.publishRequestsTopic(sn, method, param); |
| | | return ResponseResult.CODE_SUCCESS != serviceReply.getResult() ? |
| | | ResponseResult.error(serviceReply.getResult(), " Error Code:" + serviceReply.getResult()) |
| | | ResponseResult.error(serviceReply.getResult(), "错误码:" + serviceReply.getResult()) |
| | | : ResponseResult.success(); |
| | | } |
| | | |
| | |
| | | |
| | | @Autowired |
| | | private IDeviceService deviceService; |
| | | |
| | | |
| | | @Autowired |
| | | private ObjectMapper mapper; |
| | | |
| | | |
| | | @Autowired |
| | | private ISendMessageService webSocketMessageService; |
| | | |
| | |
| | | @Override |
| | | public void deviceDrcExit(String workspaceId, DrcModeParam param) { |
| | | if (!deviceService.checkDockDrcMode(param.getDockSn())) { |
| | | throw new RuntimeException("The dock is not in flight control mode."); |
| | | throw new RuntimeException("机场没有进入飞行控制模式"); |
| | | } |
| | | ServiceReply reply = messageSenderService.publishServicesTopic( |
| | | param.getDockSn(), DrcMethodEnum.DRC_MODE_EXIT.getMethod(), ""); |
| | | if (ResponseResult.CODE_SUCCESS != reply.getResult()) { |
| | | throw new RuntimeException("SN: " + param.getDockSn() + "; Error Code:" + |
| | | reply.getResult() + "; Failed to exit command flight control mode, please try again later!"); |
| | | reply.getResult() + "; 命令飞行控制模式退出失败,请稍后再试!"); |
| | | } |
| | | |
| | | String jobId = waylineRedisService.getPausedWaylineJobId(param.getDockSn()); |
| | |
| | | Optional<OsdSubDeviceReceiver> deviceOpt = SpringBeanUtils.getBean(IDeviceRedisService.class) |
| | | .getDeviceOsd(deviceSn, OsdSubDeviceReceiver.class); |
| | | if (deviceOpt.isEmpty()) { |
| | | throw new RuntimeException("The device is offline."); |
| | | throw new RuntimeException("设备离线"); |
| | | } |
| | | osdCamera = deviceOpt.get().getCameras().stream() |
| | | .filter(osdCamera -> param.getPayloadIndex().equals(osdCamera.getPayloadIndex())) |
| | | .findAny() |
| | | .orElseThrow(() -> new RuntimeException("Did not receive osd information about the camera, please check the cache data.")); |
| | | .orElseThrow(() -> new RuntimeException("没有收到相机osd信息,请检查缓存数据")); |
| | | return true; |
| | | } |
| | | |
| | | private String checkDockOnline(String dockSn) { |
| | | Optional<DeviceDTO> deviceOpt = SpringBeanUtils.getBean(IDeviceRedisService.class).getDeviceOnline(dockSn); |
| | | if (deviceOpt.isEmpty()) { |
| | | throw new RuntimeException("The dock is offline."); |
| | | throw new RuntimeException("设备离线"); |
| | | } |
| | | return deviceOpt.get().getChildDeviceSn(); |
| | | } |
| | |
| | | private void checkDeviceOnline(String deviceSn) { |
| | | boolean isOnline = SpringBeanUtils.getBean(IDeviceRedisService.class).checkDeviceOnline(deviceSn); |
| | | if (!isOnline) { |
| | | throw new RuntimeException("The device is offline."); |
| | | throw new RuntimeException("设备离线"); |
| | | } |
| | | } |
| | | |
| | |
| | | boolean hasAuthority = SpringBeanUtils.getBean(IDevicePayloadService.class) |
| | | .checkAuthorityPayload(deviceSn, param.getPayloadIndex()); |
| | | if (!hasAuthority) { |
| | | throw new RuntimeException("The device does not have payload control authority."); |
| | | throw new RuntimeException("设备没有有效载荷控制权限"); |
| | | } |
| | | } |
| | | |
| | | public final void checkCondition(String dockSn) { |
| | | if (!valid()) { |
| | | throw new RuntimeException("illegal argument"); |
| | | throw new RuntimeException("非法参数"); |
| | | } |
| | | |
| | | String deviceSn = checkDockOnline(dockSn); |
| | |
| | | checkAuthority(deviceSn); |
| | | |
| | | if (!canPublish(deviceSn)) { |
| | | throw new RuntimeException("The current state of the drone does not support this function, please try again later."); |
| | | throw new RuntimeException("无人机当前状态不支持此功能,请稍后再试"); |
| | | } |
| | | } |
| | | |
| | |
| | | public ResponseResult getDevice(@PathVariable("workspace_id") String workspaceId, |
| | | @PathVariable("device_sn") String deviceSn) { |
| | | Optional<DeviceDTO> deviceOpt = deviceService.getDeviceBySn(deviceSn); |
| | | return deviceOpt.isEmpty() ? ResponseResult.error("device not found.") : ResponseResult.success(deviceOpt.get()); |
| | | return deviceOpt.isEmpty() ? ResponseResult.error("设备未找到") : ResponseResult.success(deviceOpt.get()); |
| | | } |
| | | |
| | | /** |
| | |
| | | deviceService.devicePropertySet(workspaceId, dockSn, propertyEnumOpt.get(), param.get(property)); |
| | | return ResponseResult.success(); |
| | | } |
| | | } |
| | | } |
| | |
| | | @Valid DeviceFirmwareUploadParam param) { |
| | | |
| | | if (!file.getOriginalFilename().endsWith(FirmwareFileProperties.FIRMWARE_FILE_SUFFIX)) { |
| | | return ResponseResult.error("The file format is incorrect."); |
| | | return ResponseResult.error("文件格式不正确"); |
| | | } |
| | | |
| | | CustomClaim customClaim = (CustomClaim)request.getAttribute(TOKEN_CLAIM); |
| | |
| | | URL url = deviceLogsService.getLogsFileUrl(logsId, fileId); |
| | | return ResponseResult.success(url.toString()); |
| | | } catch (Exception e) { |
| | | log.error("Failed to get the logs file download address."); |
| | | log.error("获取日志文件下载地址失败"); |
| | | e.printStackTrace(); |
| | | } |
| | | return ResponseResult.error("Failed to get the logs file download address."); |
| | | return ResponseResult.error("获取日志文件下载地址失败"); |
| | | } |
| | | } |
| | |
| | | Objects.nonNull(distanceLimitStatus.getDistanceLimit()) && |
| | | distanceLimitStatus.getDistanceLimit().intValue() != this.distanceLimit; |
| | | default: |
| | | throw new RuntimeException("Property " + fieldName + " does not exist."); |
| | | throw new RuntimeException("属性 " + fieldName + " 不存在"); |
| | | } |
| | | } |
| | | } |
| | |
| | | Objects.nonNull(obstacleAvoidance.getDownside()) && |
| | | obstacleAvoidance.getDownside().intValue() != this.downside; |
| | | default: |
| | | throw new RuntimeException("Property " + fieldName + " does not exist."); |
| | | throw new RuntimeException("属性 " + fieldName + "不存在"); |
| | | } |
| | | } |
| | | } |
| | |
| | | upgradeDTOS.forEach(upgradeDevice -> { |
| | | boolean exist = deviceRedisService.checkDeviceOnline(upgradeDevice.getSn()); |
| | | if (!exist) { |
| | | throw new IllegalArgumentException("Device is offline."); |
| | | throw new IllegalArgumentException("设备离线"); |
| | | } |
| | | Optional<DeviceFirmwareDTO> firmwareOpt = this.getFirmware( |
| | | workspaceId, upgradeDevice.getDeviceName(), upgradeDevice.getProductVersion()); |
| | | if (firmwareOpt.isEmpty()) { |
| | | throw new IllegalArgumentException("This firmware version does not exist or is not available."); |
| | | throw new IllegalArgumentException("此固件版本不存在或不可用"); |
| | | } |
| | | DeviceOtaCreateParam ota = dto2OtaCreateDto(firmwareOpt.get()); |
| | | ota.setSn(upgradeDevice.getSn()); |
| | |
| | | String key = RedisConst.FILE_UPLOADING_PREFIX + workspaceId; |
| | | String existKey = key + file.getOriginalFilename(); |
| | | if (RedisOpsUtils.getExpire(existKey) > 0) { |
| | | throw new RuntimeException("Please try again later."); |
| | | throw new RuntimeException("请稍后再试"); |
| | | } |
| | | RedisOpsUtils.setWithExpire(existKey, true, RedisConst.DEVICE_ALIVE_SECOND); |
| | | try (InputStream is = file.getInputStream()) { |
| | |
| | | key += md5; |
| | | boolean exist = checkFileExist(workspaceId, md5); |
| | | if (exist) { |
| | | throw new RuntimeException("The file already exists."); |
| | | throw new RuntimeException("文件已存在"); |
| | | } |
| | | RedisOpsUtils.set(key, System.currentTimeMillis()); |
| | | Optional<DeviceFirmwareDTO> firmwareOpt = verifyFirmwareFile(file); |
| | | if (firmwareOpt.isEmpty()) { |
| | | throw new RuntimeException("The file format is incorrect."); |
| | | throw new RuntimeException("文件格式不正确"); |
| | | } |
| | | |
| | | String firmwareId = UUID.randomUUID().toString(); |
| | |
| | | Optional<DeviceDomainEnum> domainEnumOpt = Optional.ofNullable(receiver.getDeviceType()) |
| | | .map(type -> type.split("-")).map(type -> type[0]).map(Integer::parseInt).map(DeviceDomainEnum::find); |
| | | if (domainEnumOpt.isEmpty()) { |
| | | throw new RuntimeException("The device type does not match, please check the data."); |
| | | throw new RuntimeException("设备类型不匹配,请检查数据"); |
| | | } |
| | | if (DeviceDomainEnum.DOCK == domainEnumOpt.get()) { |
| | | dto.setHmsKey(HmsEnum.HmsFaqIdEnum.DOCK_TIP.getText() + receiver.getCode()); |
| | |
| | | public ResponseResult getRealTimeLogs(String deviceSn, List<String> domainList) { |
| | | boolean exist = deviceRedisService.checkDeviceOnline(deviceSn); |
| | | if (!exist) { |
| | | return ResponseResult.error("Device is offline."); |
| | | return ResponseResult.error("设备离线"); |
| | | } |
| | | |
| | | ServiceReply<List<LogsFileUpload>> data = messageSenderService.publishServicesTopic( |
| | |
| | | |
| | | String logsId = this.insertDeviceLogs(bid, username, deviceSn, param); |
| | | if (!bid.equals(logsId)) { |
| | | return ResponseResult.error("Database insert failed."); |
| | | return ResponseResult.error("数据库插入失败"); |
| | | } |
| | | |
| | | // Save the status of the log upload. |
| | |
| | | public ResponseResult pushUpdateFile(String deviceSn, LogsFileUpdateParam param) { |
| | | LogsFileUpdateMethodEnum method = LogsFileUpdateMethodEnum.find(param.getStatus()); |
| | | if (LogsFileUpdateMethodEnum.UNKNOWN == method) { |
| | | return ResponseResult.error("Illegal param"); |
| | | return ResponseResult.error("非法参数"); |
| | | } |
| | | ServiceReply reply = messageSenderService.publishServicesTopic( |
| | | deviceSn, LogsFileMethodEnum.FILE_UPLOAD_UPDATE.getMethod(), param); |
| | | |
| | | if (ResponseResult.CODE_SUCCESS != reply.getResult()) { |
| | | return ResponseResult.error("Error Code : " + reply.getResult()); |
| | | return ResponseResult.error("错误码:" + reply.getResult()); |
| | | } |
| | | |
| | | return ResponseResult.success(); |
| | |
| | | |
| | | Optional<DeviceDTO> deviceOpt = deviceRedisService.getDeviceOnline(deviceOtaFirmwares.get(0).getSn()); |
| | | if (deviceOpt.isEmpty()) { |
| | | throw new RuntimeException("Device is offline."); |
| | | throw new RuntimeException("设备离线"); |
| | | } |
| | | DeviceDTO device = deviceOpt.get(); |
| | | String gatewaySn = DeviceDomainEnum.DOCK.getVal() == device.getDomain() ? device.getDeviceSn() : device.getParentSn(); |
| | |
| | | ServiceReply serviceReply = messageSender.publishServicesTopic( |
| | | gatewaySn, FirmwareMethodEnum.OTA_CREATE.getMethod(), Map.of(MapKeyConst.DEVICES, deviceOtaFirmwares), bid); |
| | | if (serviceReply.getResult() != ResponseResult.CODE_SUCCESS) { |
| | | return ResponseResult.error(serviceReply.getResult(), "Firmware Error Code: " + serviceReply.getResult()); |
| | | return ResponseResult.error(serviceReply.getResult(), "硬件错误码 " + serviceReply.getResult()); |
| | | } |
| | | |
| | | // Record the device state that needs to be updated. |
| | |
| | | private void checkOtaConditions(String dockSn) { |
| | | Optional<OsdDockReceiver> deviceOpt = deviceRedisService.getDeviceOsd(dockSn, OsdDockReceiver.class); |
| | | if (deviceOpt.isEmpty()) { |
| | | throw new RuntimeException("Dock is offline."); |
| | | throw new RuntimeException("机场离线"); |
| | | } |
| | | boolean emergencyStopState = deviceOpt.get().getEmergencyStopState(); |
| | | if (emergencyStopState) { |
| | | throw new RuntimeException("The emergency stop button of the dock is pressed and can't be upgraded."); |
| | | // throw new RuntimeException("The emergency stop button of the dock is pressed and can't be upgraded."); |
| | | throw new RuntimeException("机场急停按钮被按下,无法升级"); |
| | | } |
| | | |
| | | DockModeCodeEnum dockMode = this.getDockMode(dockSn); |
| | | if (DockModeCodeEnum.IDLE != dockMode) { |
| | | throw new RuntimeException("The current status of the dock can't be upgraded."); |
| | | throw new RuntimeException("当前机场状态无法升级"); |
| | | } |
| | | } |
| | | |
| | |
| | | public void devicePropertySet(String workspaceId, String dockSn, DeviceSetPropertyEnum propertyEnum, JsonNode param) { |
| | | Optional<DeviceDTO> dockOpt = deviceRedisService.getDeviceOnline(dockSn); |
| | | if (dockOpt.isEmpty()) { |
| | | throw new RuntimeException("Dock is offline."); |
| | | throw new RuntimeException("机场离线"); |
| | | } |
| | | String childSn = dockOpt.get().getChildDeviceSn(); |
| | | boolean deviceOnline = deviceRedisService.checkDeviceOnline(childSn); |
| | | Optional<OsdSubDeviceReceiver> osdOpt = deviceRedisService.getDeviceOsd(childSn, OsdSubDeviceReceiver.class); |
| | | if (!deviceOnline || osdOpt.isEmpty()) { |
| | | throw new RuntimeException("Device is offline."); |
| | | throw new RuntimeException("设备离线"); |
| | | } |
| | | |
| | | // Make sure the data is valid. |
| | |
| | | |
| | | SetReply setReply = objectMapper.convertValue(reply, SetReply.class); |
| | | if (SetReplyStatusResultEnum.SUCCESS.getVal() != setReply.getResult()) { |
| | | throw new RuntimeException("Failed to set " + value.getKey() + "; Error Code: " + setReply.getResult()); |
| | | throw new RuntimeException("设置失败" + value.getKey() + "; 错误码: " + setReply.getResult()); |
| | | } |
| | | |
| | | } |
| | |
| | | if (userEntity == null) { |
| | | return ResponseResult.builder() |
| | | .code(HttpStatus.UNAUTHORIZED.value()) |
| | | .message("invalid username") |
| | | .message("无效的用户名") |
| | | .build(); |
| | | } |
| | | |
| | |
| | | if (userEntity == null) { |
| | | return ResponseResult.builder() |
| | | .code(HttpStatus.UNAUTHORIZED.value()) |
| | | .message("invalid username") |
| | | .message("无效的用户名") |
| | | .build(); |
| | | } |
| | | if (flag.intValue() != userEntity.getUserType().intValue()) { |
| | | return ResponseResult.error("The account type does not match."); |
| | | return ResponseResult.error("帐户类型不匹配"); |
| | | } |
| | | if (!password.equals(userEntity.getPassword())) { |
| | | return ResponseResult.builder() |
| | | .code(HttpStatus.UNAUTHORIZED.value()) |
| | | .message("invalid password") |
| | | .message("无效的密码") |
| | | .build(); |
| | | } |
| | | |
| | |
| | | if (workspaceOpt.isEmpty()) { |
| | | return ResponseResult.builder() |
| | | .code(HttpStatus.UNAUTHORIZED.value()) |
| | | .message("invalid workspace id") |
| | | .message("无效的项目id") |
| | | .build(); |
| | | } |
| | | |
| | |
| | | public ResponseResult saveElement(String groupId, ElementCreateDTO elementCreate) { |
| | | boolean saveElement = groupElementService.saveElement(groupId, elementCreate); |
| | | if (!saveElement) { |
| | | return ResponseResult.error("Failed to save the element."); |
| | | return ResponseResult.error("保存元素失败"); |
| | | } |
| | | |
| | | // save coordinate |
| | |
| | | elementCreate.getResource().getContent().getGeometry().convertToList(), elementCreate.getId()); |
| | | |
| | | return saveCoordinate ? |
| | | ResponseResult.success() : ResponseResult.error("Failed to save the coordinate."); |
| | | ResponseResult.success() : ResponseResult.error("保存坐标失败"); |
| | | } |
| | | |
| | | |
| | |
| | | public ResponseResult updateElement(String elementId, ElementUpdateDTO elementUpdate, String username) { |
| | | boolean updElement = groupElementService.updateElement(elementId, elementUpdate, username); |
| | | if (!updElement) { |
| | | return ResponseResult.error("Failed to update the element."); |
| | | return ResponseResult.error("更新元素失败"); |
| | | } |
| | | |
| | | // delete all coordinates according to element id. |
| | |
| | | elementUpdate.getContent().getGeometry().convertToList(), elementId); |
| | | |
| | | return delCoordinate && saveCoordinate ? |
| | | ResponseResult.success() : ResponseResult.error("Failed to update the coordinate."); |
| | | ResponseResult.success() : ResponseResult.error("更新坐标失败"); |
| | | } |
| | | |
| | | @Override |
| | | public ResponseResult deleteElement(String elementId) { |
| | | boolean delElement = groupElementService.deleteElement(elementId); |
| | | if (!delElement) { |
| | | return ResponseResult.error("Failed to delete the element."); |
| | | return ResponseResult.error("删除元素失败"); |
| | | } |
| | | |
| | | // delete all coordinates according to element id. |
| | | boolean delCoordinate = elementCoordinateService.deleteCoordinateByElementId(elementId); |
| | | |
| | | return delCoordinate ? |
| | | ResponseResult.success() : ResponseResult.error("Failed to delete the coordinate."); |
| | | ResponseResult.success() : ResponseResult.error("删除坐标失败"); |
| | | } |
| | | |
| | | @Override |
| | |
| | | |
| | | boolean isExist = mediaService.fastUpload(workspaceId, file.getFingerprint()); |
| | | |
| | | return isExist ? ResponseResult.success() : ResponseResult.error(file.getFingerprint() + "don't exist."); |
| | | return isExist ? ResponseResult.success() : ResponseResult.error(file.getFingerprint() + "不存在"); |
| | | } |
| | | |
| | | /** |
| | |
| | | public URL getObjectUrl(String workspaceId, String fileId) { |
| | | Optional<MediaFileEntity> mediaFileOpt = getMediaByFileId(workspaceId, fileId); |
| | | if (mediaFileOpt.isEmpty()) { |
| | | throw new IllegalArgumentException("{} doesn't exist."); |
| | | throw new IllegalArgumentException("{} 不存在"); |
| | | } |
| | | |
| | | return ossService.getObjectUrl(OssConfiguration.bucket, mediaFileOpt.get().getObjectKey()); |
| | |
| | | public ResponseResult deleteWayline(@PathVariable(name = "workspace_id") String workspaceId, |
| | | @PathVariable(name = "wayline_id") String waylineId) { |
| | | boolean isDel = waylineFileService.deleteByWaylineId(workspaceId, waylineId); |
| | | return isDel ? ResponseResult.success() : ResponseResult.error("Failed to delete wayline."); |
| | | return isDel ? ResponseResult.success() : ResponseResult.error("航线删除失败"); |
| | | } |
| | | |
| | | /** |
| | |
| | | @PostMapping("/{workspace_id}/waylines/file/upload") |
| | | public ResponseResult importKmzFile(@PathVariable(name = "workspace_id") String workspaceId,HttpServletRequest request, MultipartFile file) { |
| | | if (Objects.isNull(file)) { |
| | | return ResponseResult.error("No file received."); |
| | | return ResponseResult.error("未上传文件"); |
| | | } |
| | | CustomClaim customClaim = (CustomClaim)request.getAttribute(TOKEN_CLAIM); |
| | | String creator = customClaim.getUsername(); |
| | |
| | | public URL getObjectUrl(String workspaceId, String waylineId) throws SQLException { |
| | | Optional<WaylineFileDTO> waylineOpt = this.getWaylineByWaylineId(workspaceId, waylineId); |
| | | if (waylineOpt.isEmpty()) { |
| | | throw new SQLException(waylineId + " does not exist."); |
| | | throw new SQLException(waylineId + " 不存在"); |
| | | } |
| | | return ossService.getObjectUrl(OssConfiguration.bucket, waylineOpt.get().getObjectKey()); |
| | | } |
| | |
| | | if (!StringUtils.hasText(file.getSign())) { |
| | | try (InputStream object = ossService.getObject(OssConfiguration.bucket, metadata.getObjectKey())) { |
| | | if (object.available() == 0) { |
| | | throw new RuntimeException("The file " + metadata.getObjectKey() + |
| | | " does not exist in the bucket[" + OssConfiguration.bucket + "]."); |
| | | throw new RuntimeException("文件" + metadata.getObjectKey() + |
| | | " 在空间中不存在[" + OssConfiguration.bucket + "]."); |
| | | } |
| | | file.setSign(DigestUtils.md5DigestAsHex(object)); |
| | | } catch (IOException e) { |
| | |
| | | public void importKmzFile(MultipartFile file, String workspaceId, String creator) { |
| | | Optional<WaylineFileDTO> waylineFileOpt = validKmzFile(file); |
| | | if (waylineFileOpt.isEmpty()) { |
| | | throw new RuntimeException("The file format is incorrect."); |
| | | throw new RuntimeException("文件格式错误"); |
| | | } |
| | | |
| | | try { |
| | |
| | | private Optional<WaylineFileDTO> validKmzFile(MultipartFile file) { |
| | | String filename = file.getOriginalFilename(); |
| | | if (Objects.nonNull(filename) && !filename.endsWith(WAYLINE_FILE_SUFFIX)) { |
| | | throw new RuntimeException("The file format is incorrect."); |
| | | throw new RuntimeException("文件格式错误"); |
| | | } |
| | | try (ZipInputStream unzipFile = new ZipInputStream(file.getInputStream(), StandardCharsets.UTF_8)) { |
| | | |
| | |
| | | SAXReader reader = new SAXReader(); |
| | | Document document = reader.read(unzipFile); |
| | | if (!StandardCharsets.UTF_8.name().equals(document.getXMLEncoding())) { |
| | | throw new RuntimeException("The file encoding format is incorrect."); |
| | | throw new RuntimeException("文件编码格式错误"); |
| | | } |
| | | |
| | | Node droneNode = document.selectSingleNode("//" + KmzFileProperties.TAG_WPML_PREFIX + KmzFileProperties.TAG_DRONE_INFO); |
| | | Node payloadNode = document.selectSingleNode("//" + KmzFileProperties.TAG_WPML_PREFIX + KmzFileProperties.TAG_PAYLOAD_INFO); |
| | | if (Objects.isNull(droneNode) || Objects.isNull(payloadNode)) { |
| | | throw new RuntimeException("The file format is incorrect."); |
| | | throw new RuntimeException("文件格式错误"); |
| | | } |
| | | |
| | | String type = droneNode.valueOf(KmzFileProperties.TAG_WPML_PREFIX + KmzFileProperties.TAG_DRONE_ENUM_VALUE); |
| | |
| | | if (!StringUtils.hasText(type) || !StringUtils.hasText(subType) || |
| | | !StringUtils.hasText(payloadSubType) || !StringUtils.hasText(payloadType) || |
| | | !StringUtils.hasText(templateType)) { |
| | | throw new RuntimeException("The file format is incorrect."); |
| | | throw new RuntimeException("文件格式错误"); |
| | | } |
| | | |
| | | return Optional.of(WaylineFileDTO.builder() |
| | |
| | | LocalDateTime.of(date, LocalTime.ofInstant(Instant.ofEpochSecond(taskPeriod.get(1)), ZoneId.systemDefault())) |
| | | .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() : beginTime; |
| | | if (WaylineTaskTypeEnum.IMMEDIATE != param.getTaskType() && endTime < System.currentTimeMillis()) { |
| | | return ResponseResult.error("The task has expired."); |
| | | return ResponseResult.error("任务已过期"); |
| | | } |
| | | Optional<WaylineJobDTO> waylineJobOpt = this.createWaylineJob(param, customClaim.getWorkspaceId(), customClaim.getUsername(), beginTime, endTime); |
| | | if (waylineJobOpt.isEmpty()) { |
| | | throw new SQLException("Failed to create wayline job."); |
| | | throw new SQLException("任务创建失败"); |
| | | } |
| | | WaylineJobDTO waylineJob = waylineJobOpt.get(); |
| | | // If it is a conditional task type, add conditions to the job parameters. |
| | |
| | | // value: {workspace_id}:{dock_sn}:{job_id} |
| | | boolean isAdd = waylineRedisService.addPreparedWaylineJob(waylineJob); |
| | | if (!isAdd) { |
| | | throw new RuntimeException("Failed to create prepare job."); |
| | | throw new RuntimeException("创建准备任务失败。"); |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | boolean isSuccess = this.prepareFlightTask(waylineJob); |
| | | if (!isSuccess) { |
| | | return ResponseResult.error("Failed to prepare job."); |
| | | return ResponseResult.error("任务准备失败"); |
| | | } |
| | | |
| | | // Issue an immediate task execution command. |
| | | if (WaylineTaskTypeEnum.IMMEDIATE == waylineJob.getTaskType()) { |
| | | boolean isExecuted = executeFlightTask(waylineJob.getWorkspaceId(), waylineJob.getJobId()); |
| | | if (!isExecuted) { |
| | | return ResponseResult.error("Failed to execute job."); |
| | | return ResponseResult.error("执行任务失败"); |
| | | } |
| | | } |
| | | |
| | |
| | | // get job |
| | | Optional<WaylineJobDTO> waylineJob = this.getJobByJobId(workspaceId, jobId); |
| | | if (waylineJob.isEmpty()) { |
| | | throw new IllegalArgumentException("Job doesn't exist."); |
| | | throw new IllegalArgumentException("任务不存在"); |
| | | } |
| | | |
| | | boolean isOnline = deviceRedisService.checkDeviceOnline(waylineJob.get().getDockSn()); |
| | | if (!isOnline) { |
| | | throw new RuntimeException("Dock is offline."); |
| | | throw new RuntimeException("设备离线"); |
| | | } |
| | | |
| | | WaylineJobDTO job = waylineJob.get(); |
| | |
| | | // Check if the task status is correct. |
| | | boolean isErr = !jobIds.removeAll(waylineJobIds) || !jobIds.isEmpty() ; |
| | | if (isErr) { |
| | | throw new IllegalArgumentException("These tasks have an incorrect status and cannot be canceled. " + Arrays.toString(jobIds.toArray())); |
| | | throw new IllegalArgumentException("以下任务状态不正确,不能取消" + Arrays.toString(jobIds.toArray())); |
| | | } |
| | | |
| | | // Group job id by dock sn. |
| | |
| | | public void publishCancelTask(String workspaceId, String dockSn, List<String> jobIds) { |
| | | boolean isOnline = deviceRedisService.checkDeviceOnline(dockSn); |
| | | if (!isOnline) { |
| | | throw new RuntimeException("Dock is offline."); |
| | | throw new RuntimeException("设备离线"); |
| | | } |
| | | |
| | | ServiceReply serviceReply = messageSender.publishServicesTopic( |
| | | dockSn, WaylineMethodEnum.FLIGHT_TASK_CANCEL.getMethod(), Map.of(MapKeyConst.FLIGHT_IDS, jobIds)); |
| | | if (ResponseResult.CODE_SUCCESS != serviceReply.getResult()) { |
| | | log.info("Cancel job ====> Error code: {}", serviceReply.getResult()); |
| | | throw new RuntimeException("Failed to cancel the wayline job of " + dockSn); |
| | | throw new RuntimeException("航路作业取消失败 " + dockSn); |
| | | } |
| | | |
| | | for (String jobId : jobIds) { |
| | |
| | | ServiceReply reply = messageSender.publishServicesTopic( |
| | | dockSn, MediaMethodEnum.UPLOAD_FLIGHT_TASK_MEDIA_PRIORITIZE.getMethod(), Map.of(MapKeyConst.FLIGHT_ID, jobId)); |
| | | if (ResponseResult.CODE_SUCCESS != reply.getResult()) { |
| | | throw new RuntimeException("Failed to set media job upload priority. Error Code: " + reply.getResult()); |
| | | throw new RuntimeException("设置媒体作业上传优先级失败. 错误码: " + reply.getResult()); |
| | | } |
| | | } |
| | | |
| | |
| | | public void updateJobStatus(String workspaceId, String jobId, UpdateJobParam param) { |
| | | Optional<WaylineJobDTO> waylineJobOpt = this.getJobByJobId(workspaceId, jobId); |
| | | if (waylineJobOpt.isEmpty()) { |
| | | throw new RuntimeException("The job does not exist."); |
| | | throw new RuntimeException("任务不存在"); |
| | | } |
| | | WaylineJobDTO waylineJob = waylineJobOpt.get(); |
| | | WaylineJobStatusEnum statusEnum = this.getWaylineState(waylineJob.getDockSn()); |
| | | if (statusEnum.getEnd() || WaylineJobStatusEnum.PENDING == statusEnum) { |
| | | throw new RuntimeException("The wayline job status does not match, and the operation cannot be performed."); |
| | | throw new RuntimeException("航路线作业状态不匹配,无法执行操作."); |
| | | } |
| | | |
| | | switch (param.getStatus()) { |
| | |
| | | ServiceReply reply = messageSender.publishServicesTopic( |
| | | dockSn, WaylineMethodEnum.FLIGHT_TASK_PAUSE.getMethod(), "", jobId); |
| | | if (ResponseResult.CODE_SUCCESS != reply.getResult()) { |
| | | throw new RuntimeException("Failed to pause wayline job. Error Code: " + reply.getResult()); |
| | | throw new RuntimeException("未能恢复航路作业。错误码: " + reply.getResult()); |
| | | } |
| | | waylineRedisService.delRunningWaylineJob(dockSn); |
| | | waylineRedisService.setPausedWaylineJob(dockSn, jobId); |
| | |
| | | ServiceReply reply = messageSender.publishServicesTopic( |
| | | dockSn, WaylineMethodEnum.FLIGHT_TASK_RESUME.getMethod(), "", jobId); |
| | | if (ResponseResult.CODE_SUCCESS != reply.getResult()) { |
| | | throw new RuntimeException("Failed to resume wayline job. Error Code: " + reply.getResult()); |
| | | throw new RuntimeException("未能恢复航路作业。错误码:: " + reply.getResult()); |
| | | } |
| | | |
| | | runningDataOpt.ifPresent(runningData -> waylineRedisService.setRunningWaylineJob(dockSn, runningData)); |
| | |
| | | @Override |
| | | public void setConditionalWaylineJob(WaylineJobDTO waylineJob) { |
| | | if (!StringUtils.hasText(waylineJob.getJobId())) { |
| | | throw new RuntimeException("Job id can't be null."); |
| | | throw new RuntimeException("任务id不能为空"); |
| | | } |
| | | RedisOpsUtils.setWithExpire(RedisConst.WAYLINE_JOB_CONDITION_PREFIX + waylineJob.getJobId(), waylineJob, |
| | | Math.abs(Duration.between(waylineJob.getEndTime(), LocalDateTime.now()).getSeconds())); |