Merge branch 'master' into feature/REQ-2322
This commit is contained in:
commit
f8a8a6ae58
@ -13,7 +13,7 @@ import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
@Slf4j
|
||||
@MapperScan(basePackages = {"cn.axzo.oss.dal.mapper", "cn.axzo.oss.client.icon.mapper"})
|
||||
@EnableFeignClients(basePackages = {"cn.axzo.log.platform.client"})
|
||||
@SpringBootApplication(scanBasePackages = {"cn.axzo.oss"})
|
||||
@SpringBootApplication(scanBasePackages = {"cn.axzo.oss","com.axzo.framework"})
|
||||
public class Bootstrap {
|
||||
public static void main(String[] args) {
|
||||
log.info("axzo oss begin starting...");
|
||||
|
||||
@ -22,16 +22,19 @@ import cn.axzo.oss.http.model.FindFileUrlResponse;
|
||||
import cn.axzo.oss.http.model.GetObjectMetaRequest;
|
||||
import cn.axzo.oss.http.model.GetObjectMetaResponse;
|
||||
import cn.axzo.oss.http.model.ServerFileDeleteRequest;
|
||||
import cn.axzo.oss.http.model.ServerFileUploadByUrlRequest;
|
||||
import cn.axzo.oss.http.model.ServerFileUploadRequest;
|
||||
import cn.axzo.oss.http.model.ServerFileUploadResponse;
|
||||
import cn.axzo.oss.http.model.ServerFileUploadV2Request;
|
||||
import cn.axzo.oss.manager.api.dto.request.FindFileKeyDto;
|
||||
import cn.axzo.oss.manager.api.dto.request.FindFileUrlDto;
|
||||
import cn.axzo.oss.manager.api.dto.request.ServerFileDeleteDto;
|
||||
import cn.axzo.oss.manager.api.dto.request.ServerFileUploadByUrlDto;
|
||||
import cn.axzo.oss.manager.api.dto.request.ServerFileUploadDto;
|
||||
import cn.axzo.oss.manager.api.dto.request.SignUrlDownloadDto;
|
||||
import cn.axzo.oss.manager.api.dto.request.SignUrlUploadDto;
|
||||
import cn.axzo.oss.manager.api.dto.response.ManaGetObjectMetaResponse;
|
||||
import cn.axzo.oss.service.api.FileByUrlService;
|
||||
import cn.axzo.oss.service.api.FileService;
|
||||
import cn.azxo.framework.common.model.CommonResponse;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
@ -62,6 +65,9 @@ public class ServerFileController implements ServerFileServiceApi {
|
||||
@Autowired
|
||||
private FileService fileService;
|
||||
|
||||
@Autowired
|
||||
private FileByUrlService fileByUrlService;
|
||||
|
||||
@Autowired
|
||||
private HttpServletRequest httpServletRequest;
|
||||
|
||||
@ -152,15 +158,30 @@ public class ServerFileController implements ServerFileServiceApi {
|
||||
throw new BizException(CodeEnum.URL_BUCKET_NAME_KEY_ALL_EMPTY);
|
||||
}
|
||||
|
||||
|
||||
String bucketName = UrlUtil.fetchBucketName(request.getBucketName(), request.getUrl());
|
||||
String bucketKey = UrlUtil.fetchBucketKey(request.getKey(), request.getUrl());
|
||||
ManaGetObjectMetaResponse response = this.fileService.getObjectMeta(bucketName
|
||||
, bucketKey, request.getUrl()
|
||||
, ChannelTypeEnum.OSS.getChannelCode());
|
||||
, this.swtchChannelCode(request.getUrl()));
|
||||
return CommonResponse.success(BeanConverter.convert(response, GetObjectMetaResponse.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* 决定渠道
|
||||
*/
|
||||
private String swtchChannelCode(String url) {
|
||||
if (!StringUtils.hasText(url)) {
|
||||
return "";
|
||||
}
|
||||
if (url.toLowerCase().contains("aliyun")) {
|
||||
return ChannelTypeEnum.OSS.getChannelCode();
|
||||
}
|
||||
if (url.toLowerCase().contains("huaweicloud")) {
|
||||
return ChannelTypeEnum.OBS.getChannelCode();
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件元数据信息-批量
|
||||
*/
|
||||
@ -179,4 +200,18 @@ public class ServerFileController implements ServerFileServiceApi {
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 通过URL上传文件
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public CommonResponse<ServerFileUploadResponse> uploadByUrl(@Valid @RequestBody ServerFileUploadByUrlRequest request) {
|
||||
ServerFileUploadByUrlDto dto = BeanConvertUtil.copyBean(request, ServerFileUploadByUrlDto.class);
|
||||
// 获取feign调用请求头携带的用户信息
|
||||
String contextInfoLiteJsonStr = httpServletRequest.getHeader("X-CONTEXT-INFO-LITE");
|
||||
ContextInfo.LiteSaasContext liteSaasContext = JSONUtil.toBean(contextInfoLiteJsonStr, ContextInfo.LiteSaasContext.class);
|
||||
return CommonResponse.success(BeanConverter.convert(fileByUrlService.uploadByUrl(dto.getAppCode(), dto.getBizScene(), dto.getFileName(), dto.getFileUrl(), dto.getChannelCode(), dto.getStyle(), liteSaasContext), ServerFileUploadResponse.class));
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,6 +26,7 @@ public enum ChannelTypeEnum {
|
||||
private final String channelCode;
|
||||
|
||||
private final static Map<String, ChannelTypeEnum> channelCodeMap = Arrays.stream(ChannelTypeEnum.values()).collect(Collectors.toMap(ChannelTypeEnum::getChannelCode, Function.identity()));
|
||||
private final static Map<Integer, ChannelTypeEnum> codeMap = Arrays.stream(ChannelTypeEnum.values()).collect(Collectors.toMap(ChannelTypeEnum::getCode, Function.identity()));
|
||||
|
||||
ChannelTypeEnum(Integer code, String message, String channelCode) {
|
||||
this.code = code;
|
||||
@ -45,9 +46,16 @@ public enum ChannelTypeEnum {
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过code获取枚举
|
||||
* 通过channelCode获取枚举
|
||||
*/
|
||||
public static ChannelTypeEnum getChannelTypeByChannelCode(String channelCode) {
|
||||
return channelCodeMap.get(channelCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过code获取枚举
|
||||
*/
|
||||
public static ChannelTypeEnum getChannelTypeByCode(Integer code) {
|
||||
return codeMap.get(code);
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,8 +10,14 @@ import org.apache.commons.lang3.StringUtils;
|
||||
public class UrlUtil {
|
||||
|
||||
|
||||
public static String HTTP = "http:";
|
||||
public static String HTTPS = "https:";
|
||||
public static String HTTP_START = "http:";
|
||||
public static String HTTPS_START = "https:";
|
||||
public static String X_OSS_PROCESS = "x-oss-process";
|
||||
public static String X_OSS_PROCESS_APPEND = "?x-oss-process=";
|
||||
public static String X_IMAGE_PROCESS = "x-image-process";
|
||||
public static String X_IMAGE_PROCESS_APPEND = "?x-image-process=";
|
||||
public static String ALIYUN = "aliyun";
|
||||
public static String HUAWEICLOUD = "huaweicloud";
|
||||
|
||||
/**
|
||||
* http的url替换成https
|
||||
@ -20,8 +26,8 @@ public class UrlUtil {
|
||||
if (StringUtils.isBlank(str)) {
|
||||
return str;
|
||||
}
|
||||
if (str.startsWith(HTTP)) {
|
||||
return HTTPS + str.substring(str.indexOf(HTTP) + HTTP.length());
|
||||
if (str.startsWith(HTTP_START)) {
|
||||
return HTTPS_START + str.substring(str.indexOf(HTTP_START) + HTTP_START.length());
|
||||
}
|
||||
return str;
|
||||
}
|
||||
@ -47,11 +53,16 @@ public class UrlUtil {
|
||||
if (org.springframework.util.StringUtils.hasText(bucketKey)) {
|
||||
return bucketKey;
|
||||
}
|
||||
if (org.springframework.util.StringUtils.hasText(url)) {
|
||||
if (url.contains(".") && url.contains("//")) {
|
||||
String urlPathNoHttp = url.split("//")[1];
|
||||
return urlPathNoHttp.substring(urlPathNoHttp.indexOf("/") + 1);
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(url)) {
|
||||
return url;
|
||||
}
|
||||
if (url.contains("?")) {
|
||||
url = url.split("\\?")[0];
|
||||
}
|
||||
if (url.contains(".") && url.contains("//")) {
|
||||
String urlPathNoHttp = url.split("//")[1];
|
||||
return urlPathNoHttp.substring(urlPathNoHttp.indexOf("/") + 1);
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
@ -14,6 +14,7 @@ import cn.axzo.oss.http.model.FindFileUrlResponse;
|
||||
import cn.axzo.oss.http.model.GetObjectMetaRequest;
|
||||
import cn.axzo.oss.http.model.GetObjectMetaResponse;
|
||||
import cn.axzo.oss.http.model.ServerFileDeleteRequest;
|
||||
import cn.axzo.oss.http.model.ServerFileUploadByUrlRequest;
|
||||
import cn.axzo.oss.http.model.ServerFileUploadRequest;
|
||||
import cn.axzo.oss.http.model.ServerFileUploadResponse;
|
||||
import cn.axzo.oss.http.model.ServerFileUploadV2Request;
|
||||
@ -98,4 +99,12 @@ public interface ServerFileServiceApi {
|
||||
@RequestMapping(value = "api/server/batchGetObjectMeta", method = RequestMethod.POST)
|
||||
CommonResponse<BatchGetObjectMetaResponse> batchGetObjectMeta(BatchGetObjectMetaRequest request);
|
||||
|
||||
/**
|
||||
* 通过URL上传文件
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/api/v1/server/uploadByUrl", method = RequestMethod.POST)
|
||||
CommonResponse<ServerFileUploadResponse> uploadByUrl(ServerFileUploadByUrlRequest request);
|
||||
|
||||
}
|
||||
|
||||
@ -32,4 +32,14 @@ public class ApiSignUrlDownloadRequest {
|
||||
*/
|
||||
private String bizScene;
|
||||
|
||||
/**
|
||||
* 图片样式,比如x-oss-process=image/auto-orient,1/resize,p_50/quality,q_30
|
||||
*/
|
||||
private String style;
|
||||
|
||||
/**
|
||||
* 是否带上文件名称
|
||||
*/
|
||||
private Boolean hasFileName = true;
|
||||
|
||||
}
|
||||
|
||||
@ -56,4 +56,9 @@ public class ApiSignUrlUploadRequest {
|
||||
* 过期时间
|
||||
*/
|
||||
private Long expiration;
|
||||
|
||||
/**
|
||||
* 是否带上文件名称
|
||||
*/
|
||||
private Boolean hasFileName = true;
|
||||
}
|
||||
|
||||
@ -46,4 +46,9 @@ public class ApiSignUrlUploadResponse {
|
||||
* 下载url
|
||||
*/
|
||||
private String downloadSignUrl;
|
||||
|
||||
/**
|
||||
* 文件名称
|
||||
*/
|
||||
private String fileName;
|
||||
}
|
||||
|
||||
@ -0,0 +1,35 @@
|
||||
package cn.axzo.oss.http.model;
|
||||
|
||||
import lombok.Data;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 服务端文件上传请求类
|
||||
*
|
||||
* @author zhaoyong
|
||||
* @see ServerFileUploadByUrlRequest
|
||||
* @since 2021-07-23 10:35
|
||||
*/
|
||||
@Data
|
||||
public class ServerFileUploadByUrlRequest {
|
||||
|
||||
@NotBlank(message = "appCode must not be null")
|
||||
private String appCode;
|
||||
@NotBlank(message = "bizScene must not be null")
|
||||
private String bizScene;
|
||||
@NotBlank(message = "fileName must not be null")
|
||||
@Length(max = 128, message = "文件名不能超过128个字符")
|
||||
private String fileName;
|
||||
@NotNull(message = "fileUrl must not be null")
|
||||
private String fileUrl;
|
||||
|
||||
private Integer channelCode;
|
||||
/**
|
||||
* 图片样式,比如x-oss-process=image/auto-orient,1/resize,p_50/quality,q_30
|
||||
*/
|
||||
private String style;
|
||||
|
||||
}
|
||||
@ -14,7 +14,7 @@ public interface AliOssService extends BaseS3Service {
|
||||
/**
|
||||
* 授权给第三方下载
|
||||
*/
|
||||
String downloadSignUrl(String bucketName, String key, Long expireSecond, String fileName);
|
||||
String downloadSignUrl(String bucketName, String key, Long expireSecond, String fileName, boolean hasFileName);
|
||||
|
||||
/**
|
||||
* 授权给第三方-上传
|
||||
@ -35,4 +35,9 @@ public interface AliOssService extends BaseS3Service {
|
||||
*/
|
||||
SimplifiedObjectMeta getObjectMeta(String bucketName, String key, String url);
|
||||
|
||||
|
||||
/**
|
||||
* 通过url上传至OBS
|
||||
*/
|
||||
String uploadByUrl(String bucketName, String tgtFileKey, String fileName, String url);
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package cn.axzo.oss.integration.s3;
|
||||
|
||||
import com.obs.services.model.ObjectMetadata;
|
||||
import com.obs.services.model.TemporarySignatureResponse;
|
||||
|
||||
import java.io.InputStream;
|
||||
@ -24,7 +25,7 @@ public interface HuaWeiCloudService {
|
||||
/**
|
||||
* 授权给第三方-下载
|
||||
*/
|
||||
String downloadSignUrl(String bucketName, String key, Long expireSecond, String fileName);
|
||||
String downloadSignUrl(String bucketName, String key, Long expireSecond, String fileName, String style, boolean hasFilename);
|
||||
|
||||
/**
|
||||
* 授权给第三方-上传
|
||||
@ -40,4 +41,14 @@ public interface HuaWeiCloudService {
|
||||
* 获取url
|
||||
*/
|
||||
String getUrl(String bucketName, String tgtFileKey);
|
||||
|
||||
/**
|
||||
* 通过url上传OBS
|
||||
*/
|
||||
String uploadFileByUrl(String bucketName, String key, String fileName, String url);
|
||||
|
||||
/**
|
||||
* 元数据
|
||||
*/
|
||||
ObjectMetadata getObjectMeta(String bucketName, String key, String url);
|
||||
}
|
||||
|
||||
@ -289,7 +289,7 @@ public class AliOssServiceImpl implements AliOssService {
|
||||
* 授权给第三方-下载
|
||||
*/
|
||||
@Override
|
||||
public String downloadSignUrl(String bucketName, String key, Long expireSecond, String fileName) {
|
||||
public String downloadSignUrl(String bucketName, String key, Long expireSecond, String fileName, boolean hasFileName) {
|
||||
Date date = new Date();
|
||||
date.setTime(date.getTime() + expireSecond * 1000);
|
||||
try {
|
||||
@ -297,7 +297,9 @@ public class AliOssServiceImpl implements AliOssService {
|
||||
GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, key, HttpMethod.GET);
|
||||
request.setExpiration(date);
|
||||
ResponseHeaderOverrides responseHeaderOverrides = new ResponseHeaderOverrides();
|
||||
responseHeaderOverrides.setContentDisposition("attachment;filename=\"" + URLEncoder.encode(fileName, "utf-8") + "\"");
|
||||
if (hasFileName) {
|
||||
responseHeaderOverrides.setContentDisposition("attachment;filename=\"" + URLEncoder.encode(fileName, "utf-8") + "\"");
|
||||
}
|
||||
request.setResponseHeaders(responseHeaderOverrides);
|
||||
URL url = aliOssClient.getClient().generatePresignedUrl(request);
|
||||
log.info("aliyun downloadSignUrl result, bucketName:{}, key:{}, url:{}", bucketName, key, JsonUtil.obj2Str(url));
|
||||
@ -390,4 +392,29 @@ public class AliOssServiceImpl implements AliOssService {
|
||||
return new SimplifiedObjectMeta();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过url上传至OSS
|
||||
*/
|
||||
@Override
|
||||
public String uploadByUrl(String bucketName, String tgtFileKey, String fileName, String url) {
|
||||
OSS client = aliOssClient.getClient();
|
||||
try {
|
||||
InputStream srcStream = new URL(url).openStream();
|
||||
// 创建上传文件的元信息,通过文件云信息设置HTTP Header
|
||||
ObjectMetadata metadata = new ObjectMetadata();
|
||||
// 设置内容被下载时的名称
|
||||
metadata.setContentDisposition("attachment;filename=\"" + URLEncoder.encode(fileName, "utf-8") + "\"");
|
||||
metadata.setContentEncoding("utf-8");
|
||||
client.putObject(bucketName, tgtFileKey, srcStream, metadata);
|
||||
} catch (OSSException e) {
|
||||
LogUtil.error("uploadByStream OSSException", e);
|
||||
return "";
|
||||
} catch (Exception e) {
|
||||
LogUtil.error("uploadByStream ClientException", e);
|
||||
return "";
|
||||
}
|
||||
|
||||
return getUrl(bucketName, tgtFileKey);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
package cn.axzo.oss.integration.s3.impl;
|
||||
|
||||
import cn.axzo.oss.common.enums.FileDownloadTypeEnum;
|
||||
import cn.axzo.oss.common.enums.CodeEnum;
|
||||
import cn.axzo.oss.common.enums.FileDownloadTypeEnum;
|
||||
import cn.axzo.oss.common.exception.BizException;
|
||||
import cn.axzo.oss.common.utils.JsonUtil;
|
||||
import cn.axzo.oss.integration.s3.HuaWeiCloudService;
|
||||
@ -13,12 +13,33 @@ import cn.hutool.json.JSONUtil;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.obs.services.ObsClient;
|
||||
import com.obs.services.exception.ObsException;
|
||||
import com.obs.services.model.*;
|
||||
import com.obs.services.model.CompleteMultipartUploadRequest;
|
||||
import com.obs.services.model.CompleteMultipartUploadResult;
|
||||
import com.obs.services.model.DeleteObjectResult;
|
||||
import com.obs.services.model.DownloadFileRequest;
|
||||
import com.obs.services.model.DownloadFileResult;
|
||||
import com.obs.services.model.GetObjectRequest;
|
||||
import com.obs.services.model.HttpMethodEnum;
|
||||
import com.obs.services.model.InitiateMultipartUploadRequest;
|
||||
import com.obs.services.model.InitiateMultipartUploadResult;
|
||||
import com.obs.services.model.ObjectMetadata;
|
||||
import com.obs.services.model.ObsObject;
|
||||
import com.obs.services.model.PartEtag;
|
||||
import com.obs.services.model.PutObjectRequest;
|
||||
import com.obs.services.model.PutObjectResult;
|
||||
import com.obs.services.model.TemporarySignatureRequest;
|
||||
import com.obs.services.model.TemporarySignatureResponse;
|
||||
import com.obs.services.model.UploadFileRequest;
|
||||
import com.obs.services.model.UploadPartRequest;
|
||||
import com.obs.services.model.UploadPartResult;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
@ -331,14 +352,21 @@ public class HuaWeiCloudServiceImpl implements HuaWeiCloudService {
|
||||
* 授权给第三方-下载
|
||||
*/
|
||||
@Override
|
||||
public String downloadSignUrl(String bucketName, String key, Long expireSeconds, String fileName) {
|
||||
public String downloadSignUrl(String bucketName, String key, Long expireSeconds, String fileName, String style, boolean hasFilename) {
|
||||
TemporarySignatureRequest request = new TemporarySignatureRequest(HttpMethodEnum.GET, expireSeconds);
|
||||
request.setBucketName(bucketName);
|
||||
request.setObjectKey(key);
|
||||
Map<String, Object> queryParams = Maps.newHashMap();
|
||||
try {
|
||||
queryParams.put("response-content-disposition", "attachment;filename=\"" + URLEncoder.encode(fileName, "utf-8") + "\"");
|
||||
request.setQueryParams(queryParams);
|
||||
if (hasFilename) {
|
||||
queryParams.put("response-content-disposition", "attachment;filename=\"" + URLEncoder.encode(fileName, "utf-8") + "\"");
|
||||
}
|
||||
if (StringUtils.hasText(style)) {
|
||||
queryParams.put("x-image-process", style);
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(queryParams)) {
|
||||
request.setQueryParams(queryParams);
|
||||
}
|
||||
log.info("huawei cloud downloadSignUrl params, bucketName:{}, key:{}, request:{}", bucketName, key, JsonUtil.obj2Str(request));
|
||||
TemporarySignatureResponse response = huaWeiCloudObsClient.getClient().createTemporarySignature(request);
|
||||
log.info("huawei cloud downloadSignUrl result, bucketName:{}, key:{}, request:{}", bucketName, key, JsonUtil.obj2Str(response));
|
||||
@ -403,4 +431,45 @@ public class HuaWeiCloudServiceImpl implements HuaWeiCloudService {
|
||||
|
||||
return allBuilder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过URL上传文件到OBS
|
||||
*/
|
||||
@Override
|
||||
public String uploadFileByUrl(String bucketName, String key, String fileName, String url) {
|
||||
ObsClient obsClient = huaWeiCloudObsClient.getClient();
|
||||
try {
|
||||
InputStream srcStream = new URL(url).openStream();
|
||||
// 创建上传文件的元信息,通过文件云信息设置HTTP Header
|
||||
ObjectMetadata metadata = new ObjectMetadata();
|
||||
// 设置内容被下载时的名称
|
||||
metadata.setContentDisposition("attachment;filename=\"" + URLEncoder.encode(fileName, "utf-8") + "\"");
|
||||
metadata.setContentEncoding("utf-8");
|
||||
PutObjectResult putObjectResult = obsClient.putObject(bucketName, key, srcStream, metadata);
|
||||
return putObjectResult.getObjectUrl();
|
||||
} catch (Exception e) {
|
||||
log.error("通过url上传 exception,bucketName:{}, key:{}, fileName:{},url:{}", bucketName, key, fileName, url);
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 元数据
|
||||
*/
|
||||
@Override
|
||||
public ObjectMetadata getObjectMeta(String bucketName, String key, String url) {
|
||||
try {
|
||||
if (org.apache.commons.lang3.StringUtils.isNotBlank(url) && url.toLowerCase().startsWith("http") && url.toLowerCase().contains("huaweicloud")) {
|
||||
return huaWeiCloudObsClient.getClient().getObjectMetadata(bucketName, key);
|
||||
}
|
||||
log.info("huaweicloud-none-endpoint getObjectMeta params, bucketName:{}, key:{},url:{}", bucketName, key, url);
|
||||
return new ObjectMetadata();
|
||||
} catch (Exception e) {
|
||||
log.warn("huaweicloud-getObjectMeta-exception, bucketName:{}, key:{}", bucketName, key, e);
|
||||
return new ObjectMetadata();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -60,12 +60,12 @@ public interface FileManager {
|
||||
/**
|
||||
* 根据华为云/阿里云,授权给第三方下载
|
||||
*/
|
||||
String signUrlDownload(String bucketName, String key, Long expireSecond, String channelCode, String fileName);
|
||||
String signUrlDownload(String bucketName, String key, Long expireSecond, String channelCode, String fileName, String style, boolean hasFileName);
|
||||
|
||||
/**
|
||||
* 根据华为云/阿里云,授权给第三方上传
|
||||
*/
|
||||
SignUrlUploadVo signUrlUpload(String bucketName, String key, String fileName, Long expireSecond, String channelCode, String contentType, String bucketType);
|
||||
SignUrlUploadVo signUrlUpload(String bucketName, String key, String fileName, Long expireSecond, String channelCode, String contentType, String bucketType, boolean hasFileName);
|
||||
|
||||
/**
|
||||
* 删除File
|
||||
@ -81,4 +81,10 @@ public interface FileManager {
|
||||
* 元数据
|
||||
*/
|
||||
ManaGetObjectMetaResponse getObjectMeta(String bucketName, String key, String url,String channelCode);
|
||||
|
||||
/**
|
||||
* 通过url上传至云
|
||||
*/
|
||||
String uploadByUrl(String bulkName, String keyPath, String fileName, String url,
|
||||
String channelCode);
|
||||
}
|
||||
|
||||
@ -0,0 +1,33 @@
|
||||
package cn.axzo.oss.manager.api.dto.request;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.ToString;
|
||||
|
||||
/**
|
||||
* @program: oss
|
||||
* @description: 文件上传
|
||||
* @author: mr.jie
|
||||
* @date: 2021-07-29 18:31
|
||||
**/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@ToString
|
||||
public class ServerFileUploadByUrlDto {
|
||||
private String appCode;
|
||||
private String bizScene;
|
||||
private String fileName;
|
||||
private String fileUrl;
|
||||
private String filePath;
|
||||
private Integer channelCode;
|
||||
|
||||
/**
|
||||
* 图片样式,比如x-oss-process=image/auto-orient,1/resize,p_50/quality,q_30
|
||||
*/
|
||||
private String style;
|
||||
|
||||
}
|
||||
@ -34,4 +34,13 @@ public class SignUrlDownloadDto {
|
||||
*/
|
||||
private String bizScene;
|
||||
|
||||
/**
|
||||
* 图片样式,比如x-oss-process=image/auto-orient,1/resize,p_50/quality,q_30
|
||||
*/
|
||||
private String style;
|
||||
/**
|
||||
* 是否带上文件名称
|
||||
*/
|
||||
private Boolean hasFileName = true;
|
||||
|
||||
}
|
||||
|
||||
@ -57,4 +57,9 @@ public class SignUrlUploadDto {
|
||||
* 过期时间
|
||||
*/
|
||||
private Long expiration;
|
||||
|
||||
/**
|
||||
* 是否带上文件名称
|
||||
*/
|
||||
private Boolean hasFileName = true;
|
||||
}
|
||||
|
||||
@ -46,4 +46,9 @@ public class SignUrlUploadResponse {
|
||||
* 下载url
|
||||
*/
|
||||
private String downloadSignUrl;
|
||||
|
||||
/**
|
||||
* 文件名称
|
||||
*/
|
||||
private String fileName;
|
||||
}
|
||||
|
||||
@ -16,6 +16,7 @@ import cn.axzo.oss.manager.api.dto.request.MultipartUploadDto;
|
||||
import cn.axzo.oss.manager.api.dto.response.ManaGetObjectMetaResponse;
|
||||
import cn.axzo.oss.manager.api.vo.SignUrlUploadVo;
|
||||
import com.aliyun.oss.model.SimplifiedObjectMeta;
|
||||
import com.obs.services.model.ObjectMetadata;
|
||||
import com.obs.services.model.TemporarySignatureResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
@ -150,13 +151,13 @@ public class FileManagerImpl implements FileManager {
|
||||
* 根据华为云/阿里云,授权给第三方下载
|
||||
*/
|
||||
@Override
|
||||
public String signUrlDownload(String bucketName, String key, Long expireSecond, String channelCode, String fileName) {
|
||||
public String signUrlDownload(String bucketName, String key, Long expireSecond, String channelCode, String fileName, String style, boolean hasFileName) {
|
||||
ChannelTypeEnum typeEnum = ChannelTypeEnum.getChannelTypeByChannelCode(channelCode);
|
||||
switch (typeEnum) {
|
||||
case OBS:// 华为云
|
||||
return huaWeiCloudService.downloadSignUrl(bucketName, key, expireSecond, fileName);
|
||||
return huaWeiCloudService.downloadSignUrl(bucketName, key, expireSecond, fileName, style, hasFileName);
|
||||
case OSS:// 阿里云
|
||||
return aliOssService.downloadSignUrl(bucketName, key, expireSecond, fileName);
|
||||
return aliOssService.downloadSignUrl(bucketName, key, expireSecond, fileName, hasFileName);
|
||||
default:
|
||||
BizException.error(CodeEnum.CHANNEL_TYPE_NOT_EXIST);
|
||||
}
|
||||
@ -167,7 +168,7 @@ public class FileManagerImpl implements FileManager {
|
||||
* 根据华为云/阿里云,授权给第三方上传
|
||||
*/
|
||||
@Override
|
||||
public SignUrlUploadVo signUrlUpload(String bucketName, String key, String fileName, Long expireSecond, String channelCode, String contentType, String bucketType) {
|
||||
public SignUrlUploadVo signUrlUpload(String bucketName, String key, String fileName, Long expireSecond, String channelCode, String contentType, String bucketType, boolean hasFileName) {
|
||||
ChannelTypeEnum typeEnum = ChannelTypeEnum.getChannelTypeByChannelCode(channelCode);
|
||||
switch (typeEnum) {
|
||||
case OBS:// 华为云
|
||||
@ -178,13 +179,13 @@ public class FileManagerImpl implements FileManager {
|
||||
.host(response.getActualSignedRequestHeaders().get(HUAWEI_CLOUD_SIGNURL_UPLOAD_HOST_KEY))
|
||||
.contentType(response.getActualSignedRequestHeaders().get(HUAWEI_CLOUD_SIGNURL_UPLOAD_CONTENT_TYPE_KEY))
|
||||
.channelCode(channelCode)
|
||||
.downloadSignUrl(UrlUtil.httpToHttps(this.downloadHuaweiSignUrl(bucketName, key, expireSecond, bucketType, fileName)))
|
||||
.downloadSignUrl(UrlUtil.httpToHttps(this.downloadHuaweiSignUrl(bucketName, key, expireSecond, bucketType, fileName, hasFileName)))
|
||||
.build();
|
||||
case OSS:// 阿里云
|
||||
return SignUrlUploadVo.builder()
|
||||
.signUrl(UrlUtil.httpToHttps(aliOssService.uploadSignUrl(bucketName, key, fileName,expireSecond)))
|
||||
.channelCode(channelCode)
|
||||
.downloadSignUrl(UrlUtil.httpToHttps(this.downloadAliyunSignUrl(bucketName, key, expireSecond, bucketType, fileName)))
|
||||
.downloadSignUrl(UrlUtil.httpToHttps(this.downloadAliyunSignUrl(bucketName, key, expireSecond, bucketType, fileName, hasFileName)))
|
||||
.build();
|
||||
default:
|
||||
BizException.error(CodeEnum.CHANNEL_TYPE_NOT_EXIST);
|
||||
@ -195,10 +196,10 @@ public class FileManagerImpl implements FileManager {
|
||||
/**
|
||||
* 构建华为云下载地址
|
||||
*/
|
||||
private String downloadHuaweiSignUrl(String bucketName, String key, Long expireSecond, String bucketType, String fileName) {
|
||||
private String downloadHuaweiSignUrl(String bucketName, String key, Long expireSecond, String bucketType, String fileName, boolean hasFileName) {
|
||||
switch (BucketTypeEnum.getByCode(bucketType)) {
|
||||
case PRIVATE_BUCKET:
|
||||
return huaWeiCloudService.downloadSignUrl(bucketName, key, expireSecond, fileName);
|
||||
return huaWeiCloudService.downloadSignUrl(bucketName, key, expireSecond, fileName, null, hasFileName);
|
||||
case PUBLIC_BUCKET:
|
||||
return huaWeiCloudService.getUrl(bucketName, key);
|
||||
default:
|
||||
@ -210,10 +211,10 @@ public class FileManagerImpl implements FileManager {
|
||||
/**
|
||||
* 构建阿里云下载地址
|
||||
*/
|
||||
private String downloadAliyunSignUrl(String bucketName, String key, Long expireSecond, String bucketType, String fileName) {
|
||||
private String downloadAliyunSignUrl(String bucketName, String key, Long expireSecond, String bucketType, String fileName, boolean hasFileName) {
|
||||
switch (BucketTypeEnum.getByCode(bucketType)) {
|
||||
case PRIVATE_BUCKET:
|
||||
return aliOssService.downloadSignUrl(bucketName, key, expireSecond, fileName);
|
||||
return aliOssService.downloadSignUrl(bucketName, key, expireSecond, fileName, hasFileName);
|
||||
case PUBLIC_BUCKET:
|
||||
return aliOssService.getUrl(bucketName, key);
|
||||
default:
|
||||
@ -263,7 +264,8 @@ public class FileManagerImpl implements FileManager {
|
||||
ChannelTypeEnum typeEnum = ChannelTypeEnum.getChannelTypeByChannelCode(channelCode);
|
||||
switch (typeEnum) {
|
||||
case OBS:// 华为云
|
||||
return ManaGetObjectMetaResponse.builder().build();
|
||||
ObjectMetadata objectMetadata = huaWeiCloudService.getObjectMeta(bucketName, key, url);
|
||||
return ManaGetObjectMetaResponse.builder().bucketName(bucketName).key(key).size(objectMetadata.getContentLength()).build();
|
||||
case OSS:// 阿里云
|
||||
SimplifiedObjectMeta simplifiedObjectMeta = aliOssService.getObjectMeta(bucketName, key, url);
|
||||
return ManaGetObjectMetaResponse.builder().bucketName(bucketName).key(key).size(simplifiedObjectMeta.getSize()).build();
|
||||
@ -272,4 +274,26 @@ public class FileManagerImpl implements FileManager {
|
||||
}
|
||||
return ManaGetObjectMetaResponse.builder().build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过url上传至云
|
||||
*/
|
||||
public String uploadByUrl(String bulkName, String keyPath, String fileName, String url,
|
||||
String channelCode) {
|
||||
try {
|
||||
switch (ChannelTypeEnum.getChannelTypeByChannelCode(channelCode)) {
|
||||
case OSS:
|
||||
return aliOssService.uploadByUrl(bulkName,keyPath, fileName, url);
|
||||
case OBS:
|
||||
return huaWeiCloudService.uploadFileByUrl(bulkName, keyPath, fileName, url);
|
||||
default:
|
||||
BizException.error(CodeEnum.CHANNEL_TYPE_NOT_EXIST);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("通过url上传至云 exception,bulkName:{}, key:{}, fileName:{}, url:{},channelCode:{}"
|
||||
, bulkName, keyPath, fileName, url, channelCode, e);
|
||||
}
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,41 @@
|
||||
package cn.axzo.oss.service.api;
|
||||
|
||||
import cn.axzo.framework.auth.domain.ContextInfo;
|
||||
import cn.axzo.oss.manager.api.dto.request.DeleteFileDto;
|
||||
import cn.axzo.oss.manager.api.dto.request.FindFileKeyDto;
|
||||
import cn.axzo.oss.manager.api.dto.request.FindFileUrlDto;
|
||||
import cn.axzo.oss.manager.api.dto.request.MultipartUploadCompleteDto;
|
||||
import cn.axzo.oss.manager.api.dto.request.MultipartUploadDto;
|
||||
import cn.axzo.oss.manager.api.dto.request.MultipartUploadFileDto;
|
||||
import cn.axzo.oss.manager.api.dto.request.MultipartUploadInitDto;
|
||||
import cn.axzo.oss.manager.api.dto.request.ServerFileDeleteDto;
|
||||
import cn.axzo.oss.manager.api.dto.request.ServerFileDownloadDto;
|
||||
import cn.axzo.oss.manager.api.dto.request.ServerFileUploadDto;
|
||||
import cn.axzo.oss.manager.api.dto.request.SignUrlDownloadDto;
|
||||
import cn.axzo.oss.manager.api.dto.request.SignUrlUploadDto;
|
||||
import cn.axzo.oss.manager.api.dto.response.FileInformationResponse;
|
||||
import cn.axzo.oss.manager.api.dto.response.FindFileKeyResponse;
|
||||
import cn.axzo.oss.manager.api.dto.response.FindFileUrlResponse;
|
||||
import cn.axzo.oss.manager.api.dto.response.MultipartUploadInitResponse;
|
||||
import cn.axzo.oss.manager.api.dto.response.MultipartUploadResponse;
|
||||
import cn.axzo.oss.manager.api.dto.response.ServerFileDownloadResponse;
|
||||
import cn.axzo.oss.manager.api.dto.response.ServerFileUploadResponse;
|
||||
import cn.axzo.oss.manager.api.dto.response.SignUrlDownloadResponse;
|
||||
import cn.axzo.oss.manager.api.dto.response.SignUrlUploadResponse;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author admin
|
||||
* @Description
|
||||
* @Date 2021/7/28 22:48
|
||||
* @Version 0.0.1
|
||||
**/
|
||||
public interface FileByUrlService {
|
||||
|
||||
/**
|
||||
* 上传-通过url
|
||||
*/
|
||||
ServerFileUploadResponse uploadByUrl(String appCode, String bizScene, String fileName, String url,Integer channelType, String style, ContextInfo.LiteSaasContext liteSaasContext);
|
||||
}
|
||||
@ -26,6 +26,12 @@
|
||||
<groupId>com.huaweicloud</groupId>
|
||||
<artifactId>esdk-obs-java-bundle</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.axzo.framework.logging</groupId>
|
||||
<artifactId>axzo-common-trace</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
||||
@ -0,0 +1,349 @@
|
||||
package cn.axzo.oss.service.impl;
|
||||
|
||||
import cn.axzo.framework.auth.domain.ContextInfo;
|
||||
import cn.axzo.log.platform.client.LogPlatClient;
|
||||
import cn.axzo.log.platform.client.model.OperateLogReq;
|
||||
import cn.axzo.oss.common.constans.CommonConstants;
|
||||
import cn.axzo.oss.common.constans.CommonConstants.FileStatus;
|
||||
import cn.axzo.oss.common.constans.CommonConstants.TableDelete;
|
||||
import cn.axzo.oss.common.enums.BucketTypeEnum;
|
||||
import cn.axzo.oss.common.enums.ChannelTypeEnum;
|
||||
import cn.axzo.oss.common.enums.CodeEnum;
|
||||
import cn.axzo.oss.common.enums.FileClassEnum;
|
||||
import cn.axzo.oss.common.enums.FileDownloadTypeEnum;
|
||||
import cn.axzo.oss.common.enums.FileStatusEnum;
|
||||
import cn.axzo.oss.common.enums.FileUploadTypeEnum;
|
||||
import cn.axzo.oss.common.exception.BizException;
|
||||
import cn.axzo.oss.common.utils.JsonUtil;
|
||||
import cn.axzo.oss.common.utils.UrlUtil;
|
||||
import cn.axzo.oss.common.utils.Utility;
|
||||
import cn.axzo.oss.dal.entity.AppChannelBucket;
|
||||
import cn.axzo.oss.dal.entity.File;
|
||||
import cn.axzo.oss.dal.entity.FileApp;
|
||||
import cn.axzo.oss.dal.entity.FileBusinessScene;
|
||||
import cn.axzo.oss.dal.entity.FileUploadConfig;
|
||||
import cn.axzo.oss.dal.repository.FileAppDao;
|
||||
import cn.axzo.oss.dal.repository.FileDao;
|
||||
import cn.axzo.oss.integration.s3.config.HuaWeiCloudObsConfig;
|
||||
import cn.axzo.oss.manager.api.AppChannelBucketManager;
|
||||
import cn.axzo.oss.manager.api.FileBusinessSceneManager;
|
||||
import cn.axzo.oss.manager.api.FileManager;
|
||||
import cn.axzo.oss.manager.api.FileUploadConfigManager;
|
||||
import cn.axzo.oss.manager.api.dto.PartETag;
|
||||
import cn.axzo.oss.manager.api.dto.request.DeleteFileDto;
|
||||
import cn.axzo.oss.manager.api.dto.request.FindFileKeyDto;
|
||||
import cn.axzo.oss.manager.api.dto.request.FindFileUrlDto;
|
||||
import cn.axzo.oss.manager.api.dto.request.MultipartUploadCompleteDto;
|
||||
import cn.axzo.oss.manager.api.dto.request.MultipartUploadDto;
|
||||
import cn.axzo.oss.manager.api.dto.request.MultipartUploadFileDto;
|
||||
import cn.axzo.oss.manager.api.dto.request.MultipartUploadInitDto;
|
||||
import cn.axzo.oss.manager.api.dto.request.ServerFileDeleteDto;
|
||||
import cn.axzo.oss.manager.api.dto.request.ServerFileDownloadDto;
|
||||
import cn.axzo.oss.manager.api.dto.request.ServerFileUploadDto;
|
||||
import cn.axzo.oss.manager.api.dto.request.SignUrlDownloadDto;
|
||||
import cn.axzo.oss.manager.api.dto.request.SignUrlUploadDto;
|
||||
import cn.axzo.oss.manager.api.dto.response.FileInformationResponse;
|
||||
import cn.axzo.oss.manager.api.dto.response.FindFileKeyResponse;
|
||||
import cn.axzo.oss.manager.api.dto.response.FindFileUrlResponse;
|
||||
import cn.axzo.oss.manager.api.dto.response.MultipartUploadInitResponse;
|
||||
import cn.axzo.oss.manager.api.dto.response.MultipartUploadResponse;
|
||||
import cn.axzo.oss.manager.api.dto.response.ServerFileDownloadResponse;
|
||||
import cn.axzo.oss.manager.api.dto.response.ServerFileUploadResponse;
|
||||
import cn.axzo.oss.manager.api.dto.response.SignUrlDownloadResponse;
|
||||
import cn.axzo.oss.manager.api.dto.response.SignUrlUploadResponse;
|
||||
import cn.axzo.oss.manager.api.vo.SignUrlUploadVo;
|
||||
import cn.axzo.oss.service.api.FileByUrlService;
|
||||
import cn.axzo.oss.service.api.FileService;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.axzo.oss.common.constans.CommonConstants.APP_PRO_BUCKET_NAME;
|
||||
|
||||
/**
|
||||
* @Author admin
|
||||
* @Description
|
||||
* @Date 2021/7/28 22:48
|
||||
* @Version 0.0.1
|
||||
**/
|
||||
@Service
|
||||
@RefreshScope
|
||||
@Slf4j
|
||||
public class FileByUrlServiceImpl implements FileByUrlService {
|
||||
|
||||
private static final String FILE_UPLOAD_CODE = "OSS_FILE_UPLOAD";
|
||||
private static final String FILE_UPLOAD_NAME = "文件上传";
|
||||
|
||||
@Autowired
|
||||
private FileDao fileDao;
|
||||
|
||||
@Autowired
|
||||
private FileManager fileManager;
|
||||
|
||||
@Autowired
|
||||
private FileAppDao fileAppDao;
|
||||
|
||||
@Autowired
|
||||
private AppChannelBucketManager appChannelBucketManager;
|
||||
|
||||
@Autowired
|
||||
private FileBusinessSceneManager fileBusinessSceneManager;
|
||||
|
||||
@Autowired
|
||||
private FileUploadConfigManager fileUploadConfigManager;
|
||||
|
||||
@Autowired
|
||||
private Environment environment;
|
||||
|
||||
@Autowired
|
||||
private LogPlatClient logPlatClient;
|
||||
|
||||
@Autowired
|
||||
private FileService fileService;
|
||||
|
||||
@Value("${sign.url.download.expire.second:2000}")
|
||||
private Long SIGN_URL_DOWNLOAD_EXPIRE_SECOND;
|
||||
|
||||
/**
|
||||
* 通过url上传
|
||||
*/
|
||||
@Override
|
||||
public ServerFileUploadResponse uploadByUrl(String appCode, String bizScene, String fileName, String url, Integer channelType,String style, ContextInfo.LiteSaasContext liteSaasContext) {
|
||||
log.info("uploadByUrl params,appCode:{},bizScene:{}, fileName:{},url:{},channelType:{}", appCode, bizScene, fileName, url, channelType);
|
||||
Long start = System.currentTimeMillis();
|
||||
//重新构建链接
|
||||
url = this.rebuildUrl(url, style);
|
||||
log.info("uploadByUrl-style-url:{}",url);
|
||||
File ossFile = uploadFileAndGetFile(appCode, bizScene, fileName, url, channelType);
|
||||
//操作日志记录
|
||||
operateLog(this.buildUploadParams(appCode, bizScene, fileName, url, channelType), "", FILE_UPLOAD_CODE, FILE_UPLOAD_NAME, liteSaasContext);
|
||||
ServerFileUploadResponse response = this.buildResponse(ossFile);
|
||||
log.info("uploadByUrl result,appCode:{},bizScene:{}, fileName:{},url:{},channelType:{}, response:{},times:{}"
|
||||
, appCode, bizScene, fileName, url, channelType, JsonUtil.obj2Str(response), System.currentTimeMillis() - start);
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* url:https://xxx,则直接返回
|
||||
* url:fileKey,则返回https://链接
|
||||
*/
|
||||
private String rebuildUrl(String url, String style) {
|
||||
if (StringUtils.isNotBlank(url)) {
|
||||
SignUrlDownloadDto signUrlDownloadDto = SignUrlDownloadDto.builder().fileKeys(Lists.newArrayList(url)).style(style).build();
|
||||
|
||||
List<SignUrlDownloadResponse> responseList = fileService.signUrlDownload(signUrlDownloadDto);
|
||||
if (CollectionUtil.isNotEmpty(responseList)) {
|
||||
return responseList.get(0).getSignUrl();
|
||||
}
|
||||
}
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
* 操作日志记录
|
||||
*/
|
||||
private void operateLog(String param, String serviceName, String featureCode, String featureName, ContextInfo.LiteSaasContext liteSaasContext) {
|
||||
if (liteSaasContext == null || liteSaasContext.getIdentityId() == null || liteSaasContext.getIdentityType() == null) {
|
||||
log.warn("获取用户上下文信息失败");
|
||||
return;
|
||||
}
|
||||
//记录日志
|
||||
try {
|
||||
OperateLogReq log = OperateLogReq.builder()
|
||||
.serviceName(StringUtils.isNotEmpty(serviceName) ? serviceName : environment.getProperty("spring.application.name"))
|
||||
.featureCode(featureCode)
|
||||
.featureName(featureName)
|
||||
.operateTime(new Date())
|
||||
.identityId(liteSaasContext.getIdentityId())
|
||||
.identityType(liteSaasContext.getIdentityType())
|
||||
.operateParam(param)
|
||||
.workspaceId(liteSaasContext.getWorkspaceId())
|
||||
.operateType(1)
|
||||
.build();
|
||||
logPlatClient.createOperateLog(log);
|
||||
} catch (Exception e) {
|
||||
log.warn("服务间调用异常-发送日志失败: errMsg={}.", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传并获取文件
|
||||
*/
|
||||
private File uploadFileAndGetFile(String appCode, String bizScene, String fileName, String url, Integer channelType) {
|
||||
log.info("update channelType:{}, fileName:{}, appCode:{}, bizScene:{}",
|
||||
channelType, fileName, appCode, bizScene);
|
||||
|
||||
// 检查appCode
|
||||
checkAppCode(appCode);
|
||||
|
||||
// 通过appcode获取文件渠道桶信息
|
||||
AppChannelBucket appChannelBucket = appChannelBucketManager.getByAppCode(appCode, channelType);
|
||||
|
||||
// 通过渠道桶编码获取到具体文件业务场景
|
||||
FileBusinessScene scene = fileBusinessSceneManager
|
||||
.getByBucketNoAndScene(appChannelBucket.getAppChannelBucketNo(), bizScene);
|
||||
|
||||
// 通过渠道码和桶名称获取获取指定上传配置
|
||||
FileUploadConfig fileUploadConfig = fileUploadConfigManager
|
||||
.getByUploadConfig(scene.getAppChannelBucketNo(), scene.getDirectory());
|
||||
|
||||
// 上传文件并生成file对象
|
||||
return generateFile(fileUploadConfig, fileName,url, fileUploadConfig.getChannelCode(), appChannelBucket.getBucketType(), scene.getDownloadExpiration());
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查appCode是否有效
|
||||
*
|
||||
* @param appCode
|
||||
*/
|
||||
private void checkAppCode(final String appCode) {
|
||||
log.info("checkAppCode appCode = {}", appCode);
|
||||
FileApp fileApp = fileAppDao.getByAppCode(appCode);
|
||||
BizException.error(Utility.objIsNotNull(fileApp), CodeEnum.FILE_APP_IS_EMPTY);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生产File对象
|
||||
*/
|
||||
private File generateFile(FileUploadConfig fileUploadConfig, String fileName, String url, String channelCode, String bucketType, Long expire) {
|
||||
// 判断容量
|
||||
String fileConform = isFileConform(fileUploadConfig, fileName);
|
||||
String uuid = Utility.getUUID();
|
||||
// 生成上传文件的唯一key
|
||||
String tgtFileKey = Utility.generateFileKey(fileUploadConfig.getDirectory(), uuid, fileConform);
|
||||
// 上传文件
|
||||
String fileUrl = fileManager.uploadByUrl(fileUploadConfig.getBucketName(), tgtFileKey, fileName, url, channelCode);
|
||||
//重新构建fileUrl
|
||||
fileUrl = rebuildFileUrl(fileUploadConfig, fileName, channelCode, bucketType, expire, tgtFileKey, fileUrl);
|
||||
|
||||
File file = rebuildOssFile(fileUploadConfig, fileName, fileConform, uuid, fileUrl, Utility.getMd5(url));
|
||||
fileDao.save(file);
|
||||
return file;
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新构建fileUrl
|
||||
*/
|
||||
private String rebuildFileUrl(FileUploadConfig fileUploadConfig, String fileName, String channelCode, String bucketType, Long expire, String tgtFileKey, String fileUrl) {
|
||||
switch (BucketTypeEnum.getByCode(bucketType)) {
|
||||
case PUBLIC_BUCKET:
|
||||
fileUrl = this.fileManager.fetchDownloadUrl(fileUploadConfig.getBucketName(), tgtFileKey, channelCode);
|
||||
break;
|
||||
case PRIVATE_BUCKET:
|
||||
fileUrl = this.fileManager.signUrlDownload(fileUploadConfig.getBucketName(), tgtFileKey, Objects.nonNull(expire) ? expire : SIGN_URL_DOWNLOAD_EXPIRE_SECOND , channelCode, fileName, null,false);
|
||||
break;
|
||||
default:
|
||||
BizException.error(CodeEnum.CHANNEL_TYPE_NOT_EXIST);
|
||||
}
|
||||
|
||||
// 保存失败
|
||||
if (Utility.isBlank(fileUrl)) {
|
||||
log.error("fileUrl is empty");
|
||||
throw new BizException(CodeEnum.FILE_UPLOAD_FAILED);
|
||||
}
|
||||
return fileUrl;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param fileUploadConfig
|
||||
* @param fileName
|
||||
* @param fileConform
|
||||
* @param uuid
|
||||
* @param fileUrl
|
||||
* @param fileMd5
|
||||
* @return
|
||||
*/
|
||||
private File rebuildOssFile(FileUploadConfig fileUploadConfig, String fileName, String fileConform, String uuid,
|
||||
String fileUrl, String fileMd5) {
|
||||
File ossFile = new File();
|
||||
ossFile.setAppChannelBucketNo(fileUploadConfig.getAppChannelBucketNo());
|
||||
ossFile.setAppCode(fileUploadConfig.getAppCode());
|
||||
ossFile.setChannelCode(fileUploadConfig.getChannelCode());
|
||||
ossFile.setBucketName(fileUploadConfig.getBucketName());
|
||||
ossFile.setDirectory(fileUploadConfig.getDirectory());
|
||||
ossFile.setStatus(FileStatusEnum.STATUS_UPLOAD_FAIL.getCode());
|
||||
ossFile.setStorageUnit(fileUploadConfig.getStorageUnit());
|
||||
ossFile.setStorageSize(fileUploadConfig.getStorageSize());
|
||||
ossFile.setFileFormat(fileConform);
|
||||
ossFile.setFileUuid(uuid);
|
||||
ossFile.setFileUrl(fileUrl);
|
||||
ossFile.setUrlMd5(Utility.getMd5(fileUrl));
|
||||
ossFile.setStatus(FileStatusEnum.STATUS_UPLOAD_SUCCESS.getCode());
|
||||
ossFile.setFileName(fileName);
|
||||
ossFile.setFileMd5(fileMd5);
|
||||
return ossFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断文件是否符合要求
|
||||
*/
|
||||
private String isFileConform(FileUploadConfig fileUploadConfig, String fileName) {
|
||||
// 文件格式判断
|
||||
String[] formats = fileUploadConfig.getFileFormat().split(FileClassEnum.COMMA.type);
|
||||
|
||||
int lastIndexOf = fileName.lastIndexOf(FileClassEnum.DOT.type);
|
||||
BizException
|
||||
.error(lastIndexOf != CommonConstants.NOT_FOUND_INDEX_OF, CodeEnum.NOT_FILE_FORMAT);
|
||||
|
||||
// 是否包含指定格式
|
||||
String fileFormat = fileName.substring(lastIndexOf + CommonConstants.ONE).toLowerCase();
|
||||
boolean contains = Arrays.asList(formats).contains(fileFormat);
|
||||
BizException.error(contains, CodeEnum.FILE_FORMAT_NOT_SUPPORTED);
|
||||
|
||||
return fileFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建操作日志入参
|
||||
*/
|
||||
private String buildUploadParams(String appCode, String bizScene, String fileName, String url,Integer channelType) {
|
||||
StringBuilder builder = new StringBuilder("appCode:");
|
||||
builder.append(appCode).append(";");
|
||||
builder.append("bizScene").append(":");
|
||||
builder.append(bizScene).append(";");
|
||||
builder.append("fileName").append(":");
|
||||
builder.append(fileName).append(";");
|
||||
builder.append("url").append(":");
|
||||
builder.append(url).append(";");
|
||||
builder.append("channelType").append("");
|
||||
builder.append(channelType).append(";");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建返回对象
|
||||
*/
|
||||
private ServerFileUploadResponse buildResponse(File ossFile) {
|
||||
ServerFileUploadResponse response = new ServerFileUploadResponse();
|
||||
response.setUrl(ossFile.getFileUrl());
|
||||
response.setUrlMd5(ossFile.getUrlMd5());
|
||||
response.setFileKey(ossFile.getFileUuid());
|
||||
return response;
|
||||
}
|
||||
}
|
||||
@ -502,7 +502,7 @@ public class FileServiceImpl implements FileService {
|
||||
response.setFileKey(fileKey);
|
||||
if (Objects.nonNull(bucketTypeMap.get(file.getAppChannelBucketNo())) && BucketTypeEnum.PRIVATE_BUCKET.getCode().equals(bucketTypeMap.get(file.getAppChannelBucketNo()))) {
|
||||
String tgtFileKey = Utility.generateFileKey(file.getDirectory(), file.getFileUuid(), file.getFileFormat());
|
||||
response.setUrl(fileManager.signUrlDownload(file.getBucketName(), tgtFileKey, SIGN_URL_DOWNLOAD_EXPIRE_SECOND, file.getChannelCode(), file.getFileName()));
|
||||
response.setUrl(fileManager.signUrlDownload(file.getBucketName(), tgtFileKey, SIGN_URL_DOWNLOAD_EXPIRE_SECOND, file.getChannelCode(), file.getFileName(), null, false));
|
||||
} else {
|
||||
response.setUrl(fileUrl);
|
||||
}
|
||||
@ -833,6 +833,8 @@ public class FileServiceImpl implements FileService {
|
||||
public List<SignUrlDownloadResponse> signUrlDownload(SignUrlDownloadDto dto) {
|
||||
log.info("signUrl download dto = {}", JsonUtil.obj2Str(dto));
|
||||
Long start = System.currentTimeMillis();
|
||||
//是否代文件名称
|
||||
dto.setHasFileName(Objects.isNull(dto.getHasFileName()) ? true : dto.getHasFileName());
|
||||
|
||||
if (CollectionUtil.isEmpty(dto.getFileKeys())) {
|
||||
return Lists.newArrayList();
|
||||
@ -846,7 +848,7 @@ public class FileServiceImpl implements FileService {
|
||||
List<SignUrlDownloadResponse> httpUrlSignResList = this.buildHttpUrlSignResponse(dto);
|
||||
|
||||
//3 构建fileKey入参对象集合
|
||||
List<SignUrlDownloadResponse> fileKeyResList = this.buildFileKeyResponse(dto.getFileKeys(), dto.getBizScene());
|
||||
List<SignUrlDownloadResponse> fileKeyResList = this.buildFileKeyResponse(dto.getFileKeys(), dto.getBizScene(), dto.getStyle(), dto.getHasFileName());
|
||||
//4 1/2/3集合累加
|
||||
httpUrlResList.addAll(fileKeyResList);
|
||||
httpUrlResList.addAll(httpUrlSignResList);
|
||||
@ -857,7 +859,7 @@ public class FileServiceImpl implements FileService {
|
||||
/**
|
||||
* 构建fileKey(非http的入参)的返回对象
|
||||
*/
|
||||
private List<SignUrlDownloadResponse> buildFileKeyResponse(List<String> fileKeys, String bizScene) {
|
||||
private List<SignUrlDownloadResponse> buildFileKeyResponse(List<String> fileKeys, String bizScene, String style, boolean hasFileName) {
|
||||
if (CollectionUtil.isEmpty(fileKeys)) {
|
||||
return Lists.newArrayList();
|
||||
}
|
||||
@ -878,13 +880,13 @@ public class FileServiceImpl implements FileService {
|
||||
List<FileBusinessScene> fileBusinessSceneList = fileBusinessSceneManager.queryByBucketNoAndScene(fileList.stream().map(File::getAppChannelBucketNo).collect(Collectors.toSet()), bizScene);
|
||||
Map<String, Long> bizSceneExpireMap = fileBusinessSceneList.stream().collect(Collectors.toMap(FileBusinessScene::getAppChannelBucketNo, FileBusinessScene::getDownloadExpiration, (x, y) -> y));
|
||||
//构建返回集合
|
||||
return this.buildFileKeyRespByFile(fileList, bucketTypeMap, bizSceneExpireMap);
|
||||
return this.buildFileKeyRespByFile(fileList, bucketTypeMap, bizSceneExpireMap, style, hasFileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过File对象,构建返回集合
|
||||
*/
|
||||
private List<SignUrlDownloadResponse> buildFileKeyRespByFile(List<File> fileList,Map<String, String> bucketTypeMap, Map<String, Long> bizSceneExpireMap) {
|
||||
private List<SignUrlDownloadResponse> buildFileKeyRespByFile(List<File> fileList,Map<String, String> bucketTypeMap, Map<String, Long> bizSceneExpireMap, String style, boolean hasFileName) {
|
||||
List<SignUrlDownloadResponse> responseList = fileList.stream().map(item -> {
|
||||
Long expire = bizSceneExpireMap.get(item.getAppChannelBucketNo());
|
||||
// bucket下的key
|
||||
@ -894,12 +896,12 @@ public class FileServiceImpl implements FileService {
|
||||
case PUBLIC_BUCKET://公有桶 - 永久链接,例如 http://xxx.png
|
||||
String url = this.fileManager.fetchDownloadUrl(item.getBucketName(), tgtFileKey, item.getChannelCode());
|
||||
return SignUrlDownloadResponse.builder()
|
||||
.signUrl(url)
|
||||
.signUrl(this.buildPublicXImageProcess(url, style))
|
||||
.fileKey(item.getFileUuid())
|
||||
.fileName(item.getFileName())
|
||||
.build();
|
||||
case PRIVATE_BUCKET://私有桶 - 临时授权链接 例如 http://xxx.png?Expire=a&AccessKeyId=b&Signature=c&repsonse-content-disposition=d
|
||||
String signUrl = this.fileManager.signUrlDownload(item.getBucketName(), tgtFileKey, Objects.nonNull(expire) ? expire : SIGN_URL_DOWNLOAD_EXPIRE_SECOND , item.getChannelCode(), item.getFileName());
|
||||
String signUrl = this.fileManager.signUrlDownload(item.getBucketName(), tgtFileKey, Objects.nonNull(expire) ? expire : SIGN_URL_DOWNLOAD_EXPIRE_SECOND , item.getChannelCode(), item.getFileName(), style, hasFileName);
|
||||
return SignUrlDownloadResponse.builder()
|
||||
.signUrl(UrlUtil.httpToHttps(signUrl))
|
||||
.fileKey(item.getFileUuid())
|
||||
@ -925,11 +927,27 @@ public class FileServiceImpl implements FileService {
|
||||
return Lists.newArrayList();
|
||||
}
|
||||
return httpUrlList.stream().map(item -> SignUrlDownloadResponse.builder()
|
||||
.signUrl(item)
|
||||
.signUrl(this.buildPublicXImageProcess(item, dto.getStyle()))
|
||||
.fileKey(item)
|
||||
.build()).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建公开Style
|
||||
*/
|
||||
private String buildPublicXImageProcess(String url, String style) {
|
||||
if (StringUtils.isBlank(style)) {
|
||||
return url;
|
||||
}
|
||||
if (url.toLowerCase().contains(UrlUtil.ALIYUN) && !url.toLowerCase().contains(UrlUtil.X_OSS_PROCESS)) {
|
||||
return url + UrlUtil.X_OSS_PROCESS_APPEND + style;
|
||||
}
|
||||
if (url.toLowerCase().contains(UrlUtil.HUAWEICLOUD) && !url.toLowerCase().contains(UrlUtil.X_IMAGE_PROCESS)) {
|
||||
return url + UrlUtil.X_IMAGE_PROCESS_APPEND + style;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建http链接(非fileKey入参)返回对象
|
||||
*/
|
||||
@ -945,7 +963,7 @@ public class FileServiceImpl implements FileService {
|
||||
if (CollectionUtil.isEmpty(map)) {
|
||||
return httpUrlList.stream().map(item -> SignUrlDownloadResponse.builder().fileKey(item).signUrl(item).build()).collect(Collectors.toList());
|
||||
}
|
||||
List<SignUrlDownloadResponse> responseList = this.buildFileKeyResponse(Lists.newArrayList(map.values()), null);
|
||||
List<SignUrlDownloadResponse> responseList = this.buildFileKeyResponse(Lists.newArrayList(map.values()), null, dto.getStyle(), dto.getHasFileName());
|
||||
if (CollectionUtil.isEmpty(responseList)) {
|
||||
return httpUrlList.stream().map(item -> SignUrlDownloadResponse.builder().fileKey(item).signUrl(item).build()).collect(Collectors.toList());
|
||||
}
|
||||
@ -1072,7 +1090,9 @@ public class FileServiceImpl implements FileService {
|
||||
Long expiration = this.buildExpiration(dto, scene);
|
||||
//1 调用阿里云/华为云 获取临时授权signUrl
|
||||
SignUrlUploadVo signUrlUpload = this.fileManager.signUrlUpload(fileUploadConfig.getBucketName(), tgtFileKey, dto.getFileName(),expiration
|
||||
, fileUploadConfig.getChannelCode(), StringUtils.isNotBlank(dto.getContentType()) ? dto.getContentType() : "multipart/form-data", appChannelBucket.getBucketType());
|
||||
, fileUploadConfig.getChannelCode()
|
||||
, StringUtils.isNotBlank(dto.getContentType()) ? dto.getContentType() : "multipart/form-data", appChannelBucket.getBucketType()
|
||||
, Objects.isNull(dto.getHasFileName()) ? true: dto.getHasFileName() );
|
||||
//2 保存File对象
|
||||
this.saveOssFile(fileUploadConfig, dto.getFileName(), fileFormat, uuid,
|
||||
signUrlUpload.getDownloadSignUrl(), Utility.getMd5(signUrlUpload.getDownloadSignUrl()), expiration);
|
||||
@ -1083,6 +1103,7 @@ public class FileServiceImpl implements FileService {
|
||||
.host(signUrlUpload.getHost())
|
||||
.channelCode(signUrlUpload.getChannelCode())
|
||||
.downloadSignUrl(UrlUtil.httpToHttps(signUrlUpload.getDownloadSignUrl()))
|
||||
.fileName(dto.getFileName())
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user