mirror of
https://github.com/hpd840321/starRiverProperty.git
synced 2026-06-09 08:20:31 +08:00
chore: 工作区反编译与 Maven/文档/脚本同步到发布分支
- artifacts/decompiled 树与相关源码变更 - maven-cw-elevator-application 业务 docs 与 package-info - scripts 下 formatter 校验与辅助脚本 - 其他子工程/接口与发布线一并纳入版本控制 Made-with: Cursor Former-commit-id: e102e8cab64e575bcd23c9a66a598aa1892bb492
This commit is contained in:
+19
-19
@@ -1,19 +1,19 @@
|
||||
package cn.cloudwalk.intelligent.davinci.storage.bean.file.dto;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
public class FileRemoveDTO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -5375408551667275621L;
|
||||
|
||||
private List<String> fileList;
|
||||
|
||||
public List<String> getFileList() {
|
||||
return fileList;
|
||||
}
|
||||
|
||||
public void setFileList(List<String> fileList) {
|
||||
this.fileList = fileList;
|
||||
}
|
||||
}
|
||||
package cn.cloudwalk.intelligent.davinci.storage.bean.file.dto;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
public class FileRemoveDTO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -5375408551667275621L;
|
||||
|
||||
private List<String> fileList;
|
||||
|
||||
public List<String> getFileList() {
|
||||
return fileList;
|
||||
}
|
||||
|
||||
public void setFileList(List<String> fileList) {
|
||||
this.fileList = fileList;
|
||||
}
|
||||
}
|
||||
|
||||
+45
-45
@@ -1,45 +1,45 @@
|
||||
package cn.cloudwalk.intelligent.davinci.storage.bean.part.dto;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class PartFinishDTO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -6084049403163053112L;
|
||||
|
||||
private String uploadId;
|
||||
private Long fileSize;
|
||||
private String filePath;
|
||||
private Integer returnType = Integer.valueOf(0);
|
||||
|
||||
public String getUploadId() {
|
||||
return uploadId;
|
||||
}
|
||||
|
||||
public void setUploadId(String uploadId) {
|
||||
this.uploadId = uploadId;
|
||||
}
|
||||
|
||||
public Long getFileSize() {
|
||||
return fileSize;
|
||||
}
|
||||
|
||||
public void setFileSize(Long fileSize) {
|
||||
this.fileSize = fileSize;
|
||||
}
|
||||
|
||||
public String getFilePath() {
|
||||
return filePath;
|
||||
}
|
||||
|
||||
public void setFilePath(String filePath) {
|
||||
this.filePath = filePath;
|
||||
}
|
||||
|
||||
public Integer getReturnType() {
|
||||
return returnType;
|
||||
}
|
||||
|
||||
public void setReturnType(Integer returnType) {
|
||||
this.returnType = returnType;
|
||||
}
|
||||
}
|
||||
package cn.cloudwalk.intelligent.davinci.storage.bean.part.dto;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class PartFinishDTO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -6084049403163053112L;
|
||||
|
||||
private String uploadId;
|
||||
private Long fileSize;
|
||||
private String filePath;
|
||||
private Integer returnType = Integer.valueOf(0);
|
||||
|
||||
public String getUploadId() {
|
||||
return uploadId;
|
||||
}
|
||||
|
||||
public void setUploadId(String uploadId) {
|
||||
this.uploadId = uploadId;
|
||||
}
|
||||
|
||||
public Long getFileSize() {
|
||||
return fileSize;
|
||||
}
|
||||
|
||||
public void setFileSize(Long fileSize) {
|
||||
this.fileSize = fileSize;
|
||||
}
|
||||
|
||||
public String getFilePath() {
|
||||
return filePath;
|
||||
}
|
||||
|
||||
public void setFilePath(String filePath) {
|
||||
this.filePath = filePath;
|
||||
}
|
||||
|
||||
public Integer getReturnType() {
|
||||
return returnType;
|
||||
}
|
||||
|
||||
public void setReturnType(Integer returnType) {
|
||||
this.returnType = returnType;
|
||||
}
|
||||
}
|
||||
|
||||
+18
-18
@@ -1,18 +1,18 @@
|
||||
package cn.cloudwalk.intelligent.davinci.storage.bean.part.dto;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class PartInitDTO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -5411973046504674893L;
|
||||
|
||||
private String fileName;
|
||||
|
||||
public String getFileName() {
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public void setFileName(String fileName) {
|
||||
this.fileName = fileName;
|
||||
}
|
||||
}
|
||||
package cn.cloudwalk.intelligent.davinci.storage.bean.part.dto;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class PartInitDTO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -5411973046504674893L;
|
||||
|
||||
private String fileName;
|
||||
|
||||
public String getFileName() {
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public void setFileName(String fileName) {
|
||||
this.fileName = fileName;
|
||||
}
|
||||
}
|
||||
|
||||
+27
-27
@@ -1,27 +1,27 @@
|
||||
package cn.cloudwalk.intelligent.davinci.storage.bean.part.dto;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class PartInitResultDTO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -4514634072455987454L;
|
||||
|
||||
private String filePath;
|
||||
private String uploadId;
|
||||
|
||||
public String getFilePath() {
|
||||
return filePath;
|
||||
}
|
||||
|
||||
public void setFilePath(String filePath) {
|
||||
this.filePath = filePath;
|
||||
}
|
||||
|
||||
public String getUploadId() {
|
||||
return uploadId;
|
||||
}
|
||||
|
||||
public void setUploadId(String uploadId) {
|
||||
this.uploadId = uploadId;
|
||||
}
|
||||
}
|
||||
package cn.cloudwalk.intelligent.davinci.storage.bean.part.dto;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class PartInitResultDTO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -4514634072455987454L;
|
||||
|
||||
private String filePath;
|
||||
private String uploadId;
|
||||
|
||||
public String getFilePath() {
|
||||
return filePath;
|
||||
}
|
||||
|
||||
public void setFilePath(String filePath) {
|
||||
this.filePath = filePath;
|
||||
}
|
||||
|
||||
public String getUploadId() {
|
||||
return uploadId;
|
||||
}
|
||||
|
||||
public void setUploadId(String uploadId) {
|
||||
this.uploadId = uploadId;
|
||||
}
|
||||
}
|
||||
|
||||
+93
-91
@@ -1,91 +1,93 @@
|
||||
package cn.cloudwalk.intelligent.davinci.storage.feign;
|
||||
|
||||
import cn.cloudwalk.intelligent.davinci.common.result.DavinciResult;
|
||||
import cn.cloudwalk.intelligent.davinci.storage.bean.file.dto.FileRemoveDTO;
|
||||
import feign.Request;
|
||||
import feign.Response;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RequestPart;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
public interface FileManagerFeign {
|
||||
|
||||
String DEFAULT_MODULE_CATEGORY = "default";
|
||||
|
||||
@RequestMapping(value = {"/default/fileUpload"}, method = {RequestMethod.POST}, consumes = {"multipart/form-data"})
|
||||
DavinciResult<String> fileUpload(@RequestPart("file") MultipartFile file);
|
||||
|
||||
@RequestMapping(value = {"/{moduleCategory}/fileUpload"}, method = {RequestMethod.POST}, consumes = {"multipart/form-data"})
|
||||
DavinciResult<String> fileUpload(
|
||||
@PathVariable("moduleCategory") String moduleCategory, @RequestPart("file") MultipartFile file);
|
||||
|
||||
@RequestMapping(value = {"/default/bigFileUpload"}, method = {RequestMethod.POST}, consumes = {"multipart/form-data"})
|
||||
DavinciResult<String> bigFileUpload(@RequestPart("file") MultipartFile file);
|
||||
|
||||
@RequestMapping(value = {"/{moduleCategory}/bigFileUpload"}, method = {RequestMethod.POST}, consumes = {"multipart/form-data"})
|
||||
DavinciResult<String> bigFileUpload(
|
||||
@PathVariable("moduleCategory") String moduleCategory, @RequestPart("file") MultipartFile file);
|
||||
|
||||
@RequestMapping(value = {"/imgByPath"}, method = {RequestMethod.GET})
|
||||
Response fileDownload(@RequestParam("path") String path);
|
||||
|
||||
@RequestMapping(value = {"/default/getFileData"}, method = {RequestMethod.POST})
|
||||
DavinciResult<String> getFileData(@RequestParam("path") String path);
|
||||
|
||||
@RequestMapping(value = {"/remove/images"}, method = {RequestMethod.POST})
|
||||
DavinciResult<List<String>> remove(@RequestBody FileRemoveDTO dto);
|
||||
|
||||
@Component
|
||||
class FileManagerFeignClientFallback implements FileManagerFeign {
|
||||
|
||||
private static final String FEIGN_DOWN = "DAVINCI_FEIGN_DOWN";
|
||||
|
||||
@Override
|
||||
public DavinciResult<String> fileUpload(MultipartFile file) {
|
||||
return DavinciResult.fail(FEIGN_DOWN, "调用Davinci-portal服务,模块文件上传接口降级");
|
||||
}
|
||||
|
||||
@Override
|
||||
public DavinciResult<String> fileUpload(String moduleCategory, MultipartFile file) {
|
||||
return DavinciResult.fail(FEIGN_DOWN, "调用Davinci-portal服务,模块文件上传接口降级");
|
||||
}
|
||||
|
||||
@Override
|
||||
public DavinciResult<String> bigFileUpload(MultipartFile file) {
|
||||
return DavinciResult.fail(FEIGN_DOWN, "调用Davinci-portal服务,大文件上传接口降级");
|
||||
}
|
||||
|
||||
@Override
|
||||
public DavinciResult<String> bigFileUpload(String moduleCategory, MultipartFile file) {
|
||||
return DavinciResult.fail(FEIGN_DOWN, "调用Davinci-portal服务,大文件上传接口降级");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response fileDownload(String path) {
|
||||
return Response.builder()
|
||||
.status(503)
|
||||
.reason("Feign fallback")
|
||||
.request(Request.create(Request.HttpMethod.GET, "/", Collections.emptyMap(), null, StandardCharsets.UTF_8))
|
||||
.body("{}", StandardCharsets.UTF_8)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DavinciResult<String> getFileData(String path) {
|
||||
return DavinciResult.fail(FEIGN_DOWN, "调用Davinci-portal服务,获取文件Base64内容接口降级");
|
||||
}
|
||||
|
||||
@Override
|
||||
public DavinciResult<List<String>> remove(FileRemoveDTO dto) {
|
||||
return DavinciResult.fail(FEIGN_DOWN, "调用Davinci-portal服务,删除文件接口降级");
|
||||
}
|
||||
}
|
||||
}
|
||||
package cn.cloudwalk.intelligent.davinci.storage.feign;
|
||||
|
||||
import cn.cloudwalk.intelligent.davinci.common.result.DavinciResult;
|
||||
import cn.cloudwalk.intelligent.davinci.storage.bean.file.dto.FileRemoveDTO;
|
||||
import feign.Request;
|
||||
import feign.Response;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RequestPart;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
public interface FileManagerFeign {
|
||||
|
||||
String DEFAULT_MODULE_CATEGORY = "default";
|
||||
|
||||
@RequestMapping(value = { "/default/fileUpload" }, method = { RequestMethod.POST }, consumes = {
|
||||
"multipart/form-data" })
|
||||
DavinciResult<String> fileUpload(@RequestPart("file") MultipartFile file);
|
||||
|
||||
@RequestMapping(value = { "/{moduleCategory}/fileUpload" }, method = { RequestMethod.POST }, consumes = {
|
||||
"multipart/form-data" })
|
||||
DavinciResult<String> fileUpload(@PathVariable("moduleCategory") String moduleCategory,
|
||||
@RequestPart("file") MultipartFile file);
|
||||
|
||||
@RequestMapping(value = { "/default/bigFileUpload" }, method = { RequestMethod.POST }, consumes = {
|
||||
"multipart/form-data" })
|
||||
DavinciResult<String> bigFileUpload(@RequestPart("file") MultipartFile file);
|
||||
|
||||
@RequestMapping(value = { "/{moduleCategory}/bigFileUpload" }, method = { RequestMethod.POST }, consumes = {
|
||||
"multipart/form-data" })
|
||||
DavinciResult<String> bigFileUpload(@PathVariable("moduleCategory") String moduleCategory,
|
||||
@RequestPart("file") MultipartFile file);
|
||||
|
||||
@RequestMapping(value = { "/imgByPath" }, method = { RequestMethod.GET })
|
||||
Response fileDownload(@RequestParam("path") String path);
|
||||
|
||||
@RequestMapping(value = { "/default/getFileData" }, method = { RequestMethod.POST })
|
||||
DavinciResult<String> getFileData(@RequestParam("path") String path);
|
||||
|
||||
@RequestMapping(value = { "/remove/images" }, method = { RequestMethod.POST })
|
||||
DavinciResult<List<String>> remove(@RequestBody FileRemoveDTO dto);
|
||||
|
||||
@Component
|
||||
class FileManagerFeignClientFallback implements FileManagerFeign {
|
||||
|
||||
private static final String FEIGN_DOWN = "DAVINCI_FEIGN_DOWN";
|
||||
|
||||
@Override
|
||||
public DavinciResult<String> fileUpload(MultipartFile file) {
|
||||
return DavinciResult.fail(FEIGN_DOWN, "调用Davinci-portal服务,模块文件上传接口降级");
|
||||
}
|
||||
|
||||
@Override
|
||||
public DavinciResult<String> fileUpload(String moduleCategory, MultipartFile file) {
|
||||
return DavinciResult.fail(FEIGN_DOWN, "调用Davinci-portal服务,模块文件上传接口降级");
|
||||
}
|
||||
|
||||
@Override
|
||||
public DavinciResult<String> bigFileUpload(MultipartFile file) {
|
||||
return DavinciResult.fail(FEIGN_DOWN, "调用Davinci-portal服务,大文件上传接口降级");
|
||||
}
|
||||
|
||||
@Override
|
||||
public DavinciResult<String> bigFileUpload(String moduleCategory, MultipartFile file) {
|
||||
return DavinciResult.fail(FEIGN_DOWN, "调用Davinci-portal服务,大文件上传接口降级");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response fileDownload(String path) {
|
||||
return Response
|
||||
.builder().status(503).reason("Feign fallback").request(Request.create(Request.HttpMethod.GET, "/",
|
||||
Collections.emptyMap(), null, StandardCharsets.UTF_8))
|
||||
.body("{}", StandardCharsets.UTF_8).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DavinciResult<String> getFileData(String path) {
|
||||
return DavinciResult.fail(FEIGN_DOWN, "调用Davinci-portal服务,获取文件Base64内容接口降级");
|
||||
}
|
||||
|
||||
@Override
|
||||
public DavinciResult<List<String>> remove(FileRemoveDTO dto) {
|
||||
return DavinciResult.fail(FEIGN_DOWN, "调用Davinci-portal服务,删除文件接口降级");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+26
-31
@@ -1,31 +1,26 @@
|
||||
package cn.cloudwalk.intelligent.davinci.storage.feign;
|
||||
|
||||
import cn.cloudwalk.intelligent.davinci.common.result.DavinciResult;
|
||||
import cn.cloudwalk.intelligent.davinci.storage.bean.part.dto.PartFinishDTO;
|
||||
import cn.cloudwalk.intelligent.davinci.storage.bean.part.dto.PartInitDTO;
|
||||
import cn.cloudwalk.intelligent.davinci.storage.bean.part.dto.PartInitResultDTO;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RequestPart;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
public interface FilePartFeign {
|
||||
|
||||
@RequestMapping(value = {"/init"}, method = {RequestMethod.POST})
|
||||
DavinciResult<PartInitResultDTO> init(@RequestBody PartInitDTO paramPartInitDTO);
|
||||
|
||||
@RequestMapping(
|
||||
value = {"/append"},
|
||||
method = {RequestMethod.POST},
|
||||
consumes = {"multipart/form-data"})
|
||||
DavinciResult<PartInitResultDTO> append(
|
||||
@RequestParam("filePath") String paramString1,
|
||||
@RequestParam("partNumber") Integer paramInteger,
|
||||
@RequestParam("uploadId") String paramString2,
|
||||
@RequestPart("file") MultipartFile paramMultipartFile);
|
||||
|
||||
@RequestMapping(value = {"/finish"}, method = {RequestMethod.POST})
|
||||
DavinciResult<String> finish(@RequestBody PartFinishDTO paramPartFinishDTO);
|
||||
}
|
||||
package cn.cloudwalk.intelligent.davinci.storage.feign;
|
||||
|
||||
import cn.cloudwalk.intelligent.davinci.common.result.DavinciResult;
|
||||
import cn.cloudwalk.intelligent.davinci.storage.bean.part.dto.PartFinishDTO;
|
||||
import cn.cloudwalk.intelligent.davinci.storage.bean.part.dto.PartInitDTO;
|
||||
import cn.cloudwalk.intelligent.davinci.storage.bean.part.dto.PartInitResultDTO;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RequestPart;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
public interface FilePartFeign {
|
||||
|
||||
@RequestMapping(value = { "/init" }, method = { RequestMethod.POST })
|
||||
DavinciResult<PartInitResultDTO> init(@RequestBody PartInitDTO paramPartInitDTO);
|
||||
|
||||
@RequestMapping(value = { "/append" }, method = { RequestMethod.POST }, consumes = { "multipart/form-data" })
|
||||
DavinciResult<PartInitResultDTO> append(@RequestParam("filePath") String paramString1,
|
||||
@RequestParam("partNumber") Integer paramInteger, @RequestParam("uploadId") String paramString2,
|
||||
@RequestPart("file") MultipartFile paramMultipartFile);
|
||||
|
||||
@RequestMapping(value = { "/finish" }, method = { RequestMethod.POST })
|
||||
DavinciResult<String> finish(@RequestBody PartFinishDTO paramPartFinishDTO);
|
||||
}
|
||||
|
||||
+11
-11
@@ -1,11 +1,11 @@
|
||||
package cn.cloudwalk.intelligent.davinci.storage.feign;
|
||||
|
||||
import feign.RequestLine;
|
||||
import feign.Response;
|
||||
|
||||
public interface OuterCallFeignClient {
|
||||
|
||||
/** 与动态 {@code target(…, url)} 组合;{@code url} 须为完整可 GET 的资源地址(由上层做 SSRF 校验)。 */
|
||||
@RequestLine("GET ")
|
||||
Response downLoad();
|
||||
}
|
||||
package cn.cloudwalk.intelligent.davinci.storage.feign;
|
||||
|
||||
import feign.RequestLine;
|
||||
import feign.Response;
|
||||
|
||||
public interface OuterCallFeignClient {
|
||||
|
||||
/** 与动态 {@code target(…, url)} 组合;{@code url} 须为完整可 GET 的资源地址(由上层做 SSRF 校验)。 */
|
||||
@RequestLine("GET ")
|
||||
Response downLoad();
|
||||
}
|
||||
|
||||
+17
-18
@@ -1,18 +1,17 @@
|
||||
package cn.cloudwalk.intelligent.davinci.storage.manager;
|
||||
|
||||
import cn.cloudwalk.intelligent.davinci.common.exception.DavinciServiceException;
|
||||
import cn.cloudwalk.intelligent.davinci.storage.bean.part.dto.PartFinishDTO;
|
||||
import cn.cloudwalk.intelligent.davinci.storage.bean.part.dto.PartInitDTO;
|
||||
import cn.cloudwalk.intelligent.davinci.storage.bean.part.dto.PartInitResultDTO;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
public interface FilePartManager {
|
||||
|
||||
PartInitResultDTO init(PartInitDTO paramPartInitDTO) throws DavinciServiceException;
|
||||
|
||||
PartInitResultDTO append(
|
||||
String paramString1, Integer paramInteger, String paramString2, MultipartFile paramMultipartFile)
|
||||
throws DavinciServiceException;
|
||||
|
||||
String finish(PartFinishDTO paramPartFinishDTO) throws DavinciServiceException;
|
||||
}
|
||||
package cn.cloudwalk.intelligent.davinci.storage.manager;
|
||||
|
||||
import cn.cloudwalk.intelligent.davinci.common.exception.DavinciServiceException;
|
||||
import cn.cloudwalk.intelligent.davinci.storage.bean.part.dto.PartFinishDTO;
|
||||
import cn.cloudwalk.intelligent.davinci.storage.bean.part.dto.PartInitDTO;
|
||||
import cn.cloudwalk.intelligent.davinci.storage.bean.part.dto.PartInitResultDTO;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
public interface FilePartManager {
|
||||
|
||||
PartInitResultDTO init(PartInitDTO paramPartInitDTO) throws DavinciServiceException;
|
||||
|
||||
PartInitResultDTO append(String paramString1, Integer paramInteger, String paramString2,
|
||||
MultipartFile paramMultipartFile) throws DavinciServiceException;
|
||||
|
||||
String finish(PartFinishDTO paramPartFinishDTO) throws DavinciServiceException;
|
||||
}
|
||||
|
||||
+28
-28
@@ -1,28 +1,28 @@
|
||||
package cn.cloudwalk.intelligent.davinci.storage.manager;
|
||||
|
||||
import cn.cloudwalk.intelligent.davinci.common.exception.DavinciServiceException;
|
||||
import cn.cloudwalk.intelligent.davinci.storage.bean.file.dto.FileRemoveDTO;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
public interface FileStorageManager {
|
||||
|
||||
String fileUpload(MultipartFile paramMultipartFile) throws DavinciServiceException;
|
||||
|
||||
String fileUpload(String paramString, MultipartFile paramMultipartFile) throws DavinciServiceException;
|
||||
|
||||
String bigFileUpload(MultipartFile paramMultipartFile) throws DavinciServiceException;
|
||||
|
||||
String bigFileUpload(String paramString, MultipartFile paramMultipartFile) throws DavinciServiceException;
|
||||
|
||||
byte[] fileDownload(String paramString) throws DavinciServiceException;
|
||||
|
||||
String getFileBase64(String paramString) throws DavinciServiceException;
|
||||
|
||||
List<String> remove(FileRemoveDTO paramFileRemoveDTO) throws DavinciServiceException;
|
||||
|
||||
InputStream fileDownloadStream(String paramString) throws DavinciServiceException;
|
||||
|
||||
InputStream fileDownLoadWithAbsoluteUrl(String paramString) throws DavinciServiceException;
|
||||
}
|
||||
package cn.cloudwalk.intelligent.davinci.storage.manager;
|
||||
|
||||
import cn.cloudwalk.intelligent.davinci.common.exception.DavinciServiceException;
|
||||
import cn.cloudwalk.intelligent.davinci.storage.bean.file.dto.FileRemoveDTO;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
public interface FileStorageManager {
|
||||
|
||||
String fileUpload(MultipartFile paramMultipartFile) throws DavinciServiceException;
|
||||
|
||||
String fileUpload(String paramString, MultipartFile paramMultipartFile) throws DavinciServiceException;
|
||||
|
||||
String bigFileUpload(MultipartFile paramMultipartFile) throws DavinciServiceException;
|
||||
|
||||
String bigFileUpload(String paramString, MultipartFile paramMultipartFile) throws DavinciServiceException;
|
||||
|
||||
byte[] fileDownload(String paramString) throws DavinciServiceException;
|
||||
|
||||
String getFileBase64(String paramString) throws DavinciServiceException;
|
||||
|
||||
List<String> remove(FileRemoveDTO paramFileRemoveDTO) throws DavinciServiceException;
|
||||
|
||||
InputStream fileDownloadStream(String paramString) throws DavinciServiceException;
|
||||
|
||||
InputStream fileDownLoadWithAbsoluteUrl(String paramString) throws DavinciServiceException;
|
||||
}
|
||||
|
||||
+69
-84
@@ -1,84 +1,69 @@
|
||||
package cn.cloudwalk.intelligent.davinci.storage.manager.impl;
|
||||
|
||||
import cn.cloudwalk.intelligent.davinci.common.exception.DavinciServiceException;
|
||||
import cn.cloudwalk.intelligent.davinci.common.result.DavinciResult;
|
||||
import cn.cloudwalk.intelligent.davinci.storage.bean.part.dto.PartFinishDTO;
|
||||
import cn.cloudwalk.intelligent.davinci.storage.bean.part.dto.PartInitDTO;
|
||||
import cn.cloudwalk.intelligent.davinci.storage.bean.part.dto.PartInitResultDTO;
|
||||
import cn.cloudwalk.intelligent.davinci.storage.feign.FilePartFeign;
|
||||
import cn.cloudwalk.intelligent.davinci.storage.manager.FilePartManager;
|
||||
import feign.Client;
|
||||
import feign.Feign;
|
||||
import feign.codec.Decoder;
|
||||
import feign.codec.Encoder;
|
||||
import feign.form.spring.SpringFormEncoder;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.cloud.openfeign.FeignClientsConfiguration;
|
||||
import org.springframework.cloud.openfeign.support.SpringMvcContract;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
@Component
|
||||
@Import({FeignClientsConfiguration.class})
|
||||
public class FilePartManagerImpl implements FilePartManager {
|
||||
|
||||
private FilePartFeign filePartFeign;
|
||||
private FilePartFeign filePartRestFeign;
|
||||
|
||||
@Autowired
|
||||
public FilePartManagerImpl(
|
||||
@Value("${feign.davinci-portal.name:davinci-portal}") String serviceName,
|
||||
Decoder decoder,
|
||||
Encoder encoder,
|
||||
Client client) {
|
||||
String url = "http://" + serviceName + "/portal/file/part";
|
||||
|
||||
this.filePartFeign =
|
||||
Feign.builder()
|
||||
.client(client)
|
||||
.decode404()
|
||||
.encoder(new SpringFormEncoder())
|
||||
.decoder(decoder)
|
||||
.contract(new SpringMvcContract())
|
||||
.target(FilePartFeign.class, url);
|
||||
|
||||
this.filePartRestFeign =
|
||||
Feign.builder()
|
||||
.client(client)
|
||||
.decode404()
|
||||
.encoder(encoder)
|
||||
.decoder(decoder)
|
||||
.contract(new SpringMvcContract())
|
||||
.target(FilePartFeign.class, url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PartInitResultDTO init(PartInitDTO dto) throws DavinciServiceException {
|
||||
DavinciResult<PartInitResultDTO> result = this.filePartRestFeign.init(dto);
|
||||
if (result.isSuccess()) {
|
||||
return result.getData();
|
||||
}
|
||||
throw new DavinciServiceException(result.getCode(), result.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PartInitResultDTO append(
|
||||
String filePath, Integer partNumber, String uploadId, MultipartFile file) throws DavinciServiceException {
|
||||
DavinciResult<PartInitResultDTO> result = this.filePartFeign.append(filePath, partNumber, uploadId, file);
|
||||
if (result.isSuccess()) {
|
||||
return result.getData();
|
||||
}
|
||||
throw new DavinciServiceException(result.getCode(), result.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String finish(PartFinishDTO dto) throws DavinciServiceException {
|
||||
DavinciResult<String> result = this.filePartRestFeign.finish(dto);
|
||||
if (result.isSuccess()) {
|
||||
return result.getData();
|
||||
}
|
||||
throw new DavinciServiceException(result.getCode(), result.getMessage());
|
||||
}
|
||||
}
|
||||
package cn.cloudwalk.intelligent.davinci.storage.manager.impl;
|
||||
|
||||
import cn.cloudwalk.intelligent.davinci.common.exception.DavinciServiceException;
|
||||
import cn.cloudwalk.intelligent.davinci.common.result.DavinciResult;
|
||||
import cn.cloudwalk.intelligent.davinci.storage.bean.part.dto.PartFinishDTO;
|
||||
import cn.cloudwalk.intelligent.davinci.storage.bean.part.dto.PartInitDTO;
|
||||
import cn.cloudwalk.intelligent.davinci.storage.bean.part.dto.PartInitResultDTO;
|
||||
import cn.cloudwalk.intelligent.davinci.storage.feign.FilePartFeign;
|
||||
import cn.cloudwalk.intelligent.davinci.storage.manager.FilePartManager;
|
||||
import feign.Client;
|
||||
import feign.Feign;
|
||||
import feign.codec.Decoder;
|
||||
import feign.codec.Encoder;
|
||||
import feign.form.spring.SpringFormEncoder;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.cloud.openfeign.FeignClientsConfiguration;
|
||||
import org.springframework.cloud.openfeign.support.SpringMvcContract;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
@Component
|
||||
@Import({ FeignClientsConfiguration.class })
|
||||
public class FilePartManagerImpl implements FilePartManager {
|
||||
|
||||
private FilePartFeign filePartFeign;
|
||||
private FilePartFeign filePartRestFeign;
|
||||
|
||||
@Autowired
|
||||
public FilePartManagerImpl(@Value("${feign.davinci-portal.name:davinci-portal}") String serviceName,
|
||||
Decoder decoder, Encoder encoder, Client client) {
|
||||
String url = "http://" + serviceName + "/portal/file/part";
|
||||
|
||||
this.filePartFeign = Feign.builder().client(client).decode404().encoder(new SpringFormEncoder())
|
||||
.decoder(decoder).contract(new SpringMvcContract()).target(FilePartFeign.class, url);
|
||||
|
||||
this.filePartRestFeign = Feign.builder().client(client).decode404().encoder(encoder).decoder(decoder)
|
||||
.contract(new SpringMvcContract()).target(FilePartFeign.class, url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PartInitResultDTO init(PartInitDTO dto) throws DavinciServiceException {
|
||||
DavinciResult<PartInitResultDTO> result = this.filePartRestFeign.init(dto);
|
||||
if (result.isSuccess()) {
|
||||
return result.getData();
|
||||
}
|
||||
throw new DavinciServiceException(result.getCode(), result.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PartInitResultDTO append(String filePath, Integer partNumber, String uploadId, MultipartFile file)
|
||||
throws DavinciServiceException {
|
||||
DavinciResult<PartInitResultDTO> result = this.filePartFeign.append(filePath, partNumber, uploadId, file);
|
||||
if (result.isSuccess()) {
|
||||
return result.getData();
|
||||
}
|
||||
throw new DavinciServiceException(result.getCode(), result.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String finish(PartFinishDTO dto) throws DavinciServiceException {
|
||||
DavinciResult<String> result = this.filePartRestFeign.finish(dto);
|
||||
if (result.isSuccess()) {
|
||||
return result.getData();
|
||||
}
|
||||
throw new DavinciServiceException(result.getCode(), result.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
+236
-251
@@ -1,251 +1,236 @@
|
||||
package cn.cloudwalk.intelligent.davinci.storage.manager.impl;
|
||||
|
||||
import cn.cloudwalk.intelligent.davinci.common.exception.DavinciServiceException;
|
||||
import cn.cloudwalk.intelligent.davinci.common.result.DavinciResult;
|
||||
import cn.cloudwalk.intelligent.davinci.storage.bean.file.dto.FileRemoveDTO;
|
||||
import cn.cloudwalk.intelligent.davinci.storage.feign.FileManagerFeign;
|
||||
import cn.cloudwalk.intelligent.davinci.storage.feign.OuterCallFeignClient;
|
||||
import cn.cloudwalk.intelligent.davinci.storage.manager.FileStorageManager;
|
||||
import feign.Client;
|
||||
import feign.Feign;
|
||||
import feign.Response;
|
||||
import feign.codec.Decoder;
|
||||
import feign.codec.Encoder;
|
||||
import feign.form.spring.SpringFormEncoder;
|
||||
import feign.okhttp.OkHttpClient;
|
||||
import java.io.FilterInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.cloud.openfeign.FeignClientsConfiguration;
|
||||
import org.springframework.cloud.openfeign.support.SpringMvcContract;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
@Component
|
||||
@Import({FeignClientsConfiguration.class})
|
||||
public class FileStorageManagerImpl implements FileStorageManager {
|
||||
|
||||
private FileManagerFeign fileManagerFeign;
|
||||
private FileManagerFeign fileManagerRestFeign;
|
||||
|
||||
@Autowired
|
||||
public FileStorageManagerImpl(
|
||||
@Value("${feign.davinci-portal.name:davinci-portal}") String serviceName,
|
||||
Decoder decoder,
|
||||
Encoder encoder,
|
||||
Client client) {
|
||||
String url = "http://" + serviceName + "/portal/fileManager";
|
||||
|
||||
this.fileManagerFeign =
|
||||
Feign.builder()
|
||||
.client(client)
|
||||
.decode404()
|
||||
.encoder(new SpringFormEncoder())
|
||||
.decoder(decoder)
|
||||
.contract(new SpringMvcContract())
|
||||
.target(FileManagerFeign.class, url);
|
||||
|
||||
this.fileManagerRestFeign =
|
||||
Feign.builder()
|
||||
.client(client)
|
||||
.decode404()
|
||||
.encoder(encoder)
|
||||
.decoder(decoder)
|
||||
.contract(new SpringMvcContract())
|
||||
.target(FileManagerFeign.class, url);
|
||||
}
|
||||
|
||||
/**
|
||||
* 限制通过「绝对 URL」拉流时的 SSRF:仅 http(s),且解析后不得为回环、链路本地、站点本地及常见元数据地址。
|
||||
*/
|
||||
static void assertSafeHttpUrl(String urlString) throws DavinciServiceException {
|
||||
if (StringUtils.isEmpty(urlString)) {
|
||||
throw new DavinciServiceException("INVALID_URL", "URL 为空");
|
||||
}
|
||||
URI uri;
|
||||
try {
|
||||
uri = new URI(urlString);
|
||||
} catch (URISyntaxException e) {
|
||||
throw new DavinciServiceException("INVALID_URL", "URL 非法");
|
||||
}
|
||||
String scheme = uri.getScheme();
|
||||
if (scheme == null || (!"http".equalsIgnoreCase(scheme) && !"https".equalsIgnoreCase(scheme))) {
|
||||
throw new DavinciServiceException("INVALID_URL", "仅允许 http 或 https 协议");
|
||||
}
|
||||
String host = uri.getHost();
|
||||
if (StringUtils.isEmpty(host)) {
|
||||
throw new DavinciServiceException("INVALID_URL", "缺少主机名");
|
||||
}
|
||||
String lowerHost = host.toLowerCase(Locale.ROOT);
|
||||
if ("localhost".equals(lowerHost) || lowerHost.endsWith(".local")) {
|
||||
throw new DavinciServiceException("INVALID_URL", "禁止访问该主机");
|
||||
}
|
||||
if ("metadata.google.internal".equalsIgnoreCase(host)) {
|
||||
throw new DavinciServiceException("INVALID_URL", "禁止访问该主机");
|
||||
}
|
||||
try {
|
||||
InetAddress[] all = InetAddress.getAllByName(host);
|
||||
for (InetAddress addr : all) {
|
||||
if (addr.isAnyLocalAddress() || addr.isLoopbackAddress() || addr.isLinkLocalAddress()
|
||||
|| addr.isSiteLocalAddress() || addr.isMulticastAddress()) {
|
||||
throw new DavinciServiceException("INVALID_URL", "禁止访问内网或保留地址");
|
||||
}
|
||||
}
|
||||
} catch (UnknownHostException e) {
|
||||
throw new DavinciServiceException("INVALID_URL", "无法解析主机");
|
||||
}
|
||||
}
|
||||
|
||||
private static void requireDavinciResult(DavinciResult<?> result, String op) throws DavinciServiceException {
|
||||
if (result == null) {
|
||||
throw new DavinciServiceException("NULL_RESULT", "Davinci-portal 返回空结果: " + op);
|
||||
}
|
||||
}
|
||||
|
||||
private static InputStream attachResponseClose(InputStream bodyStream, Response response) {
|
||||
return new FilterInputStream(bodyStream) {
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
try {
|
||||
super.close();
|
||||
} finally {
|
||||
response.close();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String fileUpload(MultipartFile file) throws DavinciServiceException {
|
||||
DavinciResult<String> result = this.fileManagerFeign.fileUpload(file);
|
||||
requireDavinciResult(result, "fileUpload");
|
||||
if (result.isSuccess()) {
|
||||
return result.getData();
|
||||
}
|
||||
throw new DavinciServiceException(result.getCode(), result.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String fileUpload(String moduleCategory, MultipartFile file) throws DavinciServiceException {
|
||||
DavinciResult<String> result = this.fileManagerFeign.fileUpload(moduleCategory, file);
|
||||
requireDavinciResult(result, "fileUpload(module)");
|
||||
if (result.isSuccess()) {
|
||||
return result.getData();
|
||||
}
|
||||
throw new DavinciServiceException(result.getCode(), result.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String bigFileUpload(MultipartFile file) throws DavinciServiceException {
|
||||
DavinciResult<String> result = this.fileManagerFeign.bigFileUpload(file);
|
||||
requireDavinciResult(result, "bigFileUpload");
|
||||
if (result.isSuccess()) {
|
||||
return result.getData();
|
||||
}
|
||||
throw new DavinciServiceException(result.getCode(), result.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String bigFileUpload(String moduleCategory, MultipartFile file) throws DavinciServiceException {
|
||||
DavinciResult<String> result = this.fileManagerFeign.bigFileUpload(moduleCategory, file);
|
||||
requireDavinciResult(result, "bigFileUpload(module)");
|
||||
if (result.isSuccess()) {
|
||||
return result.getData();
|
||||
}
|
||||
throw new DavinciServiceException(result.getCode(), result.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] fileDownload(String path) throws DavinciServiceException {
|
||||
try (Response response = this.fileManagerFeign.fileDownload(path)) {
|
||||
if (response == null) {
|
||||
return null;
|
||||
}
|
||||
if (response.body() == null) {
|
||||
return null;
|
||||
}
|
||||
try (InputStream inputStream = response.body().asInputStream()) {
|
||||
return IOUtils.toByteArray(inputStream);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new DavinciServiceException("FILE_DOWNLOAD_IO", "调用Davinci-portal服务,获取文件流接口异常");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream fileDownloadStream(String path) throws DavinciServiceException {
|
||||
Response response = this.fileManagerFeign.fileDownload(path);
|
||||
try {
|
||||
if (response == null) {
|
||||
return null;
|
||||
}
|
||||
if (response.body() == null) {
|
||||
response.close();
|
||||
return null;
|
||||
}
|
||||
return attachResponseClose(response.body().asInputStream(), response);
|
||||
} catch (IOException e) {
|
||||
if (response != null) {
|
||||
response.close();
|
||||
}
|
||||
throw new DavinciServiceException("FILE_DOWNLOAD_IO", "调用Davinci-portal服务,获取文件流接口异常");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFileBase64(String path) throws DavinciServiceException {
|
||||
if (StringUtils.isEmpty(path)) {
|
||||
return "";
|
||||
}
|
||||
DavinciResult<String> result = this.fileManagerFeign.getFileData(path);
|
||||
requireDavinciResult(result, "getFileData");
|
||||
if (result.isSuccess()) {
|
||||
return result.getData();
|
||||
}
|
||||
throw new DavinciServiceException(result.getCode(), result.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> remove(FileRemoveDTO dto) throws DavinciServiceException {
|
||||
DavinciResult<List<String>> result = this.fileManagerRestFeign.remove(dto);
|
||||
requireDavinciResult(result, "remove");
|
||||
if (result.isSuccess()) {
|
||||
return result.getData();
|
||||
}
|
||||
throw new DavinciServiceException(result.getCode(), result.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream fileDownLoadWithAbsoluteUrl(String url) throws DavinciServiceException {
|
||||
assertSafeHttpUrl(url);
|
||||
OuterCallFeignClient feignClient =
|
||||
Feign.builder().client(new OkHttpClient()).target(OuterCallFeignClient.class, url);
|
||||
Response response;
|
||||
try {
|
||||
response = feignClient.downLoad();
|
||||
} catch (RuntimeException e) {
|
||||
throw new DavinciServiceException("OUTER_DOWNLOAD", "拉取远程文件失败");
|
||||
}
|
||||
try {
|
||||
if (response.body() == null) {
|
||||
response.close();
|
||||
return null;
|
||||
}
|
||||
return attachResponseClose(response.body().asInputStream(), response);
|
||||
} catch (IOException e) {
|
||||
response.close();
|
||||
throw new DavinciServiceException("OUTER_DOWNLOAD", "读取远程文件流失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
package cn.cloudwalk.intelligent.davinci.storage.manager.impl;
|
||||
|
||||
import cn.cloudwalk.intelligent.davinci.common.exception.DavinciServiceException;
|
||||
import cn.cloudwalk.intelligent.davinci.common.result.DavinciResult;
|
||||
import cn.cloudwalk.intelligent.davinci.storage.bean.file.dto.FileRemoveDTO;
|
||||
import cn.cloudwalk.intelligent.davinci.storage.feign.FileManagerFeign;
|
||||
import cn.cloudwalk.intelligent.davinci.storage.feign.OuterCallFeignClient;
|
||||
import cn.cloudwalk.intelligent.davinci.storage.manager.FileStorageManager;
|
||||
import feign.Client;
|
||||
import feign.Feign;
|
||||
import feign.Response;
|
||||
import feign.codec.Decoder;
|
||||
import feign.codec.Encoder;
|
||||
import feign.form.spring.SpringFormEncoder;
|
||||
import feign.okhttp.OkHttpClient;
|
||||
import java.io.FilterInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.cloud.openfeign.FeignClientsConfiguration;
|
||||
import org.springframework.cloud.openfeign.support.SpringMvcContract;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
@Component
|
||||
@Import({ FeignClientsConfiguration.class })
|
||||
public class FileStorageManagerImpl implements FileStorageManager {
|
||||
|
||||
private FileManagerFeign fileManagerFeign;
|
||||
private FileManagerFeign fileManagerRestFeign;
|
||||
|
||||
@Autowired
|
||||
public FileStorageManagerImpl(@Value("${feign.davinci-portal.name:davinci-portal}") String serviceName,
|
||||
Decoder decoder, Encoder encoder, Client client) {
|
||||
String url = "http://" + serviceName + "/portal/fileManager";
|
||||
|
||||
this.fileManagerFeign = Feign.builder().client(client).decode404().encoder(new SpringFormEncoder())
|
||||
.decoder(decoder).contract(new SpringMvcContract()).target(FileManagerFeign.class, url);
|
||||
|
||||
this.fileManagerRestFeign = Feign.builder().client(client).decode404().encoder(encoder).decoder(decoder)
|
||||
.contract(new SpringMvcContract()).target(FileManagerFeign.class, url);
|
||||
}
|
||||
|
||||
/**
|
||||
* 限制通过「绝对 URL」拉流时的 SSRF:仅 http(s),且解析后不得为回环、链路本地、站点本地及常见元数据地址。
|
||||
*/
|
||||
static void assertSafeHttpUrl(String urlString) throws DavinciServiceException {
|
||||
if (StringUtils.isEmpty(urlString)) {
|
||||
throw new DavinciServiceException("INVALID_URL", "URL 为空");
|
||||
}
|
||||
URI uri;
|
||||
try {
|
||||
uri = new URI(urlString);
|
||||
} catch (URISyntaxException e) {
|
||||
throw new DavinciServiceException("INVALID_URL", "URL 非法");
|
||||
}
|
||||
String scheme = uri.getScheme();
|
||||
if (scheme == null || (!"http".equalsIgnoreCase(scheme) && !"https".equalsIgnoreCase(scheme))) {
|
||||
throw new DavinciServiceException("INVALID_URL", "仅允许 http 或 https 协议");
|
||||
}
|
||||
String host = uri.getHost();
|
||||
if (StringUtils.isEmpty(host)) {
|
||||
throw new DavinciServiceException("INVALID_URL", "缺少主机名");
|
||||
}
|
||||
String lowerHost = host.toLowerCase(Locale.ROOT);
|
||||
if ("localhost".equals(lowerHost) || lowerHost.endsWith(".local")) {
|
||||
throw new DavinciServiceException("INVALID_URL", "禁止访问该主机");
|
||||
}
|
||||
if ("metadata.google.internal".equalsIgnoreCase(host)) {
|
||||
throw new DavinciServiceException("INVALID_URL", "禁止访问该主机");
|
||||
}
|
||||
try {
|
||||
InetAddress[] all = InetAddress.getAllByName(host);
|
||||
for (InetAddress addr : all) {
|
||||
if (addr.isAnyLocalAddress() || addr.isLoopbackAddress() || addr.isLinkLocalAddress()
|
||||
|| addr.isSiteLocalAddress() || addr.isMulticastAddress()) {
|
||||
throw new DavinciServiceException("INVALID_URL", "禁止访问内网或保留地址");
|
||||
}
|
||||
}
|
||||
} catch (UnknownHostException e) {
|
||||
throw new DavinciServiceException("INVALID_URL", "无法解析主机");
|
||||
}
|
||||
}
|
||||
|
||||
private static void requireDavinciResult(DavinciResult<?> result, String op) throws DavinciServiceException {
|
||||
if (result == null) {
|
||||
throw new DavinciServiceException("NULL_RESULT", "Davinci-portal 返回空结果: " + op);
|
||||
}
|
||||
}
|
||||
|
||||
private static InputStream attachResponseClose(InputStream bodyStream, Response response) {
|
||||
return new FilterInputStream(bodyStream) {
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
try {
|
||||
super.close();
|
||||
} finally {
|
||||
response.close();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String fileUpload(MultipartFile file) throws DavinciServiceException {
|
||||
DavinciResult<String> result = this.fileManagerFeign.fileUpload(file);
|
||||
requireDavinciResult(result, "fileUpload");
|
||||
if (result.isSuccess()) {
|
||||
return result.getData();
|
||||
}
|
||||
throw new DavinciServiceException(result.getCode(), result.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String fileUpload(String moduleCategory, MultipartFile file) throws DavinciServiceException {
|
||||
DavinciResult<String> result = this.fileManagerFeign.fileUpload(moduleCategory, file);
|
||||
requireDavinciResult(result, "fileUpload(module)");
|
||||
if (result.isSuccess()) {
|
||||
return result.getData();
|
||||
}
|
||||
throw new DavinciServiceException(result.getCode(), result.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String bigFileUpload(MultipartFile file) throws DavinciServiceException {
|
||||
DavinciResult<String> result = this.fileManagerFeign.bigFileUpload(file);
|
||||
requireDavinciResult(result, "bigFileUpload");
|
||||
if (result.isSuccess()) {
|
||||
return result.getData();
|
||||
}
|
||||
throw new DavinciServiceException(result.getCode(), result.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String bigFileUpload(String moduleCategory, MultipartFile file) throws DavinciServiceException {
|
||||
DavinciResult<String> result = this.fileManagerFeign.bigFileUpload(moduleCategory, file);
|
||||
requireDavinciResult(result, "bigFileUpload(module)");
|
||||
if (result.isSuccess()) {
|
||||
return result.getData();
|
||||
}
|
||||
throw new DavinciServiceException(result.getCode(), result.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] fileDownload(String path) throws DavinciServiceException {
|
||||
try (Response response = this.fileManagerFeign.fileDownload(path)) {
|
||||
if (response == null) {
|
||||
return null;
|
||||
}
|
||||
if (response.body() == null) {
|
||||
return null;
|
||||
}
|
||||
try (InputStream inputStream = response.body().asInputStream()) {
|
||||
return IOUtils.toByteArray(inputStream);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new DavinciServiceException("FILE_DOWNLOAD_IO", "调用Davinci-portal服务,获取文件流接口异常");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream fileDownloadStream(String path) throws DavinciServiceException {
|
||||
Response response = this.fileManagerFeign.fileDownload(path);
|
||||
try {
|
||||
if (response == null) {
|
||||
return null;
|
||||
}
|
||||
if (response.body() == null) {
|
||||
response.close();
|
||||
return null;
|
||||
}
|
||||
return attachResponseClose(response.body().asInputStream(), response);
|
||||
} catch (IOException e) {
|
||||
if (response != null) {
|
||||
response.close();
|
||||
}
|
||||
throw new DavinciServiceException("FILE_DOWNLOAD_IO", "调用Davinci-portal服务,获取文件流接口异常");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFileBase64(String path) throws DavinciServiceException {
|
||||
if (StringUtils.isEmpty(path)) {
|
||||
return "";
|
||||
}
|
||||
DavinciResult<String> result = this.fileManagerFeign.getFileData(path);
|
||||
requireDavinciResult(result, "getFileData");
|
||||
if (result.isSuccess()) {
|
||||
return result.getData();
|
||||
}
|
||||
throw new DavinciServiceException(result.getCode(), result.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> remove(FileRemoveDTO dto) throws DavinciServiceException {
|
||||
DavinciResult<List<String>> result = this.fileManagerRestFeign.remove(dto);
|
||||
requireDavinciResult(result, "remove");
|
||||
if (result.isSuccess()) {
|
||||
return result.getData();
|
||||
}
|
||||
throw new DavinciServiceException(result.getCode(), result.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream fileDownLoadWithAbsoluteUrl(String url) throws DavinciServiceException {
|
||||
assertSafeHttpUrl(url);
|
||||
OuterCallFeignClient feignClient = Feign.builder().client(new OkHttpClient()).target(OuterCallFeignClient.class,
|
||||
url);
|
||||
Response response;
|
||||
try {
|
||||
response = feignClient.downLoad();
|
||||
} catch (RuntimeException e) {
|
||||
throw new DavinciServiceException("OUTER_DOWNLOAD", "拉取远程文件失败");
|
||||
}
|
||||
try {
|
||||
if (response.body() == null) {
|
||||
response.close();
|
||||
return null;
|
||||
}
|
||||
return attachResponseClose(response.body().asInputStream(), response);
|
||||
} catch (IOException e) {
|
||||
response.close();
|
||||
throw new DavinciServiceException("OUTER_DOWNLOAD", "读取远程文件流失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user