add-增加manager,优化方法

This commit is contained in:
zhangran 2021-08-03 17:31:31 +08:00
parent 2b3b6f85bd
commit 2451b8c2b3
13 changed files with 345 additions and 70 deletions

View File

@ -31,6 +31,7 @@ public class ServerFileController implements ServerFileServiceApi {
@Override @Override
public CommonResponse<ServerFileUploadResponse> upload(@Valid @RequestBody ServerFileUploadRequest request) { public CommonResponse<ServerFileUploadResponse> upload(@Valid @RequestBody ServerFileUploadRequest request) {
ServerFileUploadDto dto = BeanConvertUtil.copyBean(request, ServerFileUploadDto.class); ServerFileUploadDto dto = BeanConvertUtil.copyBean(request, ServerFileUploadDto.class);
request.setFileContent(null);
return CommonResponse.success(fileService.upload(dto)); return CommonResponse.success(fileService.upload(dto));
} }

View File

@ -19,6 +19,22 @@ public abstract class CommonConstants {
*/ */
public static final String DOT = "."; public static final String DOT = ".";
/**
* 逗号
*/
public static final String COMMA = ",";
/**
* 在指定字符串未找字符串的位置
*/
public static final int NOT_FOUND_INDEX_OF = -1;
/**
* 1
*/
public static final int ONE = 1;
/** /**
* 是否删除 * 是否删除
*/ */

View File

@ -3,6 +3,8 @@ package cn.axzo.oss.common.exception;
import cn.axzo.oss.common.enums.CodeEnum; import cn.axzo.oss.common.enums.CodeEnum;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.springframework.lang.Nullable;
import org.springframework.util.ObjectUtils;
/** /**
* 业务异常 * 业务异常
@ -60,25 +62,25 @@ public class BizException extends RuntimeException {
} }
public static void error(boolean b, CodeEnum returnCode) { public static void error(boolean b, CodeEnum returnCode) {
if (!b) { if (b) {
throw new BizException(returnCode.getCode(), returnCode.getMessage(), null); throw new BizException(returnCode.getCode(), returnCode.getMessage(), null);
} }
} }
public static void error(boolean b, CodeEnum returnCode, String message) { public static void error(boolean b, CodeEnum returnCode, String message) {
if (!b) { if (b) {
throw new BizException(returnCode.getCode(), message, null); throw new BizException(returnCode.getCode(), message, null);
} }
} }
public static void error(boolean b, Integer code, String message) { public static void error(boolean b, Integer code, String message) {
if (!b) { if (b) {
throw new BizException(code, message, null); throw new BizException(code, message, null);
} }
} }
public static void error(boolean b, Integer code, String message, Object data) { public static void error(boolean b, Integer code, String message, Object data) {
if (!b) { if (b) {
throw new BizException(code, message, data); throw new BizException(code, message, data);
} }
} }
@ -87,4 +89,9 @@ public class BizException extends RuntimeException {
throw new BizException(returnCode.getCode(), returnCode.getMessage(), null); throw new BizException(returnCode.getCode(), returnCode.getMessage(), null);
} }
public static void isEmpty(@Nullable Object obj, CodeEnum returnCode) {
if (ObjectUtils.isEmpty(obj)) {
throw new BizException(returnCode.getCode(), returnCode.getMessage(), null);
}
}
} }

View File

@ -0,0 +1,20 @@
package cn.axzo.oss.manager.api;
import cn.axzo.oss.dal.entity.AppChannelBucket;
import java.util.List;
/**
* @author: zhangran
* @date: 20210803 15:30
* @description:
**/
public interface AppChannelBucketManager {
/**
* 通过appcode获取文件渠道桶信息
*
* @param appCode appcode
* @return
*/
List<AppChannelBucket> getByAppCode(String appCode);
}

View File

@ -0,0 +1,21 @@
package cn.axzo.oss.manager.api;
import cn.axzo.oss.dal.entity.FileApp;
/**
* @author: zhangran
* @date: 20210803 15:28
* @description:
**/
public interface FileAppManager {
/**
* 通过appCode获取应用信息
*
* @param appCode
* @return
*/
FileApp getByAppCode(String appCode);
}

View File

@ -0,0 +1,20 @@
package cn.axzo.oss.manager.api;
import cn.axzo.oss.dal.entity.FileBusinessScene;
/**
* @author: zhangran
* @date: 20210803 15:42
* @description:
**/
public interface FileBusinessSceneManager {
/**
* 指定appcode文件业务场景
*
* @param bucketNo 应用编码
* @param bizScene
* @return
*/
FileBusinessScene getByBucketNoAndScene(String bucketNo,String bizScene);
}

View File

@ -0,0 +1,28 @@
package cn.axzo.oss.manager.api;
import cn.axzo.oss.dal.entity.FileChannel;
import java.util.List;
/**
* @author: zhangran
* @date: 20210803 15:33
* @description:
**/
public interface FileChannelManager {
/**
* 返回所有渠道 按优先级升序返回
*
* @param channelCodes
* @return
*/
List<FileChannel> listChannelCodeOrderByPriorityAsc(List<String> channelCodes);
/**
* 返回一个最优的渠道 升序第一个
*
* @param channelCodes
* @return
*/
FileChannel getOptimalChannel(List<String> channelCodes);
}

View File

@ -0,0 +1,20 @@
package cn.axzo.oss.manager.api;
import cn.axzo.oss.dal.entity.FileUploadConfig;
/**
* @author: zhangran
* @date: 20210803 15:43
* @description:
**/
public interface FileUploadConfigManager {
/**
* 通过渠道码和桶名称获取获取指定上传配置
*
* @param bucketNo
* @param directory
* @return
*/
FileUploadConfig getByUploadConfig(String bucketNo, String directory);
}

View File

@ -0,0 +1,37 @@
package cn.axzo.oss.manager.impl;
import cn.axzo.oss.common.enums.CodeEnum;
import cn.axzo.oss.common.exception.BizException;
import cn.axzo.oss.dal.entity.AppChannelBucket;
import cn.axzo.oss.dal.repository.AppChannelBucketDao;
import cn.axzo.oss.manager.api.AppChannelBucketManager;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author: zhangran
* @date: 20210803 15:44
* @description:
**/
@Service
@Slf4j
public class AppChannelBucketManagerImpl implements AppChannelBucketManager {
@Autowired
private AppChannelBucketDao appChannelBucketDao;
/**
* 通过appcode获取文件渠道桶信息
*
* @param appCode appcode
* @return
*/
@Override
public List<AppChannelBucket> getByAppCode(String appCode) {
List<AppChannelBucket> appChannelBuckets = appChannelBucketDao.getByAppCode(appCode);
BizException.isEmpty(appChannelBuckets, CodeEnum.APP_CHANNEL_BUCKET_NOT_FOUND);
return appChannelBuckets;
}
}

View File

@ -0,0 +1,38 @@
package cn.axzo.oss.manager.impl;
import cn.axzo.oss.common.enums.CodeEnum;
import cn.axzo.oss.common.exception.BizException;
import cn.axzo.oss.dal.entity.FileBusinessScene;
import cn.axzo.oss.dal.repository.FileBusinessSceneDao;
import cn.axzo.oss.manager.api.FileBusinessSceneManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author: zhangran
* @date: 20210803 16:36
* @description:
**/
@Service
@Slf4j
public class FileBusinessSceneManagerImpl implements FileBusinessSceneManager {
@Autowired
private FileBusinessSceneDao fileBusinessSceneDao;
/**
* 指定appcode文件业务场景
*
* @param bucketNo 应用编码
* @param bizScene
* @return
*/
@Override
public FileBusinessScene getByBucketNoAndScene(String bucketNo, String bizScene) {
FileBusinessScene fileBusinessScene = fileBusinessSceneDao
.getByBucketNoAndScene(bucketNo, bizScene);
BizException.isEmpty(fileBusinessScene, CodeEnum.APP_CHANNEL_NOT_FOUND);
return fileBusinessScene;
}
}

View File

@ -0,0 +1,50 @@
package cn.axzo.oss.manager.impl;
import cn.axzo.oss.common.enums.CodeEnum;
import cn.axzo.oss.common.exception.BizException;
import cn.axzo.oss.dal.entity.FileChannel;
import cn.axzo.oss.dal.repository.FileChannelDao;
import cn.axzo.oss.manager.api.FileChannelManager;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author: zhangran
* @date: 20210803 16:28
* @description:
**/
@Service
@Slf4j
public class FileChannelManagerImpl implements FileChannelManager {
@Autowired
private FileChannelDao fileChannelDao;
/**
* 返回所有渠道 按优先级升序返回
*
* @param channelCodes
* @return
*/
@Override
public List<FileChannel> listChannelCodeOrderByPriorityAsc(List<String> channelCodes) {
List<FileChannel> fileChannels = fileChannelDao.getByChannelCode(channelCodes);
BizException.isEmpty(fileChannels, CodeEnum.APP_CHANNEL_NOT_FOUND);
return fileChannels;
}
/**
* 返回一个最优的渠道 升序第一个
*
* @param channelCodes
* @return
*/
@Override
public FileChannel getOptimalChannel(List<String> channelCodes) {
List<FileChannel> fileChannels = fileChannelDao.getByChannelCode(channelCodes);
BizException.isEmpty(fileChannels, CodeEnum.APP_CHANNEL_NOT_FOUND);
return fileChannels.get(0);
}
}

View File

@ -0,0 +1,37 @@
package cn.axzo.oss.manager.impl;
import cn.axzo.oss.common.enums.CodeEnum;
import cn.axzo.oss.common.exception.BizException;
import cn.axzo.oss.dal.entity.FileUploadConfig;
import cn.axzo.oss.dal.repository.FileUploadConfigDao;
import cn.axzo.oss.manager.api.FileUploadConfigManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author: zhangran
* @date: 20210803 16:39
* @description:
**/
@Service
@Slf4j
public class FileUploadConfigManagerImpl implements FileUploadConfigManager {
@Autowired
private FileUploadConfigDao fileUploadConfigDao;
/**
* 通过渠道码和桶名称获取获取指定上传配置
*
* @param bucketNo
* @param directory
* @return
*/
@Override
public FileUploadConfig getByUploadConfig(String bucketNo, String directory) {
FileUploadConfig uploadConfig = fileUploadConfigDao.getByUploadConfig(bucketNo, directory);
BizException.isEmpty(uploadConfig, CodeEnum.NO_UPLOAD_CONFIG);
return uploadConfig;
}
}

View File

@ -1,5 +1,6 @@
package cn.axzo.oss.service.impl; package cn.axzo.oss.service.impl;
import cn.axzo.oss.common.constans.CommonConstants;
import cn.axzo.oss.common.constans.CommonConstants.FileStatus; import cn.axzo.oss.common.constans.CommonConstants.FileStatus;
import cn.axzo.oss.common.constans.CommonConstants.TableDelete; import cn.axzo.oss.common.constans.CommonConstants.TableDelete;
import cn.axzo.oss.common.enums.CodeEnum; import cn.axzo.oss.common.enums.CodeEnum;
@ -13,13 +14,13 @@ import cn.axzo.oss.dal.entity.FileApp;
import cn.axzo.oss.dal.entity.FileBusinessScene; import cn.axzo.oss.dal.entity.FileBusinessScene;
import cn.axzo.oss.dal.entity.FileChannel; import cn.axzo.oss.dal.entity.FileChannel;
import cn.axzo.oss.dal.entity.FileUploadConfig; import cn.axzo.oss.dal.entity.FileUploadConfig;
import cn.axzo.oss.dal.repository.AppChannelBucketDao;
import cn.axzo.oss.dal.repository.FileAppDao; import cn.axzo.oss.dal.repository.FileAppDao;
import cn.axzo.oss.dal.repository.FileBusinessSceneDao;
import cn.axzo.oss.dal.repository.FileChannelDao;
import cn.axzo.oss.dal.repository.FileDao; import cn.axzo.oss.dal.repository.FileDao;
import cn.axzo.oss.dal.repository.FileUploadConfigDao; import cn.axzo.oss.manager.api.AppChannelBucketManager;
import cn.axzo.oss.manager.api.FileBusinessSceneManager;
import cn.axzo.oss.manager.api.FileChannelManager;
import cn.axzo.oss.manager.api.FileManager; import cn.axzo.oss.manager.api.FileManager;
import cn.axzo.oss.manager.api.FileUploadConfigManager;
import cn.axzo.oss.manager.api.dto.request.ServerFileDeleteDto; import cn.axzo.oss.manager.api.dto.request.ServerFileDeleteDto;
import cn.axzo.oss.manager.api.dto.request.ServerFileUploadDto; import cn.axzo.oss.manager.api.dto.request.ServerFileUploadDto;
import cn.axzo.oss.manager.api.dto.response.ServerFileUploadResponse; import cn.axzo.oss.manager.api.dto.response.ServerFileUploadResponse;
@ -31,7 +32,6 @@ import java.util.List;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
/** /**
* @Author admin * @Author admin
@ -52,13 +52,13 @@ public class FileServiceImpl implements FileService {
@Autowired @Autowired
private FileAppDao fileAppDao; private FileAppDao fileAppDao;
@Autowired @Autowired
private AppChannelBucketDao appChannelBucketDao; private AppChannelBucketManager appChannelBucketManager;
@Autowired @Autowired
private FileChannelDao fileChannelDao; private FileChannelManager fileChannelManager;
@Autowired @Autowired
private FileBusinessSceneDao fileBusinessSceneDao; private FileBusinessSceneManager fileBusinessSceneManager;
@Autowired @Autowired
private FileUploadConfigDao fileUploadConfigDao; private FileUploadConfigManager fileUploadConfigManager;
/** /**
@ -80,7 +80,8 @@ public class FileServiceImpl implements FileService {
log.warn("delete file is null,url = {}, urlMd5 = {}", dto.getUrl(), urlMd5); log.warn("delete file is null,url = {}, urlMd5 = {}", dto.getUrl(), urlMd5);
return; return;
} }
String tgtFileKey = Utility.generateFileKey(file.getDirectory(), file.getFileUuid(), file.getFileFormat()); String tgtFileKey = Utility
.generateFileKey(file.getDirectory(), file.getFileUuid(), file.getFileFormat());
log.debug("delete tgtFileKey = {}", tgtFileKey); log.debug("delete tgtFileKey = {}", tgtFileKey);
boolean deleteFlag = fileManager.delete(file.getBucketName(), tgtFileKey); boolean deleteFlag = fileManager.delete(file.getBucketName(), tgtFileKey);
log.info("delete deleteFlag = {}", deleteFlag); log.info("delete deleteFlag = {}", deleteFlag);
@ -97,9 +98,10 @@ public class FileServiceImpl implements FileService {
/** /**
* 检查appCode是否有效 * 检查appCode是否有效
*
* @param appCode * @param appCode
*/ */
private void checkAppCode(final String appCode){ private void checkAppCode(final String appCode) {
log.info("checkAppCode appCode = {}", appCode); log.info("checkAppCode appCode = {}", appCode);
FileApp fileApp = fileAppDao.getByAppCode(appCode); FileApp fileApp = fileAppDao.getByAppCode(appCode);
BizException.error(Utility.objIsNull(fileApp), CodeEnum.APP_CODE_NOT_FOUND); BizException.error(Utility.objIsNull(fileApp), CodeEnum.APP_CODE_NOT_FOUND);
@ -117,74 +119,33 @@ public class FileServiceImpl implements FileService {
// 检查appCode // 检查appCode
checkAppCode(dto.getAppCode()); checkAppCode(dto.getAppCode());
List<AppChannelBucket> appChannelBuckets = appChannelBucketDao // 通过appcode获取文件渠道桶信息
List<AppChannelBucket> appChannelBuckets = appChannelBucketManager
.getByAppCode(dto.getAppCode()); .getByAppCode(dto.getAppCode());
if (ObjectUtils.isEmpty(appChannelBuckets)) {
log.error("upload 文件渠道桶信息不存在 appCode:{}", dto.getAppCode());
throw new BizException(CodeEnum.APP_CHANNEL_BUCKET_NOT_FOUND);
}
// todo 判断权限 // 暂无权限判断
// 找到最优渠道 // 找到最优渠道
ArrayList<String> channels = Lists.newArrayList(); ArrayList<String> channels = Lists.newArrayList();
appChannelBuckets.forEach(appChannelBucket -> channels.add(appChannelBucket.getChannelCode())); appChannelBuckets.forEach(appChannelBucket -> channels.add(appChannelBucket.getChannelCode()));
FileChannel fileChannel = fileChannelManager.getOptimalChannel(channels);
List<FileChannel> fileChannels = fileChannelDao.getByChannelCode(channels);
if (ObjectUtils.isEmpty(fileChannels)) {
log.error("upload 最优渠道为空 channels:{}", channels);
throw new BizException(CodeEnum.APP_CHANNEL_NOT_FOUND);
}
FileChannel fileChannel = fileChannels.get(0);
AppChannelBucket appChannelBucket = appChannelBuckets.stream().filter(bucket -> AppChannelBucket appChannelBucket = appChannelBuckets.stream().filter(bucket ->
bucket.getChannelCode().equals(fileChannel.getChannelCode())) bucket.getChannelCode().equals(fileChannel.getChannelCode()))
.findFirst().orElse(null); .findFirst().orElse(null);
if (appChannelBucket == null) { BizException.isEmpty(appChannelBucket, CodeEnum.APP_CHANNEL_NOT_FOUND);
log.error("upload 最优渠道为空 channels:{}", channels);
throw new BizException(CodeEnum.APP_CHANNEL_NOT_FOUND);
}
// 通过渠道桶编码获取到具体文件业务场景 // 通过渠道桶编码获取到具体文件业务场景
FileBusinessScene scene = fileBusinessSceneDao FileBusinessScene scene = fileBusinessSceneManager
.getByBucketNoAndScene(appChannelBucket.getAppChannelBucketNo(), dto.getBizScene()); .getByBucketNoAndScene(appChannelBucket.getAppChannelBucketNo(), dto.getBizScene());
if (scene == null) {
log.error("upload 渠道不存在 appCode:{},bizScene:{}", dto.getAppCode(), dto.getBizScene());
throw new BizException(CodeEnum.APP_CHANNEL_NOT_FOUND);
}
FileUploadConfig fileUploadConfig = fileUploadConfigDao // 通过渠道码和桶名称获取获取指定上传配置
FileUploadConfig fileUploadConfig = fileUploadConfigManager
.getByUploadConfig(scene.getAppChannelBucketNo(), scene.getDirectory()); .getByUploadConfig(scene.getAppChannelBucketNo(), scene.getDirectory());
if (fileUploadConfig == null) {
log.error("upload 上传配置不存在 bucketNo:{},bucketName:{}", scene.getAppChannelBucketNo()
, scene.getBucketName());
throw new BizException(CodeEnum.NO_UPLOAD_CONFIG);
}
// 判断容量 // 判断容量
int size = Utility String fileConform = isFileConform(fileUploadConfig, dto.getFileContent().length,
.capacityConversion(fileUploadConfig.getStorageSize(), fileUploadConfig.getStorageUnit()); dto.getFileName());
if (dto.getFileContent().length > size) {
log.error("upload 文件大小超出上限 file size:{},storageSize:{}", dto.getFileContent().length
, size);
throw new BizException(CodeEnum.FILE_SIZE_EXCEEDS_LIMIT);
}
// 文件格式判断
String[] formats = fileUploadConfig.getFileFormat().split(",");
int lastIndexOf = dto.getFileName().lastIndexOf(".");
if (lastIndexOf == -1) {
log.error("获取文件格式失败:{}", dto.getFileName());
throw new BizException(CodeEnum.NOT_FILE_FORMAT);
}
String fileFormats = dto.getFileName().substring(lastIndexOf + 1).toLowerCase();
boolean contains = Arrays.asList(formats).contains(fileFormats);
if (!contains) {
log.error("不支持此格式文件fileName:{},formats:{}", dto.getFileName(), formats);
throw new BizException(CodeEnum.FILE_FORMAT_NOT_SUPPORTED);
}
String md5 = Utility.getMd5(dto.getFileContent());
File ossFile = new File(); File ossFile = new File();
ossFile.setAppChannelBucketNo(fileUploadConfig.getAppChannelBucketNo()); ossFile.setAppChannelBucketNo(fileUploadConfig.getAppChannelBucketNo());
@ -192,18 +153,17 @@ public class FileServiceImpl implements FileService {
ossFile.setChannelCode(fileUploadConfig.getChannelCode()); ossFile.setChannelCode(fileUploadConfig.getChannelCode());
ossFile.setBucketName(fileUploadConfig.getBucketName()); ossFile.setBucketName(fileUploadConfig.getBucketName());
ossFile.setDirectory(fileUploadConfig.getDirectory()); ossFile.setDirectory(fileUploadConfig.getDirectory());
ossFile.setFileMd5(md5); ossFile.setFileMd5(Utility.getMd5(dto.getFileContent()));
ossFile.setStatus(FileStatusEnum.STATUS_PROCESSING.getCode()); ossFile.setStatus(FileStatusEnum.STATUS_PROCESSING.getCode());
ossFile.setFileFormat(fileFormats); ossFile.setFileFormat(fileConform);
ossFile.setFileName(dto.getFileName()); ossFile.setFileName(dto.getFileName());
ossFile.setStorageUnit(fileUploadConfig.getStorageUnit()); ossFile.setStorageUnit(fileUploadConfig.getStorageUnit());
ossFile.setStorageSize(fileUploadConfig.getStorageSize()); ossFile.setStorageSize(fileUploadConfig.getStorageSize());
String uuid = Utility.getUUID(); String uuid = Utility.getUUID();
// 生成上传文件的唯一key // 生成上传文件的唯一key
String tgtFileKey = Utility.generateFileKey(fileUploadConfig.getDirectory(), uuid, fileFormats); String tgtFileKey = Utility.generateFileKey(fileUploadConfig.getDirectory(), uuid, fileConform);
String fileUrl = fileManager.uploadByStream( String fileUrl = fileManager.uploadByStream(
fileUploadConfig.getBucketName(), tgtFileKey, dto.getFileContent()); fileUploadConfig.getBucketName(), tgtFileKey, dto.getFileContent());
@ -227,5 +187,25 @@ public class FileServiceImpl implements FileService {
return response; return response;
} }
/**
* 判断文件是否符合要求
*/
private String isFileConform(FileUploadConfig fileUploadConfig, int fileLength, String fileName) {
// 文件大小超出上限
int size = Utility
.capacityConversion(fileUploadConfig.getStorageSize(), fileUploadConfig.getStorageUnit());
BizException.error(fileLength > size, CodeEnum.FILE_SIZE_EXCEEDS_LIMIT);
// 文件格式判断
String[] formats = fileUploadConfig.getFileFormat().split(CommonConstants.COMMA);
int lastIndexOf = fileName.lastIndexOf(CommonConstants.DOT);
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;
}
} }