Commit 34a7399a65b5cb011a5df793c16a2cc911378bac

Authored by YunaiV
1 parent 62f7d349

使用 minio client 替代 amazon 客户端,进行 S3 的对接

yudao-dependencies/pom.xml
@@ -56,7 +56,7 @@ @@ -56,7 +56,7 @@
56 <commons-net.version>3.8.0</commons-net.version> 56 <commons-net.version>3.8.0</commons-net.version>
57 <jsch.version>0.1.55</jsch.version> 57 <jsch.version>0.1.55</jsch.version>
58 <!-- 三方云服务相关 --> 58 <!-- 三方云服务相关 -->
59 - <s3.version>2.17.147</s3.version> 59 + <minio.version>8.2.2</minio.version>
60 <aliyun-java-sdk-core.version>4.5.25</aliyun-java-sdk-core.version> 60 <aliyun-java-sdk-core.version>4.5.25</aliyun-java-sdk-core.version>
61 <aliyun-java-sdk-dysmsapi.version>2.1.0</aliyun-java-sdk-dysmsapi.version> 61 <aliyun-java-sdk-dysmsapi.version>2.1.0</aliyun-java-sdk-dysmsapi.version>
62 <yunpian-java-sdk.version>1.2.7</yunpian-java-sdk.version> 62 <yunpian-java-sdk.version>1.2.7</yunpian-java-sdk.version>
@@ -514,9 +514,9 @@ @@ -514,9 +514,9 @@
514 <version>${revision}</version> 514 <version>${revision}</version>
515 </dependency> 515 </dependency>
516 <dependency> 516 <dependency>
517 - <groupId>software.amazon.awssdk</groupId>  
518 - <artifactId>s3</artifactId>  
519 - <version>${s3.version}</version> 517 + <groupId>io.minio</groupId>
  518 + <artifactId>minio</artifactId>
  519 + <version>${minio.version}</version>
520 </dependency> 520 </dependency>
521 521
522 <!-- SMS SDK begin --> 522 <!-- SMS SDK begin -->
yudao-framework/yudao-spring-boot-starter-file/pom.xml
@@ -63,8 +63,8 @@ @@ -63,8 +63,8 @@
63 63
64 <!-- 三方云服务相关 --> 64 <!-- 三方云服务相关 -->
65 <dependency> 65 <dependency>
66 - <groupId>software.amazon.awssdk</groupId>  
67 - <artifactId>s3</artifactId> 66 + <groupId>io.minio</groupId>
  67 + <artifactId>minio</artifactId>
68 </dependency> 68 </dependency>
69 69
70 <!-- Test 测试相关 --> 70 <!-- Test 测试相关 -->
yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/FileClient.java
@@ -20,15 +20,17 @@ public interface FileClient { @@ -20,15 +20,17 @@ public interface FileClient {
20 * @param content 文件流 20 * @param content 文件流
21 * @param path 相对路径 21 * @param path 相对路径
22 * @return 完整路径,即 HTTP 访问地址 22 * @return 完整路径,即 HTTP 访问地址
  23 + * @throws Exception 上传文件时,抛出 Exception 异常
23 */ 24 */
24 - String upload(byte[] content, String path); 25 + String upload(byte[] content, String path) throws Exception;
25 26
26 /** 27 /**
27 * 删除文件 28 * 删除文件
28 * 29 *
29 * @param path 相对路径 30 * @param path 相对路径
  31 + * @throws Exception 删除文件时,抛出 Exception 异常
30 */ 32 */
31 - void delete(String path); 33 + void delete(String path) throws Exception;
32 34
33 /** 35 /**
34 * 获得文件的内容 36 * 获得文件的内容
@@ -36,6 +38,6 @@ public interface FileClient { @@ -36,6 +38,6 @@ public interface FileClient {
36 * @param path 相对路径 38 * @param path 相对路径
37 * @return 文件的内容 39 * @return 文件的内容
38 */ 40 */
39 - byte[] getContent(String path); 41 + byte[] getContent(String path) throws Exception;
40 42
41 } 43 }
yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/s3/S3FileClient.java
1 package cn.iocoder.yudao.framework.file.core.client.s3; 1 package cn.iocoder.yudao.framework.file.core.client.s3;
2 2
  3 +import cn.hutool.core.io.IoUtil;
