|
@@ -4,10 +4,17 @@ import cn.hutool.core.io.IoUtil;
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
import cn.hutool.http.HttpUtil;
|
|
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.AbstractFileClient;
|
|
|
-import io.minio.*;
|
|
|
-import io.minio.http.Method;
|
|
|
+import com.amazonaws.HttpMethod;
|
|
|
+import com.amazonaws.auth.AWSStaticCredentialsProvider;
|
|
|
+import com.amazonaws.auth.BasicAWSCredentials;
|
|
|
+import com.amazonaws.client.builder.AwsClientBuilder;
|
|
|
+import com.amazonaws.services.s3.*;
|
|
|
+import com.amazonaws.services.s3.model.ObjectMetadata;
|
|
|
+import com.amazonaws.services.s3.model.S3Object;
|
|
|
+
|
|
|
|
|
|
import java.io.ByteArrayInputStream;
|
|
|
+import java.util.Date;
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
|
|
@@ -19,7 +26,7 @@ import java.util.concurrent.TimeUnit;
|
|
|
*/
|
|
|
public class S3FileClient extends AbstractFileClient<S3FileClientConfig> {
|
|
|
|
|
|
- private MinioClient client;
|
|
|
+ private AmazonS3Client client;
|
|
|
|
|
|
public S3FileClient(Long id, S3FileClientConfig config) {
|
|
|
super(id, config);
|
|
@@ -32,26 +39,57 @@ public class S3FileClient extends AbstractFileClient<S3FileClientConfig> {
|
|
|
config.setDomain(buildDomain());
|
|
|
}
|
|
|
|
|
|
- client = MinioClient.builder()
|
|
|
- .endpoint(buildEndpointURL())
|
|
|
- .region(buildRegion())
|
|
|
- .credentials(config.getAccessKey(), config.getAccessSecret())
|
|
|
+
|
|
|
+ client = (AmazonS3Client)AmazonS3ClientBuilder.standard()
|
|
|
+ .withCredentials(buildCredentials())
|
|
|
+ .withEndpointConfiguration(buildEndpointConfiguration())
|
|
|
.build();
|
|
|
- enableVirtualStyleEndpoint();
|
|
|
- }
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
- * 基于 endpoint 构建调用云服务的 URL 地址
|
|
|
+ * 基于config秘钥 构建 S3 客户端的认证信息
|
|
|
*
|
|
|
- * @return URI 地址
|
|
|
+ * @return S3 客户端的认证信息
|
|
|
*/
|
|
|
- private String buildEndpointURL() {
|
|
|
-
|
|
|
- if (HttpUtil.isHttp(config.getEndpoint()) || HttpUtil.isHttps(config.getEndpoint())) {
|
|
|
- return config.getEndpoint();
|
|
|
- }
|
|
|
- return StrUtil.format("https://{}", config.getEndpoint());
|
|
|
+ private AWSStaticCredentialsProvider buildCredentials() {
|
|
|
+ AWSStaticCredentialsProvider awsStaticCredentialsProvider = new AWSStaticCredentialsProvider(
|
|
|
+ new BasicAWSCredentials(config.getAccessKey(), config.getAccessSecret()));
|
|
|
+ return awsStaticCredentialsProvider;
|
|
|
}
|
|
|
+
|
|
|
+ * 构建 S3 客户端的 Endpoint 配置包括 region、endpoint
|
|
|
+ *
|
|
|
+ * @return S3 客户端的 EndpointConfiguration 配置
|
|
|
+ */
|
|
|
+ private AwsClientBuilder.EndpointConfiguration buildEndpointConfiguration() {
|
|
|
+ AwsClientBuilder.EndpointConfiguration endpointConfiguration = new AwsClientBuilder.EndpointConfiguration(
|
|
|
+ config.getEndpoint(), buildRegion());
|
|
|
+ return endpointConfiguration;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
|
|
|
* 基于 bucket + endpoint 构建访问的 Domain 地址
|
|
@@ -88,55 +126,69 @@ public class S3FileClient extends AbstractFileClient<S3FileClientConfig> {
|
|
|
}
|
|
|
|
|
|
|
|
|
- * 开启 VirtualStyle 模式
|
|
|
+ * 开启 PathStyle模式
|
|
|
*/
|
|
|
private void enableVirtualStyleEndpoint() {
|
|
|
- if (StrUtil.containsAny(config.getEndpoint(),
|
|
|
- S3FileClientConfig.ENDPOINT_TENCENT,
|
|
|
- S3FileClientConfig.ENDPOINT_VOLCES)) {
|
|
|
- client.enableVirtualStyleEndpoint();
|
|
|
- }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ S3ClientOptions clientOptions = S3ClientOptions.builder()
|
|
|
+ .setPathStyleAccess(true)
|
|
|
+ .build();
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public String upload(byte[] content, String path, String type) throws Exception {
|
|
|
|
|
|
- client.putObject(PutObjectArgs.builder()
|
|
|
- .bucket(config.getBucket())
|
|
|
- .contentType(type)
|
|
|
- .object(path)
|
|
|
- .stream(new ByteArrayInputStream(content), content.length, -1)
|
|
|
- .build());
|
|
|
+ ObjectMetadata objectMetadata = new ObjectMetadata();
|
|
|
+ objectMetadata.setContentType(type);
|
|
|
+
|
|
|
+ client.putObject(config.getBucket(), path, new ByteArrayInputStream(content), objectMetadata);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
return config.getDomain() + "/" + path;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public void delete(String path) throws Exception {
|
|
|
- client.removeObject(RemoveObjectArgs.builder()
|
|
|
- .bucket(config.getBucket())
|
|
|
- .object(path)
|
|
|
- .build());
|
|
|
+
|
|
|
+ client.deleteObject(config.getBucket(), path);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public byte[] getContent(String path) throws Exception {
|
|
|
- GetObjectResponse response = client.getObject(GetObjectArgs.builder()
|
|
|
- .bucket(config.getBucket())
|
|
|
- .object(path)
|
|
|
- .build());
|
|
|
- return IoUtil.readBytes(response);
|
|
|
+ S3Object tempS3Object = client.getObject(config.getBucket(), path);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ return IoUtil.readBytes(tempS3Object.getObjectContent());
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public FilePresignedUrlRespDTO getPresignedObjectUrl(String path) throws Exception {
|
|
|
- String uploadUrl = client.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
|
|
|
- .method(Method.PUT)
|
|
|
- .bucket(config.getBucket())
|
|
|
- .object(path)
|
|
|
- .expiry(10, TimeUnit.MINUTES)
|
|
|
- .build()
|
|
|
- );
|
|
|
+
|
|
|
+ Date expiration = new Date(System.currentTimeMillis() + TimeUnit.HOURS.toMillis(24));
|
|
|
+ String uploadUrl = String.valueOf(client.generatePresignedUrl(config.getBucket(), path,expiration , HttpMethod.PUT));
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
return new FilePresignedUrlRespDTO(uploadUrl, config.getDomain() + "/" + path);
|
|
|
}
|
|
|
|