add-上传文件前校验

This commit is contained in:
zhangran 2021-08-01 19:38:12 +08:00
parent fcf8713944
commit 9d69d0d727
16 changed files with 261 additions and 7 deletions

View File

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

View File

@ -30,7 +30,13 @@ public enum CodeEnum implements EnumBase<Integer> {
/**
* 101-200 业务场景
*/
S3_CLIENT_NULL(101,"oss client is null")
S3_CLIENT_NULL(101,"oss client is null"),
APP_CODE_NOT_FOUND(102,"app code not found"),
APP_CHANNEL_BUCKET_NOT_FOUND(103,"channel bucket not found"),
APP_CHANNEL_NOT_FOUND(104,"channel not found"),
NO_CHANNELS_AVAILABLE(105,"no channels available"),
NO_UPLOAD_CONFIG(106,"no upload config"),
FILE_SIZE_EXCEEDS_LIMIT(107,"file size exceeds limit"),
;

View File

@ -0,0 +1,43 @@
package cn.axzo.oss.common.enums;
import java.util.Arrays;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
/**
* @ClassName: cn.axzo.oss.common.enums
* @description:
* @author:
* @date: 2021/8/119:04
**/
@Getter
@RequiredArgsConstructor
public enum StorageUnitEnum {
/**
* B
*/
B(1, "B"),
/**
* KB
*/
KB(B.size * 1024, "KB"),
/**
* MB
*/
MB(KB.size * 1024, "MB"),
/**
* GB
*/
GB(MB.size * 1024, "GB"),
;
private final Integer size;
private final String unit;
public static StorageUnitEnum value(String unit) {
return Arrays.stream(values()).filter(storageUnitEnum -> storageUnitEnum.getUnit().equals(unit))
.findFirst().orElse(null);
}
}

View File

@ -1,5 +1,6 @@
package cn.axzo.oss.common.utils;
import cn.axzo.oss.common.enums.StorageUnitEnum;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@ -17,6 +18,7 @@ import org.apache.commons.codec.binary.Hex;
@Slf4j
public class Utility {
/**
* 判断对象为null
* @param obj
@ -88,4 +90,16 @@ public class Utility {
}
return "";
}
/**
* 容量换算
* @return
*/
public static int capacityConversion(int size, String storageUnit) {
StorageUnitEnum storageUnitEnum = StorageUnitEnum.valueOf(storageUnit);
if (objIsNull(storageUnitEnum)) {
return 0;
}
return storageUnitEnum.getSize() * size;
}
}

View File

@ -2,6 +2,7 @@ package cn.axzo.oss.dal.repository;
import cn.axzo.oss.dal.entity.AppChannelBucket;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* <p>
@ -13,4 +14,11 @@ import com.baomidou.mybatisplus.extension.service.IService;
*/
public interface AppChannelBucketDao extends IService<AppChannelBucket> {
/**
* 通过appcode获取文件渠道桶信息
*
* @param appCode appcode
* @return
*/
List<AppChannelBucket> getByAppCode(String appCode);
}

View File

@ -1,5 +1,6 @@
package cn.axzo.oss.dal.repository;
import cn.axzo.oss.dal.entity.File;
import cn.axzo.oss.dal.entity.FileApp;
import com.baomidou.mybatisplus.extension.service.IService;
@ -13,4 +14,10 @@ import com.baomidou.mybatisplus.extension.service.IService;
*/
public interface FileAppDao extends IService<FileApp> {
/**
* 通过appCode获取应用信息
* @param appCode
* @return
*/
FileApp getByAppCode(String appCode);
}

View File

@ -13,4 +13,12 @@ import com.baomidou.mybatisplus.extension.service.IService;
*/
public interface FileBusinessSceneDao extends IService<FileBusinessScene> {
/**
* 指定appcode文件业务场景
*
* @param bucketNo 应用编码
* @param bizScene
* @return
*/
FileBusinessScene getByBucketNoAndScene(String bucketNo, String bizScene);
}

View File

@ -2,6 +2,7 @@ package cn.axzo.oss.dal.repository;
import cn.axzo.oss.dal.entity.FileChannel;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* <p>
@ -13,4 +14,10 @@ import com.baomidou.mybatisplus.extension.service.IService;
*/
public interface FileChannelDao extends IService<FileChannel> {
/**
* 通过channelCode获取最高优化级可用文件渠道
* @param channelCodes
* @return
*/
List<FileChannel> getByChannelCode(List<String> channelCodes);
}

View File

@ -13,4 +13,12 @@ import com.baomidou.mybatisplus.extension.service.IService;
*/
public interface FileUploadConfigDao extends IService<FileUploadConfig> {
/**
* 通过渠道码和桶名称获取获取指定上传配置
*
* @param bucketNo
* @param directory
* @return
*/
FileUploadConfig getByUploadConfig(String bucketNo, String directory);
}

View File

@ -1,9 +1,11 @@
package cn.axzo.oss.dal.repository.impl;
import cn.axzo.oss.common.enums.IsDeleteEnum;
import cn.axzo.oss.dal.entity.AppChannelBucket;
import cn.axzo.oss.dal.mapper.AppChannelBucketMapper;
import cn.axzo.oss.dal.repository.AppChannelBucketDao;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.util.List;
import org.springframework.stereotype.Repository;
/**
@ -15,6 +17,18 @@ import org.springframework.stereotype.Repository;
* @since 2021-07-23
*/
@Repository("appChannelBucketDao")
public class AppChannelBucketDaoImpl extends ServiceImpl<AppChannelBucketMapper, AppChannelBucket> implements AppChannelBucketDao {
public class AppChannelBucketDaoImpl extends
ServiceImpl<AppChannelBucketMapper, AppChannelBucket> implements AppChannelBucketDao {
/**
* 通过appcode获取文件渠道桶信息
*
* @param appCode appcode
* @return
*/
@Override
public List<AppChannelBucket> getByAppCode(String appCode) {
return lambdaQuery().eq(AppChannelBucket::getAppCode, appCode)
.eq(AppChannelBucket::getIsDelete, IsDeleteEnum.NO.getCode()).list();
}
}

View File

@ -1,5 +1,6 @@
package cn.axzo.oss.dal.repository.impl;
import cn.axzo.oss.common.enums.IsDeleteEnum;
import cn.axzo.oss.dal.entity.FileApp;
import cn.axzo.oss.dal.mapper.FileAppMapper;
import cn.axzo.oss.dal.repository.FileAppDao;
@ -17,4 +18,17 @@ import org.springframework.stereotype.Repository;
@Repository("fileAppDao")
public class FileAppDaoImpl extends ServiceImpl<FileAppMapper, FileApp> implements FileAppDao {
/**
* 通过appCode获取应用信息
*
* @param appCode
* @return
*/
@Override
public FileApp getByAppCode(String appCode) {
return lambdaQuery().eq(FileApp::getAppCode, appCode)
.eq(FileApp::getStatus, 1)
.eq(FileApp::getIsDelete, IsDeleteEnum.NO.getCode()).one();
}
}

View File

@ -1,5 +1,6 @@
package cn.axzo.oss.dal.repository.impl;
import cn.axzo.oss.common.enums.IsDeleteEnum;
import cn.axzo.oss.dal.entity.FileBusinessScene;
import cn.axzo.oss.dal.mapper.FileBusinessSceneMapper;
import cn.axzo.oss.dal.repository.FileBusinessSceneDao;
@ -15,6 +16,19 @@ import org.springframework.stereotype.Repository;
* @since 2021-07-23
*/
@Repository("fileBusinessSceneDao")
public class FileBusinessSceneDaoImpl extends ServiceImpl<FileBusinessSceneMapper, FileBusinessScene> implements FileBusinessSceneDao {
public class FileBusinessSceneDaoImpl extends
ServiceImpl<FileBusinessSceneMapper, FileBusinessScene> implements FileBusinessSceneDao {
/**
* 指定appcode文件业务场景
*
* @param bucketNo
* @return
*/
@Override
public FileBusinessScene getByBucketNoAndScene(String bucketNo, String bizScen) {
return lambdaQuery().eq(FileBusinessScene::getAppChannelBucketNo, bucketNo)
.eq(FileBusinessScene::getBusinessScene,bizScen)
.eq(FileBusinessScene::getIsDelete, IsDeleteEnum.NO.getCode()).one();
}
}

View File

@ -4,6 +4,7 @@ import cn.axzo.oss.dal.entity.FileChannel;
import cn.axzo.oss.dal.mapper.FileChannelMapper;
import cn.axzo.oss.dal.repository.FileChannelDao;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.util.List;
import org.springframework.stereotype.Repository;
/**
@ -17,4 +18,16 @@ import org.springframework.stereotype.Repository;
@Repository("fileChannelDao")
public class FileChannelDaoImpl extends ServiceImpl<FileChannelMapper, FileChannel> implements FileChannelDao {
/**
* 通过channelCode获取多个可用文件渠道
*
* @param channelCodes
* @return
*/
@Override
public List<FileChannel> getByChannelCode(List<String> channelCodes) {
return lambdaQuery().in(FileChannel::getChannelCode,channelCodes)
.eq(FileChannel::getStatus,1)
.orderByAsc(FileChannel::getPriority).list();
}
}

View File

@ -1,5 +1,6 @@
package cn.axzo.oss.dal.repository.impl;
import cn.axzo.oss.common.enums.IsDeleteEnum;
import cn.axzo.oss.dal.entity.FileUploadConfig;
import cn.axzo.oss.dal.mapper.FileUploadConfigMapper;
import cn.axzo.oss.dal.repository.FileUploadConfigDao;
@ -15,6 +16,20 @@ import org.springframework.stereotype.Repository;
* @since 2021-07-23
*/
@Repository("fileUploadConfigDao")
public class FileUploadConfigDaoImpl extends ServiceImpl<FileUploadConfigMapper, FileUploadConfig> implements FileUploadConfigDao {
public class FileUploadConfigDaoImpl extends
ServiceImpl<FileUploadConfigMapper, FileUploadConfig> implements FileUploadConfigDao {
/**
* 通过渠道码和桶名称获取获取指定上传配置
*
* @param bucketNo
* @param directory
* @return
*/
@Override
public FileUploadConfig getByUploadConfig(String bucketNo, String directory) {
return lambdaQuery().eq(FileUploadConfig::getAppChannelBucketNo, bucketNo)
.eq(FileUploadConfig::getDirectory, directory)
.eq(FileUploadConfig::getIsDelete, IsDeleteEnum.NO.getCode()).one();
}
}

View File

@ -23,5 +23,5 @@ public interface FileService {
*
* @param request
*/
void update(ServerFileUploadDto request);
void upload(ServerFileUploadDto request);
}

View File

@ -2,18 +2,34 @@ package cn.axzo.oss.service.impl;
import cn.axzo.oss.common.constans.CommonConstants.FileStatus;
import cn.axzo.oss.common.constans.CommonConstants.TableDelete;
import cn.axzo.oss.common.enums.CodeEnum;
import cn.axzo.oss.common.exception.BizException;
import cn.axzo.oss.common.utils.JsonUtil;
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.FileChannel;
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.FileBusinessSceneDao;
import cn.axzo.oss.dal.repository.FileChannelDao;
import cn.axzo.oss.dal.repository.FileDao;
import cn.axzo.oss.dal.repository.FileUploadConfigDao;
import cn.axzo.oss.manager.api.FileManager;
import cn.axzo.oss.manager.api.dto.request.ServerFileDeleteDto;
import cn.axzo.oss.manager.api.dto.request.ServerFileUploadDto;
import cn.axzo.oss.service.api.FileService;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import java.util.ArrayList;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
/**
* @Author admin
@ -31,6 +47,17 @@ public class FileServiceImpl implements FileService {
@Autowired
private FileDao fileDao;
@Autowired
private FileAppDao fileAppDao;
@Autowired
private AppChannelBucketDao appChannelBucketDao;
@Autowired
private FileChannelDao fileChannelDao;
@Autowired
private FileBusinessSceneDao fileBusinessSceneDao;
@Autowired
private FileUploadConfigDao fileUploadConfigDao;
/**
* 删除文件
*
@ -67,7 +94,7 @@ public class FileServiceImpl implements FileService {
* @param dto
*/
@Override
public void update(ServerFileUploadDto dto) {
public void upload(ServerFileUploadDto dto) {
log.info("update dto:{}", JSON.toJSONString(dto));
/**
* 1.检查app
@ -77,5 +104,61 @@ public class FileServiceImpl implements FileService {
* 5.检查文件大小格式
* 6.上传至oss
*/
FileApp fileAppByAppCode = fileAppDao.getByAppCode(dto.getAppCode());
if (fileAppByAppCode == null) {
log.error("upload 未找到对应编码 appCode:{}", dto.getAppCode());
throw new BizException(CodeEnum.APP_CODE_NOT_FOUND);
}
List<AppChannelBucket> appChannelBuckets = appChannelBucketDao
.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();
appChannelBuckets.forEach(appChannelBucket -> channels.add(appChannelBucket.getChannelCode()));
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 ->
bucket.getChannelCode().equals(fileChannel.getChannelCode()))
.findFirst().orElse(null);
// 通过渠道桶编码获取到具体文件业务场景
FileBusinessScene scene = fileBusinessSceneDao
.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
.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
.capacityConversion(fileUploadConfig.getStorageSize(), fileUploadConfig.getStorageUnit());
if (dto.getFileContent().length > size) {
log.error("upload 文件大小超出上限 file size:{},storageSize:{}", dto.getFileContent().length
, size);
throw new BizException(CodeEnum.FILE_SIZE_EXCEEDS_LIMIT);
}
// todo 文件格式判断
}
}