3 import cn.hutool.core.util.StrUtil; 4 import cn.hutool.core.util.StrUtil;
  5 +import cn.hutool.http.HttpUtil;
4 import cn.iocoder.yudao.framework.file.core.client.AbstractFileClient; 6 import cn.iocoder.yudao.framework.file.core.client.AbstractFileClient;
5 -import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;  
6 -import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;  
7 -import software.amazon.awssdk.core.sync.RequestBody;  
8 -import software.amazon.awssdk.regions.Region;  
9 -import software.amazon.awssdk.services.s3.S3Client;  
10 -import software.amazon.awssdk.services.s3.model.DeleteObjectRequest;  
11 -import software.amazon.awssdk.services.s3.model.GetObjectRequest;  
12 -import software.amazon.awssdk.services.s3.model.PutObjectRequest; 7 +import io.minio.*;
13 8
14 -import java.net.URI; 9 +import java.io.ByteArrayInputStream;
15 10
16 -import static cn.iocoder.yudao.framework.file.core.client.s3.S3FileClientConfig.ENDPOINT_QINIU; 11 +import static cn.iocoder.yudao.framework.file.core.client.s3.S3FileClientConfig.ENDPOINT_ALIYUN;
17 12
18 /** 13 /**
19 * 基于 S3 协议的文件客户端,实现 MinIO、阿里云、腾讯云、七牛云、华为云等云服务 14 * 基于 S3 协议的文件客户端,实现 MinIO、阿里云、腾讯云、七牛云、华为云等云服务
@@ -24,7 +19,7 @@ import static cn.iocoder.yudao.framework.file.core.client.s3.S3FileClientConfig. @@ -24,7 +19,7 @@ import static cn.iocoder.yudao.framework.file.core.client.s3.S3FileClientConfig.
24 */ 19 */
25 public class S3FileClient extends AbstractFileClient<S3FileClientConfig> { 20 public class S3FileClient extends AbstractFileClient<S3FileClientConfig> {
26 21
27 - private S3Client client; 22 + private MinioClient client;
28 23
29 public S3FileClient(Long id, S3FileClientConfig config) { 24 public S3FileClient(Long id, S3FileClientConfig config) {
30 super(id, config); 25 super(id, config);
@@ -34,34 +29,27 @@ public class S3FileClient extends AbstractFileClient&lt;S3FileClientConfig&gt; { @@ -34,34 +29,27 @@ public class S3FileClient extends AbstractFileClient&lt;S3FileClientConfig&gt; {
34 protected void doInit() { 29 protected void doInit() {
35 // 补全 domain 30 // 补全 domain
36 if (StrUtil.isEmpty(config.getDomain())) { 31 if (StrUtil.isEmpty(config.getDomain())) {
37 - config.setDomain(createDomain()); 32 + config.setDomain(buildDomain());
38 } 33 }
39 // 初始化客户端 34 // 初始化客户端
40 - client = S3Client.builder()  
41 - .serviceConfiguration(sb -> sb.pathStyleAccessEnabled(false) // 关闭路径风格  
42 - .chunkedEncodingEnabled(false)) // 禁用 chunk  
43 - .endpointOverride(createURI()) // 上传地址  
44 - .region(Region.of(config.getRegion())) // Region  
45 - .credentialsProvider(StaticCredentialsProvider.create( // 认证密钥  
46 - AwsBasicCredentials.create(config.getAccessKey(), config.getAccessSecret())))  
47 - .overrideConfiguration(cb -> cb.addExecutionInterceptor(new S3ModifyPathInterceptor(config.getBucket()))) 35 + client = MinioClient.builder()
  36 + .endpoint(buildEndpointURL()) // Endpoint URL
  37 + .region(buildRegion()) // Region
  38 + .credentials(config.getAccessKey(), config.getAccessSecret()) // 认证密钥
48 .build(); 39 .build();
49 } 40 }
50 41
51 /** 42 /**
52 - * 基于 endpoint 构建调用云服务的 URI 地址 43 + * 基于 endpoint 构建调用云服务的 URL 地址
53 * 44 *
54 * @return URI 地址 45 * @return URI 地址
55 */ 46 */
56 - private URI createURI() {  
57 - String uri;  
58 - // 如果是七牛,无需拼接 bucket  
59 - if (config.getEndpoint().contains(ENDPOINT_QINIU)) {  
60 - uri = StrUtil.format("https://{}", config.getEndpoint());  
61 - } else {  
62 - uri = StrUtil.format("https://{}.{}", config.getBucket(), config.getEndpoint()); 47 + private String buildEndpointURL() {
  48 + // 如果已经是 http 或者 https,则不进行拼接.主要适配 MinIO
  49 + if (HttpUtil.isHttp(config.getEndpoint()) || HttpUtil.isHttps(config.getEndpoint())) {
  50 + return config.getEndpoint();
63 } 51 }
64 - return URI.create(uri); 52 + return StrUtil.format("https://{}", config.getEndpoint());
65 } 53 }
66 54
67 /** 55 /**
@@ -69,35 +57,56 @@ public class S3FileClient extends AbstractFileClient&lt;S3FileClientConfig&gt; { @@ -69,35 +57,56 @@ public class S3FileClient extends AbstractFileClient&lt;S3FileClientConfig&gt; {
69 * 57 *
70 * @return Domain 地址 58 * @return Domain 地址
71 */ 59 */
72 - private String createDomain() { 60 + private String buildDomain() {
  61 + // 如果已经是 http 或者 https,则不进行拼接.主要适配 MinIO
  62 + if (HttpUtil.isHttp(config.getEndpoint()) || HttpUtil.isHttps(config.getEndpoint())) {
  63 + return StrUtil.format("{}/{}", config.getEndpoint(), config.getBucket());
  64 + }
  65 + // 阿里云、腾讯云、华为云都适合。七牛云比较特殊,必须有自定义域名
73 return StrUtil.format("https://{}.{}", config.getBucket(), config.getEndpoint()); 66 return StrUtil.format("https://{}.{}", config.getBucket(), config.getEndpoint());
74 } 67 }
75 68
  69 + /**
  70 + * 基于 bucket 构建 region 地区
  71 + *
  72 + * @return region 地区
  73 + */
  74 + private String buildRegion() {
  75 + // 阿里云必须有 region,否则会报错
  76 + if (config.getEndpoint().contains(ENDPOINT_ALIYUN)) {
  77 + return StrUtil.subBefore(config.getEndpoint(), '.', false)
  78 + .replaceAll("-internal", ""); // 去除内网 Endpoint 的后缀
  79 + }
  80 + return null;
  81 + }
  82 +
76 @Override 83 @Override
77 - public String upload(byte[] content, String path) { 84 + public String upload(byte[] content, String path) throws Exception {
78 // 执行上传 85 // 执行上传
79 - PutObjectRequest.Builder request = PutObjectRequest.builder() 86 + client.putObject(PutObjectArgs.builder()
80 .bucket(config.getBucket()) // bucket 必须传递 87 .bucket(config.getBucket()) // bucket 必须传递
81 - .key(path); // 相对路径作为 key  
82 - client.putObject(request.build(), RequestBody.fromBytes(content)); 88 + .object(path) // 相对路径作为 key
  89 + .stream(new ByteArrayInputStream(content), content.length, -1) // 文件内容
  90 + .build());
83 // 拼接返回路径 91 // 拼接返回路径
84 return config.getDomain() + "/" + path; 92 return config.getDomain() + "/" + path;
85 } 93 }
86 94
87 @Override 95 @Override
88 - public void delete(String path) {  
89 - DeleteObjectRequest.Builder request = DeleteObjectRequest.builder() 96 + public void delete(String path) throws Exception {
  97 + client.removeObject(RemoveObjectArgs.builder()
90 .bucket(config.getBucket()) // bucket 必须传递 98 .bucket(config.getBucket()) // bucket 必须传递
91 - .key(path); // 相对路径作为 key  
92 - client.deleteObject(request.build()); 99 + .object(path) // 相对路径作为 key
  100 + .build());
93 } 101 }
94 102
95 @Override 103 @Override
96 - public byte[] getContent(String path) {  
97 - GetObjectRequest.Builder request = GetObjectRequest.builder() 104 + public byte[] getContent(String path) throws Exception {
  105 + GetObjectResponse response = client.getObject(GetObjectArgs.builder()
98 .bucket(config.getBucket()) // bucket 必须传递 106 .bucket(config.getBucket()) // bucket 必须传递
99 - .key(path); // 相对路径作为 key  
100 - return client.getObjectAsBytes(request.build()).asByteArray(); 107 + .object(path) // 相对路径作为 key
  108 + .build());
  109 + return IoUtil.readBytes(response);
101 } 110 }
102 111
103 } 112 }
yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/s3/S3FileClientConfig.java
@@ -18,14 +18,15 @@ import javax.validation.constraints.NotNull; @@ -18,14 +18,15 @@ import javax.validation.constraints.NotNull;
18 public class S3FileClientConfig implements FileClientConfig { 18 public class S3FileClientConfig implements FileClientConfig {
19 19
20 public static final String ENDPOINT_QINIU = "qiniucs.com"; 20 public static final String ENDPOINT_QINIU = "qiniucs.com";
  21 + public static final String ENDPOINT_ALIYUN = "aliyuncs.com";
21 22
22 /** 23 /**
23 * 节点地址 24 * 节点地址
24 * 1. MinIO: 25 * 1. MinIO:
25 * 2. 阿里云:https://help.aliyun.com/document_detail/31837.html 26 * 2. 阿里云:https://help.aliyun.com/document_detail/31837.html
26 - * 3. 腾讯云: 27 + * 3. 腾讯云:https://cloud.tencent.com/document/product/436/6224
27 * 4. 七牛云:https://developer.qiniu.com/kodo/4088/s3-access-domainname 28 * 4. 七牛云:https://developer.qiniu.com/kodo/4088/s3-access-domainname
28 - * 5. 华为云: 29 + * 5. 华为云:https://developer.huaweicloud.com/endpoint?OBS
29 */ 30 */
30 @NotNull(message = "endpoint 不能为空") 31 @NotNull(message = "endpoint 不能为空")
31 private String endpoint; 32 private String endpoint;
@@ -35,19 +36,15 @@ public class S3FileClientConfig implements FileClientConfig { @@ -35,19 +36,15 @@ public class S3FileClientConfig implements FileClientConfig {
35 * 2. 阿里云:https://help.aliyun.com/document_detail/31836.html 36 * 2. 阿里云:https://help.aliyun.com/document_detail/31836.html
36 * 3. 腾讯云:https://cloud.tencent.com/document/product/436/11142 37 * 3. 腾讯云:https://cloud.tencent.com/document/product/436/11142
37 * 4. 七牛云:https://developer.qiniu.com/kodo/8556/set-the-custom-source-domain-name 38 * 4. 七牛云:https://developer.qiniu.com/kodo/8556/set-the-custom-source-domain-name
38 - * 5. 华为云: 39 + * 5. 华为云:https://support.huaweicloud.com/usermanual-obs/obs_03_0032.html
39 */ 40 */
40 @URL(message = "domain 必须是 URL 格式") 41 @URL(message = "domain 必须是 URL 格式")
41 private String domain; 42 private String domain;
42 /** 43 /**
43 * 区域 44 * 区域
44 - * 1. MinIO:  
45 - * 2. 阿里云:https://help.aliyun.com/document_detail/31837.html  
46 - * 3. 腾讯云:  
47 - * 4. 七牛云:https://developer.qiniu.com/kodo/4088/s3-access-domainname  
48 - * 5. 华为云:  
49 */ 45 */
50 - @NotNull(message = "region 不能为空") 46 +// @NotNull(message = "region 不能为空")
  47 + @Deprecated
51 private String region; 48 private String region;
52 /** 49 /**
53 * 存储 Bucket 50 * 存储 Bucket
@@ -58,10 +55,10 @@ public class S3FileClientConfig implements FileClientConfig { @@ -58,10 +55,10 @@ public class S3FileClientConfig implements FileClientConfig {
58 /** 55 /**
59 * 访问 Key 56 * 访问 Key
60 * 1. MinIO: 57 * 1. MinIO:
61 - * 2. 阿里云: 58 + * 2. 阿里云:https://ram.console.aliyun.com/manage/ak
62 * 3. 腾讯云:https://console.cloud.tencent.com/cam/capi 59 * 3. 腾讯云:https://console.cloud.tencent.com/cam/capi
63 * 4. 七牛云:https://portal.qiniu.com/user/key 60 * 4. 七牛云:https://portal.qiniu.com/user/key
64 - * 5. 华为云: 61 + * 5. 华为云:https://support.huaweicloud.com/qs-obs/obs_qs_0005.html
65 */ 62 */
66 @NotNull(message = "accessKey 不能为空") 63 @NotNull(message = "accessKey 不能为空")
67 private String accessKey; 64 private String accessKey;
yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/s3/S3ModifyPathInterceptor.java deleted
1 -package cn.iocoder.yudao.framework.file.core.client.s3;  
2 -  
3 -import software.amazon.awssdk.core.interceptor.Context;  
4 -import software.amazon.awssdk.core.interceptor.ExecutionAttributes;  
5 -import software.amazon.awssdk.core.interceptor.ExecutionInterceptor;  
6 -import software.amazon.awssdk.http.SdkHttpRequest;  
7 -  
8 -/**  
9 - * S3 修改路径的拦截器,移除多余的 Bucket 前缀。  
10 - * 如果不使用该拦截器,希望上传的路径是 /tudou.jpg 时,会被添加成 /bucket/tudou.jpg  
11 - *  
12 - * @author 芋道源码  
13 - */  
14 -public class S3ModifyPathInterceptor implements ExecutionInterceptor {  
15 -  
16 - private final String bucket;  
17 -  
18 - public S3ModifyPathInterceptor(String bucket) {  
19 - this.bucket = "/" + bucket;  
20 - }  
21 -  
22 - @Override  
23 - public SdkHttpRequest modifyHttpRequest(Context.ModifyHttpRequest context, ExecutionAttributes executionAttributes) {  
24 - SdkHttpRequest request = context.httpRequest();  
25 - SdkHttpRequest.Builder rb = SdkHttpRequest.builder().protocol(request.protocol()).host(request.host()).port(request.port())  
26 - .method(request.method()).headers(request.headers()).rawQueryParameters(request.rawQueryParameters());  
27 - // 移除 path 前的 bucket 路径  
28 - if (request.encodedPath().startsWith(bucket)) {  
29 - rb.encodedPath(request.encodedPath().substring(bucket.length()));  
30 - } else {  
31 - rb.encodedPath(request.encodedPath());  
32 - }  
33 - return rb.build();  
34 - }  
35 -  
36 -}  
yudao-framework/yudao-spring-boot-starter-file/src/test/java/cn/iocoder/yudao/framework/file/core/client/ftp/FtpFileClientTest.java
@@ -3,11 +3,13 @@ package cn.iocoder.yudao.framework.file.core.client.ftp; @@ -3,11 +3,13 @@ package cn.iocoder.yudao.framework.file.core.client.ftp;
3 import cn.hutool.core.io.resource.ResourceUtil; 3 import cn.hutool.core.io.resource.ResourceUtil;
4 import cn.hutool.core.util.IdUtil; 4 import cn.hutool.core.util.IdUtil;
5 import cn.hutool.extra.ftp.FtpMode; 5 import cn.hutool.extra.ftp.FtpMode;
  6 +import org.junit.jupiter.api.Disabled;
6 import org.junit.jupiter.api.Test; 7 import org.junit.jupiter.api.Test;
7 8
8 public class FtpFileClientTest { 9 public class FtpFileClientTest {
9 10
10 @Test 11 @Test
  12 + @Disabled
11 public void test() { 13 public void test() {
12 // 创建客户端 14 // 创建客户端
13 FtpFileClientConfig config = new FtpFileClientConfig(); 15 FtpFileClientConfig config = new FtpFileClientConfig();
yudao-framework/yudao-spring-boot-starter-file/src/test/java/cn/iocoder/yudao/framework/file/core/client/local/LocalFileClientTest.java
@@ -2,11 +2,13 @@ package cn.iocoder.yudao.framework.file.core.client.local; @@ -2,11 +2,13 @@ package cn.iocoder.yudao.framework.file.core.client.local;
2 2
3 import cn.hutool.core.io.resource.ResourceUtil; 3 import cn.hutool.core.io.resource.ResourceUtil;
4 import cn.hutool.core.util.IdUtil; 4 import cn.hutool.core.util.IdUtil;
  5 +import org.junit.jupiter.api.Disabled;
5 import org.junit.jupiter.api.Test; 6 import org.junit.jupiter.api.Test;
6 7
7 public class LocalFileClientTest { 8 public class LocalFileClientTest {
8 9
9 @Test 10 @Test
  11 + @Disabled
10 public void test() { 12 public void test() {
11 // 创建客户端 13 // 创建客户端
12 LocalFileClientConfig config = new LocalFileClientConfig(); 14 LocalFileClientConfig config = new LocalFileClientConfig();
yudao-framework/yudao-spring-boot-starter-file/src/test/java/cn/iocoder/yudao/framework/file/core/client/s3/S3FileClientTest.java
@@ -2,7 +2,6 @@ package cn.iocoder.yudao.framework.file.core.client.s3; @@ -2,7 +2,6 @@ package cn.iocoder.yudao.framework.file.core.client.s3;
2 2
3 import cn.hutool.core.io.resource.ResourceUtil; 3 import cn.hutool.core.io.resource.ResourceUtil;
4 import cn.hutool.core.util.IdUtil; 4 import cn.hutool.core.util.IdUtil;
5 -import cn.hutool.core.util.StrUtil;  
6 import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils; 5 import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
7 import org.junit.jupiter.api.Disabled; 6 import org.junit.jupiter.api.Disabled;
8 import org.junit.jupiter.api.Test; 7 import org.junit.jupiter.api.Test;
@@ -12,8 +11,25 @@ import javax.validation.Validation; @@ -12,8 +11,25 @@ import javax.validation.Validation;
12 public class S3FileClientTest { 11 public class S3FileClientTest {
13 12
14 @Test 13 @Test
  14 + @Disabled // MinIO,如果要集成测试,可以注释本行
  15 + public void testMinIO() throws Exception {
  16 + S3FileClientConfig config = new S3FileClientConfig();
  17 + // 配置成你自己的
  18 + config.setAccessKey("admin");
  19 + config.setAccessSecret("password");
  20 + config.setBucket("yudaoyuanma");
  21 + config.setDomain(null);
  22 + // 默认 9000 endpoint
  23 + config.setEndpoint("http://127.0.0.1:9000");
  24 + config.setRegion("us-east-1");
  25 +
  26 + // 执行上传
  27 + testExecuteUpload(config);
  28 + }
  29 +
  30 + @Test
15 @Disabled // 阿里云 OSS,如果要集成测试,可以注释本行 31 @Disabled // 阿里云 OSS,如果要集成测试,可以注释本行
16 - public void testAliyun() { 32 + public void testAliyun() throws Exception {
17 S3FileClientConfig config = new S3FileClientConfig(); 33 S3FileClientConfig config = new S3FileClientConfig();
18 // 配置成你自己的 34 // 配置成你自己的
19 config.setAccessKey(System.getenv("ALIYUN_ACCESS_KEY")); 35 config.setAccessKey(System.getenv("ALIYUN_ACCESS_KEY"));
@@ -29,7 +45,7 @@ public class S3FileClientTest { @@ -29,7 +45,7 @@ public class S3FileClientTest {
29 45
30 @Test 46 @Test
31 @Disabled // 腾讯云 COS,如果要集成测试,可以注释本行 47 @Disabled // 腾讯云 COS,如果要集成测试,可以注释本行
32 - public void testQCloud() { 48 + public void testQCloud() throws Exception {
33 S3FileClientConfig config = new S3FileClientConfig(); 49 S3FileClientConfig config = new S3FileClientConfig();
34 // 配置成你自己的 50 // 配置成你自己的
35 config.setAccessKey(System.getenv("QCLOUD_ACCESS_KEY")); 51 config.setAccessKey(System.getenv("QCLOUD_ACCESS_KEY"));
@@ -38,7 +54,6 @@ public class S3FileClientTest { @@ -38,7 +54,6 @@ public class S3FileClientTest {
38 config.setDomain(null); // 如果有自定义域名,则可以设置。http://tengxun-oss.iocoder.cn 54 config.setDomain(null); // 如果有自定义域名,则可以设置。http://tengxun-oss.iocoder.cn
39 // 默认上海的 endpoint 55 // 默认上海的 endpoint
40 config.setEndpoint("cos.ap-shanghai.myqcloud.com"); 56 config.setEndpoint("cos.ap-shanghai.myqcloud.com");
41 - config.setRegion("ap-shanghai");  
42 57
43 // 执行上传 58 // 执行上传
44 testExecuteUpload(config); 59 testExecuteUpload(config);
@@ -46,7 +61,7 @@ public class S3FileClientTest { @@ -46,7 +61,7 @@ public class S3FileClientTest {
46 61
47 @Test 62 @Test
48 @Disabled // 七牛云存储,如果要集成测试,可以注释本行 63 @Disabled // 七牛云存储,如果要集成测试,可以注释本行
49 - public void testQiniu() { 64 + public void testQiniu() throws Exception {
50 S3FileClientConfig config = new S3FileClientConfig(); 65 S3FileClientConfig config = new S3FileClientConfig();
51 // 配置成你自己的 66 // 配置成你自己的
52 // config.setAccessKey(System.getenv("QINIU_ACCESS_KEY")); 67 // config.setAccessKey(System.getenv("QINIU_ACCESS_KEY"));
@@ -62,11 +77,24 @@ public class S3FileClientTest { @@ -62,11 +77,24 @@ public class S3FileClientTest {
62 testExecuteUpload(config); 77 testExecuteUpload(config);
63 } 78 }
64 79
65 - private void testExecuteUpload(S3FileClientConfig config) {  
66 - // 补全配置  
67 - if (config.getRegion() == null) {  
68 - config.setRegion(StrUtil.subBefore(config.getEndpoint(), '.', false));  
69 - } 80 + @Test
  81 + @Disabled // 华为云存储,如果要集成测试,可以注释本行
  82 + public void testHuaweiCloud() throws Exception {
  83 + S3FileClientConfig config = new S3FileClientConfig();
  84 + // 配置成你自己的
  85 +// config.setAccessKey(System.getenv("HUAWEI_CLOUD_ACCESS_KEY"));
  86 +// config.setAccessSecret(System.getenv("HUAWEI_CLOUD_SECRET_KEY"));
  87 + config.setBucket("yudao");
  88 + config.setDomain(null); // 如果有自定义域名,则可以设置。
  89 + // 默认上海的 endpoint
  90 + config.setEndpoint("obs.cn-east-3.myhuaweicloud.com");
  91 +
  92 + // 执行上传
  93 + testExecuteUpload(config);
  94 + }
  95 +
  96 + private void testExecuteUpload(S3FileClientConfig config) throws Exception {
  97 + // 校验配置
70 ValidationUtils.validate(Validation.buildDefaultValidatorFactory().getValidator(), config); 98 ValidationUtils.validate(Validation.buildDefaultValidatorFactory().getValidator(), config);
71 // 创建 Client 99 // 创建 Client
72 S3FileClient client = new S3FileClient(0L, config); 100 S3FileClient client = new S3FileClient(0L, config);
@@ -77,9 +105,9 @@ public class S3FileClientTest { @@ -77,9 +105,9 @@ public class S3FileClientTest {
77 String fullPath = client.upload(content, path); 105 String fullPath = client.upload(content, path);
78 System.out.println("访问地址:" + fullPath); 106 System.out.println("访问地址:" + fullPath);
79 // 读取文件 107 // 读取文件
80 - if (false) { 108 + if (true) {
81 byte[] bytes = client.getContent(path); 109 byte[] bytes = client.getContent(path);
82 - System.out.println("文件内容:" + bytes); 110 + System.out.println("文件内容:" + bytes.length);
83 } 111 }
84 // 删除文件 112 // 删除文件
85 if (false) { 113 if (false) {
yudao-framework/yudao-spring-boot-starter-file/src/test/java/cn/iocoder/yudao/framework/file/core/client/sftp/SftpFileClientTest.java
@@ -2,11 +2,13 @@ package cn.iocoder.yudao.framework.file.core.client.sftp; @@ -2,11 +2,13 @@ package cn.iocoder.yudao.framework.file.core.client.sftp;
2 2
3 import cn.hutool.core.io.resource.ResourceUtil; 3 import cn.hutool.core.io.resource.ResourceUtil;
4 import cn.hutool.core.util.IdUtil; 4 import cn.hutool.core.util.IdUtil;
  5 +import org.junit.jupiter.api.Disabled;
5 import org.junit.jupiter.api.Test; 6 import org.junit.jupiter.api.Test;
6 7
7 public class SftpFileClientTest { 8 public class SftpFileClientTest {
8 9
9 @Test 10 @Test
  11 + @Disabled
10 public void test() { 12 public void test() {
11 // 创建客户端 13 // 创建客户端
12 SftpFileClientConfig config = new SftpFileClientConfig(); 14 SftpFileClientConfig config = new SftpFileClientConfig();