|
@@ -1,267 +0,0 @@
|
|
|
-package com.als.common.oss.core;
|
|
|
-
|
|
|
-import cn.hutool.core.io.IoUtil;
|
|
|
-import cn.hutool.core.util.IdUtil;
|
|
|
-import com.amazonaws.ClientConfiguration;
|
|
|
-import com.amazonaws.HttpMethod;
|
|
|
-import com.amazonaws.Protocol;
|
|
|
-import com.amazonaws.auth.AWSCredentials;
|
|
|
-import com.amazonaws.auth.AWSCredentialsProvider;
|
|
|
-import com.amazonaws.auth.AWSStaticCredentialsProvider;
|
|
|
-import com.amazonaws.auth.BasicAWSCredentials;
|
|
|
-import com.amazonaws.client.builder.AwsClientBuilder;
|
|
|
-import com.amazonaws.services.s3.AmazonS3;
|
|
|
-import com.amazonaws.services.s3.AmazonS3Client;
|
|
|
-import com.amazonaws.services.s3.AmazonS3ClientBuilder;
|
|
|
-import com.amazonaws.services.s3.model.CreateBucketRequest;
|
|
|
-import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest;
|
|
|
-import com.amazonaws.services.s3.model.ObjectMetadata;
|
|
|
-import com.amazonaws.services.s3.model.PutObjectRequest;
|
|
|
-import com.amazonaws.services.s3.model.S3Object;
|
|
|
-import com.als.common.core.utils.DateUtils;
|
|
|
-import com.als.common.core.utils.StringUtils;
|
|
|
-import com.als.common.oss.constant.OssConstant;
|
|
|
-import com.als.common.oss.entity.UploadResult;
|
|
|
-import com.als.common.oss.enumd.AccessPolicyType;
|
|
|
-import com.als.common.oss.enumd.PolicyType;
|
|
|
-import com.als.common.oss.exception.OssException;
|
|
|
-import com.als.common.oss.properties.OssProperties;
|
|
|
-
|
|
|
-import java.io.ByteArrayInputStream;
|
|
|
-import java.io.File;
|
|
|
-import java.io.InputStream;
|
|
|
-import java.net.URL;
|
|
|
-import java.util.Date;
|
|
|
-
|
|
|
-/**
|
|
|
- * S3 存储协议 所有兼容S3协议的云厂商均支持
|
|
|
- * 阿里云 腾讯云 七牛云 minio
|
|
|
- *
|
|
|
- * @author km
|
|
|
- */
|
|
|
-public class OssClient {
|
|
|
-
|
|
|
- private final String configKey;
|
|
|
-
|
|
|
- private final OssProperties properties;
|
|
|
-
|
|
|
- private final AmazonS3 client;
|
|
|
-
|
|
|
- public OssClient(String configKey, OssProperties ossProperties) {
|
|
|
- this.configKey = configKey;
|
|
|
- this.properties = ossProperties;
|
|
|
- try {
|
|
|
- AwsClientBuilder.EndpointConfiguration endpointConfig =
|
|
|
- new AwsClientBuilder.EndpointConfiguration(properties.getEndpoint(), properties.getRegion());
|
|
|
-
|
|
|
- AWSCredentials credentials = new BasicAWSCredentials(properties.getAccessKey(), properties.getSecretKey());
|
|
|
- AWSCredentialsProvider credentialsProvider = new AWSStaticCredentialsProvider(credentials);
|
|
|
- ClientConfiguration clientConfig = new ClientConfiguration();
|
|
|
- if (OssConstant.IS_HTTPS.equals(properties.getIsHttps())) {
|
|
|
- clientConfig.setProtocol(Protocol.HTTPS);
|
|
|
- } else {
|
|
|
- clientConfig.setProtocol(Protocol.HTTP);
|
|
|
- }
|
|
|
- AmazonS3ClientBuilder build = AmazonS3Client.builder()
|
|
|
- .withEndpointConfiguration(endpointConfig)
|
|
|
- .withClientConfiguration(clientConfig)
|
|
|
- .withCredentials(credentialsProvider)
|
|
|
- .disableChunkedEncoding();
|
|
|
- if (!StringUtils.containsAny(properties.getEndpoint(), OssConstant.CLOUD_SERVICE)) {
|
|
|
- // minio 使用https限制使用域名访问 需要此配置 站点填域名
|
|
|
- build.enablePathStyleAccess();
|
|
|
- }
|
|
|
- this.client = build.build();
|
|
|
-
|
|
|
- createBucket();
|
|
|
- } catch (Exception e) {
|
|
|
- if (e instanceof OssException) {
|
|
|
- throw e;
|
|
|
- }
|
|
|
- throw new OssException("配置错误! 请检查系统配置:[" + e.getMessage() + "]");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private static String getPolicy(String bucketName, PolicyType policyType) {
|
|
|
- StringBuilder builder = new StringBuilder();
|
|
|
- builder.append("{\n\"Statement\": [\n{\n\"Action\": [\n");
|
|
|
- builder.append(switch (policyType) {
|
|
|
- case WRITE -> "\"s3:GetBucketLocation\",\n\"s3:ListBucketMultipartUploads\"\n";
|
|
|
- case READ_WRITE -> "\"s3:GetBucketLocation\",\n\"s3:ListBucket\",\n\"s3:ListBucketMultipartUploads\"\n";
|
|
|
- default -> "\"s3:GetBucketLocation\"\n";
|
|
|
- });
|
|
|
- builder.append("],\n\"Effect\": \"Allow\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::");
|
|
|
- builder.append(bucketName);
|
|
|
- builder.append("\"\n},\n");
|
|
|
- if (policyType == PolicyType.READ) {
|
|
|
- builder.append("{\n\"Action\": [\n\"s3:ListBucket\"\n],\n\"Effect\": \"Deny\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::");
|
|
|
- builder.append(bucketName);
|
|
|
- builder.append("\"\n},\n");
|
|
|
- }
|
|
|
- builder.append("{\n\"Action\": ");
|
|
|
- builder.append(switch (policyType) {
|
|
|
- case WRITE ->
|
|
|
- "[\n\"s3:AbortMultipartUpload\",\n\"s3:DeleteObject\",\n\"s3:ListMultipartUploadParts\",\n\"s3:PutObject\"\n],\n";
|
|
|
- case READ_WRITE ->
|
|
|
- "[\n\"s3:AbortMultipartUpload\",\n\"s3:DeleteObject\",\n\"s3:GetObject\",\n\"s3:ListMultipartUploadParts\",\n\"s3:PutObject\"\n],\n";
|
|
|
- default -> "\"s3:GetObject\",\n";
|
|
|
- });
|
|
|
- builder.append("\"Effect\": \"Allow\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::");
|
|
|
- builder.append(bucketName);
|
|
|
- builder.append("/*\"\n}\n],\n\"Version\": \"2012-10-17\"\n}\n");
|
|
|
- return builder.toString();
|
|
|
- }
|
|
|
-
|
|
|
- public void createBucket() {
|
|
|
- try {
|
|
|
- String bucketName = properties.getBucketName();
|
|
|
- if (client.doesBucketExistV2(bucketName)) {
|
|
|
- return;
|
|
|
- }
|
|
|
- CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
|
|
|
- AccessPolicyType accessPolicy = getAccessPolicy();
|
|
|
- createBucketRequest.setCannedAcl(accessPolicy.getAcl());
|
|
|
- client.createBucket(createBucketRequest);
|
|
|
- client.setBucketPolicy(bucketName, getPolicy(bucketName, accessPolicy.getPolicyType()));
|
|
|
- } catch (Exception e) {
|
|
|
- throw new OssException("创建Bucket失败, 请核对配置信息:[" + e.getMessage() + "]");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public UploadResult upload(byte[] data, String path, String contentType) {
|
|
|
- return upload(new ByteArrayInputStream(data), path, contentType);
|
|
|
- }
|
|
|
-
|
|
|
- public UploadResult upload(InputStream inputStream, String path, String contentType) {
|
|
|
- if (!(inputStream instanceof ByteArrayInputStream)) {
|
|
|
- inputStream = new ByteArrayInputStream(IoUtil.readBytes(inputStream));
|
|
|
- }
|
|
|
- try {
|
|
|
- ObjectMetadata metadata = new ObjectMetadata();
|
|
|
- metadata.setContentType(contentType);
|
|
|
- metadata.setContentLength(inputStream.available());
|
|
|
- PutObjectRequest putObjectRequest = new PutObjectRequest(properties.getBucketName(), path, inputStream, metadata);
|
|
|
- // 设置上传对象的 Acl 为公共读
|
|
|
- putObjectRequest.setCannedAcl(getAccessPolicy().getAcl());
|
|
|
- client.putObject(putObjectRequest);
|
|
|
- } catch (Exception e) {
|
|
|
- throw new OssException("上传文件失败,请检查配置信息:[" + e.getMessage() + "]");
|
|
|
- }
|
|
|
- return UploadResult.builder().url(getUrl() + "/" + path).filename(path).build();
|
|
|
- }
|
|
|
-
|
|
|
- public UploadResult upload(File file, String path) {
|
|
|
- try {
|
|
|
- PutObjectRequest putObjectRequest = new PutObjectRequest(properties.getBucketName(), path, file);
|
|
|
- // 设置上传对象的 Acl 为公共读
|
|
|
- putObjectRequest.setCannedAcl(getAccessPolicy().getAcl());
|
|
|
- client.putObject(putObjectRequest);
|
|
|
- } catch (Exception e) {
|
|
|
- throw new OssException("上传文件失败,请检查配置信息:[" + e.getMessage() + "]");
|
|
|
- }
|
|
|
- return UploadResult.builder().url(getUrl() + "/" + path).filename(path).build();
|
|
|
- }
|
|
|
-
|
|
|
- public void delete(String path) {
|
|
|
- path = path.replace(getUrl() + "/", "");
|
|
|
- try {
|
|
|
- client.deleteObject(properties.getBucketName(), path);
|
|
|
- } catch (Exception e) {
|
|
|
- throw new OssException("删除文件失败,请检查配置信息:[" + e.getMessage() + "]");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public UploadResult uploadSuffix(byte[] data, String suffix, String contentType) {
|
|
|
- return upload(data, getPath(properties.getPrefix(), suffix), contentType);
|
|
|
- }
|
|
|
-
|
|
|
- public UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType) {
|
|
|
- return upload(inputStream, getPath(properties.getPrefix(), suffix), contentType);
|
|
|
- }
|
|
|
-
|
|
|
- public UploadResult uploadSuffix(File file, String suffix) {
|
|
|
- return upload(file, getPath(properties.getPrefix(), suffix));
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取文件元数据
|
|
|
- *
|
|
|
- * @param path 完整文件路径
|
|
|
- */
|
|
|
- public ObjectMetadata getObjectMetadata(String path) {
|
|
|
- path = path.replace(getUrl() + "/", "");
|
|
|
- S3Object object = client.getObject(properties.getBucketName(), path);
|
|
|
- return object.getObjectMetadata();
|
|
|
- }
|
|
|
-
|
|
|
- public InputStream getObjectContent(String path) {
|
|
|
- path = path.replace(getUrl() + "/", "");
|
|
|
- S3Object object = client.getObject(properties.getBucketName(), path);
|
|
|
- return object.getObjectContent();
|
|
|
- }
|
|
|
-
|
|
|
- public String getUrl() {
|
|
|
- String domain = properties.getDomain();
|
|
|
- String endpoint = properties.getEndpoint();
|
|
|
- String header = OssConstant.IS_HTTPS.equals(properties.getIsHttps()) ? "https://" : "http://";
|
|
|
- // 云服务商直接返回
|
|
|
- if (StringUtils.containsAny(endpoint, OssConstant.CLOUD_SERVICE)) {
|
|
|
- if (StringUtils.isNotBlank(domain)) {
|
|
|
- return header + domain;
|
|
|
- }
|
|
|
- return header + properties.getBucketName() + "." + endpoint;
|
|
|
- }
|
|
|
- // minio 单独处理
|
|
|
- if (StringUtils.isNotBlank(domain)) {
|
|
|
- return header + domain + "/" + properties.getBucketName();
|
|
|
- }
|
|
|
- return header + endpoint + "/" + properties.getBucketName();
|
|
|
- }
|
|
|
-
|
|
|
- public String getPath(String prefix, String suffix) {
|
|
|
- // 生成uuid
|
|
|
- String uuid = IdUtil.fastSimpleUUID();
|
|
|
- // 文件路径
|
|
|
- String path = DateUtils.datePath() + "/" + uuid;
|
|
|
- if (StringUtils.isNotBlank(prefix)) {
|
|
|
- path = prefix + "/" + path;
|
|
|
- }
|
|
|
- return path + suffix;
|
|
|
- }
|
|
|
-
|
|
|
- public String getConfigKey() {
|
|
|
- return configKey;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取私有URL链接
|
|
|
- *
|
|
|
- * @param objectKey 对象KEY
|
|
|
- * @param second 授权时间
|
|
|
- */
|
|
|
- public String getPrivateUrl(String objectKey, Integer second) {
|
|
|
- GeneratePresignedUrlRequest generatePresignedUrlRequest =
|
|
|
- new GeneratePresignedUrlRequest(properties.getBucketName(), objectKey)
|
|
|
- .withMethod(HttpMethod.GET)
|
|
|
- .withExpiration(new Date(System.currentTimeMillis() + 1000L * second));
|
|
|
- URL url = client.generatePresignedUrl(generatePresignedUrlRequest);
|
|
|
- return url.toString();
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 检查配置是否相同
|
|
|
- */
|
|
|
- public boolean checkPropertiesSame(OssProperties properties) {
|
|
|
- return this.properties.equals(properties);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取当前桶权限类型
|
|
|
- *
|
|
|
- * @return 当前桶权限类型code
|
|
|
- */
|
|
|
- public AccessPolicyType getAccessPolicy() {
|
|
|
- return AccessPolicyType.getByType(properties.getAccessPolicy());
|
|
|
- }
|
|
|
-
|
|
|
-}
|