Commit 34a7399a65b5cb011a5df793c16a2cc911378bac
1 parent
62f7d349
使用 minio client 替代 amazon 客户端,进行 S3 的对接
Showing
10 changed files
with
116 additions
and
110 deletions
yudao-dependencies/pom.xml
| ... | ... | @@ -56,7 +56,7 @@ |
| 56 | 56 | <commons-net.version>3.8.0</commons-net.version> |
| 57 | 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 | 60 | <aliyun-java-sdk-core.version>4.5.25</aliyun-java-sdk-core.version> |
| 61 | 61 | <aliyun-java-sdk-dysmsapi.version>2.1.0</aliyun-java-sdk-dysmsapi.version> |
| 62 | 62 | <yunpian-java-sdk.version>1.2.7</yunpian-java-sdk.version> |
| ... | ... | @@ -514,9 +514,9 @@ |
| 514 | 514 | <version>${revision}</version> |
| 515 | 515 | </dependency> |
| 516 | 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 | 520 | </dependency> |
| 521 | 521 | |
| 522 | 522 | <!-- SMS SDK begin --> | ... | ... |
yudao-framework/yudao-spring-boot-starter-file/pom.xml
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 | 20 | * @param content 文件流 |
| 21 | 21 | * @param path 相对路径 |
| 22 | 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 | 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 | 38 | * @param path 相对路径 |
| 37 | 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 | 1 | package cn.iocoder.yudao.framework.file.core.client.s3; |
| 2 | 2 | |
| 3 | +import cn.hutool.core.io.IoUtil; | |
| 3 | 4 | import cn.hutool.core.util.StrUtil; |
| 5 | +import cn.hutool.http.HttpUtil; | |
| 4 | 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 | 14 | * 基于 S3 协议的文件客户端,实现 MinIO、阿里云、腾讯云、七牛云、华为云等云服务 |
| ... | ... | @@ -24,7 +19,7 @@ import static cn.iocoder.yudao.framework.file.core.client.s3.S3FileClientConfig. |
| 24 | 19 | */ |
| 25 | 20 | public class S3FileClient extends AbstractFileClient<S3FileClientConfig> { |
| 26 | 21 | |
| 27 | - private S3Client client; | |
| 22 | + private MinioClient client; | |
| 28 | 23 | |
| 29 | 24 | public S3FileClient(Long id, S3FileClientConfig config) { |
| 30 | 25 | super(id, config); |
| ... | ... | @@ -34,34 +29,27 @@ public class S3FileClient extends AbstractFileClient<S3FileClientConfig> { |
| 34 | 29 | protected void doInit() { |
| 35 | 30 | // 补全 domain |
| 36 | 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 | 39 | .build(); |
| 49 | 40 | } |
| 50 | 41 | |
| 51 | 42 | /** |
| 52 | - * 基于 endpoint 构建调用云服务的 URI 地址 | |
| 43 | + * 基于 endpoint 构建调用云服务的 URL 地址 | |
| 53 | 44 | * |
| 54 | 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<S3FileClientConfig> { |
| 69 | 57 | * |
| 70 | 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 | 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 | 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 | 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 | 92 | return config.getDomain() + "/" + path; |
| 85 | 93 | } |
| 86 | 94 | |
| 87 | 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 | 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 | 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 | 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 | 18 | public class S3FileClientConfig implements FileClientConfig { |
| 19 | 19 | |
| 20 | 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 | 25 | * 1. MinIO: |
| 25 | 26 | * 2. 阿里云:https://help.aliyun.com/document_detail/31837.html |
| 26 | - * 3. 腾讯云: | |
| 27 | + * 3. 腾讯云:https://cloud.tencent.com/document/product/436/6224 | |
| 27 | 28 | * 4. 七牛云:https://developer.qiniu.com/kodo/4088/s3-access-domainname |
| 28 | - * 5. 华为云: | |
| 29 | + * 5. 华为云:https://developer.huaweicloud.com/endpoint?OBS | |
| 29 | 30 | */ |
| 30 | 31 | @NotNull(message = "endpoint 不能为空") |
| 31 | 32 | private String endpoint; |
| ... | ... | @@ -35,19 +36,15 @@ public class S3FileClientConfig implements FileClientConfig { |
| 35 | 36 | * 2. 阿里云:https://help.aliyun.com/document_detail/31836.html |
| 36 | 37 | * 3. 腾讯云:https://cloud.tencent.com/document/product/436/11142 |
| 37 | 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 | 41 | @URL(message = "domain 必须是 URL 格式") |
| 41 | 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 | 48 | private String region; |
| 52 | 49 | /** |
| 53 | 50 | * 存储 Bucket |
| ... | ... | @@ -58,10 +55,10 @@ public class S3FileClientConfig implements FileClientConfig { |
| 58 | 55 | /** |
| 59 | 56 | * 访问 Key |
| 60 | 57 | * 1. MinIO: |
| 61 | - * 2. 阿里云: | |
| 58 | + * 2. 阿里云:https://ram.console.aliyun.com/manage/ak | |
| 62 | 59 | * 3. 腾讯云:https://console.cloud.tencent.com/cam/capi |
| 63 | 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 | 63 | @NotNull(message = "accessKey 不能为空") |
| 67 | 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 | 3 | import cn.hutool.core.io.resource.ResourceUtil; |
| 4 | 4 | import cn.hutool.core.util.IdUtil; |
| 5 | 5 | import cn.hutool.extra.ftp.FtpMode; |
| 6 | +import org.junit.jupiter.api.Disabled; | |
| 6 | 7 | import org.junit.jupiter.api.Test; |
| 7 | 8 | |
| 8 | 9 | public class FtpFileClientTest { |
| 9 | 10 | |
| 10 | 11 | @Test |
| 12 | + @Disabled | |
| 11 | 13 | public void test() { |
| 12 | 14 | // 创建客户端 |
| 13 | 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 | 2 | |
| 3 | 3 | import cn.hutool.core.io.resource.ResourceUtil; |
| 4 | 4 | import cn.hutool.core.util.IdUtil; |
| 5 | +import org.junit.jupiter.api.Disabled; | |
| 5 | 6 | import org.junit.jupiter.api.Test; |
| 6 | 7 | |
| 7 | 8 | public class LocalFileClientTest { |
| 8 | 9 | |
| 9 | 10 | @Test |
| 11 | + @Disabled | |
| 10 | 12 | public void test() { |
| 11 | 13 | // 创建客户端 |
| 12 | 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 | 2 | |
| 3 | 3 | import cn.hutool.core.io.resource.ResourceUtil; |
| 4 | 4 | import cn.hutool.core.util.IdUtil; |
| 5 | -import cn.hutool.core.util.StrUtil; | |
| 6 | 5 | import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils; |
| 7 | 6 | import org.junit.jupiter.api.Disabled; |
| 8 | 7 | import org.junit.jupiter.api.Test; |
| ... | ... | @@ -12,8 +11,25 @@ import javax.validation.Validation; |
| 12 | 11 | public class S3FileClientTest { |
| 13 | 12 | |
| 14 | 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 | 31 | @Disabled // 阿里云 OSS,如果要集成测试,可以注释本行 |
| 16 | - public void testAliyun() { | |
| 32 | + public void testAliyun() throws Exception { | |
| 17 | 33 | S3FileClientConfig config = new S3FileClientConfig(); |
| 18 | 34 | // 配置成你自己的 |
| 19 | 35 | config.setAccessKey(System.getenv("ALIYUN_ACCESS_KEY")); |
| ... | ... | @@ -29,7 +45,7 @@ public class S3FileClientTest { |
| 29 | 45 | |
| 30 | 46 | @Test |
| 31 | 47 | @Disabled // 腾讯云 COS,如果要集成测试,可以注释本行 |
| 32 | - public void testQCloud() { | |
| 48 | + public void testQCloud() throws Exception { | |
| 33 | 49 | S3FileClientConfig config = new S3FileClientConfig(); |
| 34 | 50 | // 配置成你自己的 |
| 35 | 51 | config.setAccessKey(System.getenv("QCLOUD_ACCESS_KEY")); |
| ... | ... | @@ -38,7 +54,6 @@ public class S3FileClientTest { |
| 38 | 54 | config.setDomain(null); // 如果有自定义域名,则可以设置。http://tengxun-oss.iocoder.cn |
| 39 | 55 | // 默认上海的 endpoint |
| 40 | 56 | config.setEndpoint("cos.ap-shanghai.myqcloud.com"); |
| 41 | - config.setRegion("ap-shanghai"); | |
| 42 | 57 | |
| 43 | 58 | // 执行上传 |
| 44 | 59 | testExecuteUpload(config); |
| ... | ... | @@ -46,7 +61,7 @@ public class S3FileClientTest { |
| 46 | 61 | |
| 47 | 62 | @Test |
| 48 | 63 | @Disabled // 七牛云存储,如果要集成测试,可以注释本行 |
| 49 | - public void testQiniu() { | |
| 64 | + public void testQiniu() throws Exception { | |
| 50 | 65 | S3FileClientConfig config = new S3FileClientConfig(); |
| 51 | 66 | // 配置成你自己的 |
| 52 | 67 | // config.setAccessKey(System.getenv("QINIU_ACCESS_KEY")); |
| ... | ... | @@ -62,11 +77,24 @@ public class S3FileClientTest { |
| 62 | 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 | 98 | ValidationUtils.validate(Validation.buildDefaultValidatorFactory().getValidator(), config); |
| 71 | 99 | // 创建 Client |
| 72 | 100 | S3FileClient client = new S3FileClient(0L, config); |
| ... | ... | @@ -77,9 +105,9 @@ public class S3FileClientTest { |
| 77 | 105 | String fullPath = client.upload(content, path); |
| 78 | 106 | System.out.println("访问地址:" + fullPath); |
| 79 | 107 | // 读取文件 |
| 80 | - if (false) { | |
| 108 | + if (true) { | |
| 81 | 109 | byte[] bytes = client.getContent(path); |
| 82 | - System.out.println("文件内容:" + bytes); | |
| 110 | + System.out.println("文件内容:" + bytes.length); | |
| 83 | 111 | } |
| 84 | 112 | // 删除文件 |
| 85 | 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 | 2 | |
| 3 | 3 | import cn.hutool.core.io.resource.ResourceUtil; |
| 4 | 4 | import cn.hutool.core.util.IdUtil; |
| 5 | +import org.junit.jupiter.api.Disabled; | |
| 5 | 6 | import org.junit.jupiter.api.Test; |
| 6 | 7 | |
| 7 | 8 | public class SftpFileClientTest { |
| 8 | 9 | |
| 9 | 10 | @Test |
| 11 | + @Disabled | |
| 10 | 12 | public void test() { |
| 11 | 13 | // 创建客户端 |
| 12 | 14 | SftpFileClientConfig config = new SftpFileClientConfig(); | ... | ... |