Commit 0c13553fbb7fd45051aabd403c2e513a6edfa62b

Authored by xp.Huang
1 parent 94f0dec9

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

@@ -1188,7 +1188,7 @@ file: @@ -1188,7 +1188,7 @@ file:
1188 randomFileName: true #是否重命名文件名字,防止冲突 1188 randomFileName: true #是否重命名文件名字,防止冲突
1189 local: 1189 local:
1190 uploadDir: /Users/thingskit/upload/ #文件上传地址 只有type = local需要 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 uploadPath: /upload #与controller里面下载文件GetMapping的path一致, 只有type = local需要 1192 uploadPath: /upload #与controller里面下载文件GetMapping的path一致, 只有type = local需要
1193 staticUrl: /oss/files/** #oss静态访问路径 只有type = local需要 1193 staticUrl: /oss/files/** #oss静态访问路径 只有type = local需要
1194 randomFileName: ${file.storage.randomFileName} 1194 randomFileName: ${file.storage.randomFileName}
@@ -87,6 +87,8 @@ public enum ErrorMessage { @@ -87,6 +87,8 @@ public enum ErrorMessage {
87 DUPLICATE_IDENTIFIERS_EXIST(400063,"存在重复的功能标识符。"), 87 DUPLICATE_IDENTIFIERS_EXIST(400063,"存在重复的功能标识符。"),
88 SMS_CONFIG_ERROR(400064,"短信配置错误。"), 88 SMS_CONFIG_ERROR(400064,"短信配置错误。"),
89 INVALID_TOPIC(400065,"无效Topic。"), 89 INVALID_TOPIC(400065,"无效Topic。"),
  90 + BUCKET_NOT_CONFORM_RENAME_RULE(400066,"存储桶不符合命名规范!!"),
  91 + MINIO_KEY_AND_SIGNATURE_ERROR(400067,"Minio签名不匹配!!"),
90 HAVE_NO_PERMISSION(500002,"没有修改权限"); 92 HAVE_NO_PERMISSION(500002,"没有修改权限");
91 private final int code; 93 private final int code;
92 private String message; 94 private String message;
@@ -17,12 +17,14 @@ import org.springframework.web.context.request.RequestContextHolder; @@ -17,12 +17,14 @@ import org.springframework.web.context.request.RequestContextHolder;
17 import org.springframework.web.context.request.ServletRequestAttributes; 17 import org.springframework.web.context.request.ServletRequestAttributes;
18 import org.springframework.web.multipart.MultipartFile; 18 import org.springframework.web.multipart.MultipartFile;
19 import org.thingsboard.server.common.data.yunteng.core.exception.FileStorageException; 19 import org.thingsboard.server.common.data.yunteng.core.exception.FileStorageException;
  20 +import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidationException;
20 import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage; 21 import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage;
21 import org.thingsboard.server.common.data.yunteng.dto.FileUploadResponse; 22 import org.thingsboard.server.common.data.yunteng.dto.FileUploadResponse;
22 23
23 import javax.net.ssl.*; 24 import javax.net.ssl.*;
24 import javax.servlet.http.HttpServletRequest; 25 import javax.servlet.http.HttpServletRequest;
25 import javax.servlet.http.HttpServletResponse; 26 import javax.servlet.http.HttpServletResponse;
  27 +import java.io.File;
26 import java.io.IOException; 28 import java.io.IOException;
27 import java.io.InputStream; 29 import java.io.InputStream;
28 import java.io.OutputStream; 30 import java.io.OutputStream;
@@ -31,6 +33,8 @@ import java.security.KeyManagementException; @@ -31,6 +33,8 @@ import java.security.KeyManagementException;
31 import java.security.NoSuchAlgorithmException; 33 import java.security.NoSuchAlgorithmException;
32 import java.security.SecureRandom; 34 import java.security.SecureRandom;
33 import java.security.cert.X509Certificate; 35 import java.security.cert.X509Certificate;
  36 +import java.time.LocalDateTime;
  37 +import java.time.format.DateTimeFormatter;
34 import java.util.Objects; 38 import java.util.Objects;
35 39
36 @Service 40 @Service
@@ -50,10 +54,8 @@ public class MinioFileStorageService implements FileStorageService { @@ -50,10 +54,8 @@ public class MinioFileStorageService implements FileStorageService {
50 MinioClient.builder() 54 MinioClient.builder()
51 .endpoint(fileStorageProperties.getMinioUrl()) 55 .endpoint(fileStorageProperties.getMinioUrl())
52 .credentials(fileStorageProperties.getMinioName(), fileStorageProperties.getMinioPass()) 56 .credentials(fileStorageProperties.getMinioName(), fileStorageProperties.getMinioPass())
53 - .httpClient(getUnsafeOkHttpClient()) 57 + .httpClient(Objects.requireNonNull(getUnsafeOkHttpClient()))
54 .build(); 58 .build();
55 - // 创建储存桶  
56 - checkBucket();  
57 } 59 }
58 60
59 public static OkHttpClient getUnsafeOkHttpClient() throws KeyManagementException { 61 public static OkHttpClient getUnsafeOkHttpClient() throws KeyManagementException {
@@ -94,12 +96,22 @@ public class MinioFileStorageService implements FileStorageService { @@ -94,12 +96,22 @@ public class MinioFileStorageService implements FileStorageService {
94 // Normalize file name 96 // Normalize file name
95 String fileName = StringUtils.cleanPath(Objects.requireNonNull(file.getOriginalFilename())); 97 String fileName = StringUtils.cleanPath(Objects.requireNonNull(file.getOriginalFilename()));
96 // random fileName if needed 98 // random fileName if needed
  99 +
97 // 储存 100 // 储存
98 try { 101 try {
99 return storeFileByInputStream(fileName, file.getContentType(), file.getInputStream()); 102 return storeFileByInputStream(fileName, file.getContentType(), file.getInputStream());
100 - } catch (Exception ex) {  
101 - ex.printStackTrace(); 103 + } catch (IOException ex) {
102 throw new FileStorageException(ErrorMessage.STORE_FILE_FAILED); 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,18 +119,14 @@ public class MinioFileStorageService implements FileStorageService {
107 public FileUploadResponse upload(MultipartFile file) { 119 public FileUploadResponse upload(MultipartFile file) {
108 String fileName = this.storeFile(file); 120 String fileName = this.storeFile(file);
109 String staticPath = getPath(fileName); 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 return new FileUploadResponse( 130 return new FileUploadResponse(
123 fileName, realDownloadPath, file.getContentType(), file.getSize(), staticPath); 131 fileName, realDownloadPath, file.getContentType(), file.getSize(), staticPath);
124 } 132 }
@@ -165,29 +173,29 @@ public class MinioFileStorageService implements FileStorageService { @@ -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,7 +230,15 @@ public class MinioFileStorageService implements FileStorageService {
222 if (fileName.contains("..")) { 230 if (fileName.contains("..")) {
223 throw new FileStorageException(ErrorMessage.STORE_FILE_FAILED); 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 PutObjectArgs build = 242 PutObjectArgs build =
227 PutObjectArgs.builder() 243 PutObjectArgs.builder()
228 .bucket(fileStorageProperties.getBucketName()) 244 .bucket(fileStorageProperties.getBucketName())