Commit 0c13553fbb7fd45051aabd403c2e513a6edfa62b

Authored by xp.Huang
1 parent 94f0dec9

fix: 在MinioService注入的时候,默认不创建存储桶。在上传文件时按日期(yyyy-MM-dd)格式来存储文件

... ... @@ -1188,7 +1188,7 @@ file:
1188 1188 randomFileName: true #是否重命名文件名字,防止冲突
1189 1189 local:
1190 1190 uploadDir: /Users/thingskit/upload/ #文件上传地址 只有type = local需要
1191   - downloadPath: /downloadFile/ #与controller里面下载文件GetMapping的path一致, 只有type = local需要
  1191 + downloadPath: /download_file/ #与controller里面下载文件GetMapping的path一致, 只有type = local需要
1192 1192 uploadPath: /upload #与controller里面下载文件GetMapping的path一致, 只有type = local需要
1193 1193 staticUrl: /oss/files/** #oss静态访问路径 只有type = local需要
1194 1194 randomFileName: ${file.storage.randomFileName}
... ...
... ... @@ -87,6 +87,8 @@ public enum ErrorMessage {
87 87 DUPLICATE_IDENTIFIERS_EXIST(400063,"存在重复的功能标识符。"),
88 88 SMS_CONFIG_ERROR(400064,"短信配置错误。"),
89 89 INVALID_TOPIC(400065,"无效Topic。"),
  90 + BUCKET_NOT_CONFORM_RENAME_RULE(400066,"存储桶不符合命名规范!!"),
  91 + MINIO_KEY_AND_SIGNATURE_ERROR(400067,"Minio签名不匹配!!"),
90 92 HAVE_NO_PERMISSION(500002,"没有修改权限");
91 93 private final int code;
92 94 private String message;
... ...
... ... @@ -17,12 +17,14 @@ import org.springframework.web.context.request.RequestContextHolder;
17 17 import org.springframework.web.context.request.ServletRequestAttributes;
18 18 import org.springframework.web.multipart.MultipartFile;
19 19 import org.thingsboard.server.common.data.yunteng.core.exception.FileStorageException;
  20 +import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidationException;
20 21 import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage;
21 22 import org.thingsboard.server.common.data.yunteng.dto.FileUploadResponse;
22 23
23 24 import javax.net.ssl.*;
24 25 import javax.servlet.http.HttpServletRequest;
25 26 import javax.servlet.http.HttpServletResponse;
  27 +import java.io.File;
26 28 import java.io.IOException;
27 29 import java.io.InputStream;
28 30 import java.io.OutputStream;
... ... @@ -31,6 +33,8 @@ import java.security.KeyManagementException;
31 33 import java.security.NoSuchAlgorithmException;
32 34 import java.security.SecureRandom;
33 35 import java.security.cert.X509Certificate;
  36 +import java.time.LocalDateTime;
  37 +import java.time.format.DateTimeFormatter;
34 38 import java.util.Objects;
35 39
36 40 @Service
... ... @@ -50,10 +54,8 @@ public class MinioFileStorageService implements FileStorageService {
50 54 MinioClient.builder()
51 55 .endpoint(fileStorageProperties.getMinioUrl())
52 56 .credentials(fileStorageProperties.getMinioName(), fileStorageProperties.getMinioPass())
53   - .httpClient(getUnsafeOkHttpClient())
  57 + .httpClient(Objects.requireNonNull(getUnsafeOkHttpClient()))
54 58 .build();
55   - // 创建储存桶
56   - checkBucket();
57 59 }
58 60
59 61 public static OkHttpClient getUnsafeOkHttpClient() throws KeyManagementException {
... ... @@ -94,12 +96,22 @@ public class MinioFileStorageService implements FileStorageService {
94 96 // Normalize file name
95 97 String fileName = StringUtils.cleanPath(Objects.requireNonNull(file.getOriginalFilename()));
96 98 // random fileName if needed
  99 +
97 100 // 储存
98 101 try {
99 102 return storeFileByInputStream(fileName, file.getContentType(), file.getInputStream());
100   - } catch (Exception ex) {
101   - ex.printStackTrace();
  103 + } catch (IOException ex) {
102 104 throw new FileStorageException(ErrorMessage.STORE_FILE_FAILED);
  105 + } catch (TkDataValidationException
  106 + | ServerException
  107 + | InsufficientDataException
  108 + | ErrorResponseException
  109 + | NoSuchAlgorithmException
  110 + | InvalidKeyException
  111 + | InvalidResponseException
  112 + | XmlParserException
  113 + | InternalException e) {
  114 + throw new TkDataValidationException(e.getMessage());
103 115 }
104 116 }
105 117
... ... @@ -107,18 +119,14 @@ public class MinioFileStorageService implements FileStorageService {
107 119 public FileUploadResponse upload(MultipartFile file) {
108 120 String fileName = this.storeFile(file);
109 121 String staticPath = getPath(fileName);
110   - String realDownloadPath = null;
111   - try {
112   - // 获取request
113   - HttpServletRequest request =
114   - ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
115   - // 生成下载接口的地址
116   - realDownloadPath =
117   - request.getRequestURL().toString().replace("upload", "downloadFile/" + fileName);
118   - } catch (Exception e) {
119   - e.printStackTrace();
120   - log.info("Could not upload file " + fileName + ". Please try again!");
121   - }
  122 + // 获取request
  123 + HttpServletRequest request =
  124 + ((ServletRequestAttributes)
  125 + Objects.requireNonNull(RequestContextHolder.getRequestAttributes()))
  126 + .getRequest();
  127 + // 生成下载接口的地址
  128 + String realDownloadPath =
  129 + request.getRequestURL().toString().replace("upload", "downloadFile/" + fileName);
122 130 return new FileUploadResponse(
123 131 fileName, realDownloadPath, file.getContentType(), file.getSize(), staticPath);
124 132 }
... ... @@ -165,29 +173,29 @@ public class MinioFileStorageService implements FileStorageService {
165 173 }
166 174 }
167 175
168   - // 检查储存桶情况
169   - private void checkBucket() {
170   - try {
171   - // 桶是否存在
172   - boolean exists =
173   - minioClient.bucketExists(
174   - BucketExistsArgs.builder().bucket(fileStorageProperties.getBucketName()).build());
175   - if (!exists) {
176   - // 不存在创建
177   - minioClient.makeBucket(
178   - MakeBucketArgs.builder().bucket(fileStorageProperties.getBucketName()).build());
179   - // 设置储存桶策略
180   - String str =
181   - "{\"Statement\": [{\"Action\": [\"s3:GetBucketLocation\",\"s3:ListBucket\"],\"Effect\": \"Allow\",\"Principal\": \"*\",\"Resource\": \"arn:aws:s3:::%\"},{\"Action\": \"s3:GetObject\",\"Effect\": \"Allow\",\"Principal\": \"*\",\"Resource\": \"arn:aws:s3:::%/*\"}],\"Version\": \"2012-10-17\"}";
182   - String replace = str.replace("%", fileStorageProperties.getBucketName());
183   - minioClient.setBucketPolicy(
184   - SetBucketPolicyArgs.builder()
185   - .bucket(fileStorageProperties.getBucketName())
186   - .config(replace)
187   - .build());
188   - }
189   - } catch (Exception e) {
190   - log.error(e.getMessage(), e);
  176 + private void checkBucket()
  177 + throws ServerException, InsufficientDataException, ErrorResponseException, IOException,
  178 + NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException,
  179 + XmlParserException, InternalException {
  180 + String bucketName = fileStorageProperties.getBucketName();
  181 + // 桶是否存在
  182 + boolean exists =
  183 + minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
  184 + if (!exists) {
  185 + // 不存在创建
  186 + minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
  187 + // 设置储存桶策略
  188 + String str =
  189 + "{\"Statement\": [{\"Action\": [\"s3:GetBucketLocation\",\"s3:ListBucket\"],"
  190 + + "\"Effect\": \"Allow\",\"Principal\": \"*\",\"Resource\": \"arn:aws:s3:::%\"},{\"Action\": "
  191 + + "\"s3:GetObject\",\"Effect\": \"Allow\",\"Principal\": \"*\","
  192 + + "\"Resource\": \"arn:aws:s3:::%/*\"}],\"Version\": \"2012-10-17\"}";
  193 + String replace = str.replace("%", fileStorageProperties.getBucketName());
  194 + minioClient.setBucketPolicy(
  195 + SetBucketPolicyArgs.builder()
  196 + .bucket(fileStorageProperties.getBucketName())
  197 + .config(replace)
  198 + .build());
191 199 }
192 200 }
193 201
... ... @@ -222,7 +230,15 @@ public class MinioFileStorageService implements FileStorageService {
222 230 if (fileName.contains("..")) {
223 231 throw new FileStorageException(ErrorMessage.STORE_FILE_FAILED);
224 232 }
225   - checkBucket();
  233 + try {
  234 + checkBucket();
  235 + } catch (ErrorResponseException e) {
  236 + throw new TkDataValidationException(ErrorMessage.MINIO_KEY_AND_SIGNATURE_ERROR.getMessage());
  237 + } catch (Exception e) {
  238 + throw new TkDataValidationException(ErrorMessage.BUCKET_NOT_CONFORM_RENAME_RULE.getMessage());
  239 + }
  240 + String date = LocalDateTime.now().format(DateTimeFormatter.ISO_DATE);
  241 + fileName = date + "/" + fileName;
226 242 PutObjectArgs build =
227 243 PutObjectArgs.builder()
228 244 .bucket(fileStorageProperties.getBucketName())
... ...