diff --git a/src/main/java/com/ai/da/common/utils/S3Util.java b/src/main/java/com/ai/da/common/utils/S3Util.java new file mode 100644 index 00000000..1d4735cc --- /dev/null +++ b/src/main/java/com/ai/da/common/utils/S3Util.java @@ -0,0 +1,225 @@ +package com.ai.da.common.utils; + +import com.ai.da.common.config.exception.BusinessException; +import com.ai.da.common.constant.CommonConstant; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; +import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; +import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; +import software.amazon.awssdk.core.ResponseBytes; +import software.amazon.awssdk.core.sync.RequestBody; +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.services.s3.S3Client; +import software.amazon.awssdk.services.s3.S3Configuration; +import software.amazon.awssdk.services.s3.model.*; +import software.amazon.awssdk.services.s3.presigner.S3Presigner; +import software.amazon.awssdk.services.s3.presigner.model.GetObjectPresignRequest; +import software.amazon.awssdk.services.s3.presigner.model.PresignedGetObjectRequest; + +import javax.annotation.PostConstruct; +import java.io.*; +import java.time.Duration; +import java.util.*; +import java.util.stream.Collectors; + + +@Slf4j +@Component +public class S3Util { + + @Value("${aws.s3.accessKeyId}") + private String accessKeyId; + + @Value("${aws.s3.secretKey}") + private String secretKey; + + @Value("${aws.s3.regionName}") + private String region; + + public static String S3_ACCESS_KEY_ID = null; + + public static String S3_SECRET_KEY = null; + + public static String S3_REGION = null; + + + @PostConstruct + public void init() { + S3_ACCESS_KEY_ID = accessKeyId; + S3_SECRET_KEY = secretKey; + S3_REGION = region; + } + + private static S3Client s3Client; + + private static S3Presigner s3Presigner; + + /** + * @description: 获取S3客户端对象 + * @return software.amazon.awssdk.services.s3.S3Client + */ + public synchronized S3Client getS3Client() { + if (null == s3Client) { + s3Client = S3Client.builder() + .credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create(S3_ACCESS_KEY_ID, S3_SECRET_KEY))) +// .endpointOverride(URI.create(S3_URI)) + .serviceConfiguration(item -> item.pathStyleAccessEnabled(true).checksumValidationEnabled(false)) + .region(Region.of(S3_REGION)) + .build(); + } + + return s3Client; + } + + /** + * @description: 获取预签名对象 + * @return software.amazon.awssdk.services.s3.presigner.S3Presigner + */ + public synchronized S3Presigner getS3PreSigner() { + if (null == s3Presigner) { + s3Presigner = S3Presigner.builder() + .credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create(S3_ACCESS_KEY_ID, S3_SECRET_KEY))) +// .endpointOverride(URI.create(S3_URI)) + .serviceConfiguration(S3Configuration.builder() + .checksumValidationEnabled(false) + .pathStyleAccessEnabled(true) + .build()) + .region(Region.of(S3_REGION)) + .build(); + } + return s3Presigner; + } + + public String upload(String bucketName, String path, MultipartFile file) { + S3Client s3Client = getS3Client(); + try { + String fileName = file.getOriginalFilename(); + assert fileName != null; + String[] split = fileName.split("\\."); + if (split.length > 1) { + fileName = path + "/" + UUID.randomUUID() + "." + split[split.length - 1]; + } else { + fileName = path + "/" + UUID.randomUUID(); + } + PutObjectRequest putObjectRequest = PutObjectRequest.builder() + .bucket(bucketName) + .contentType(file.getContentType()) + .contentLength(file.getSize()) + .key(fileName) +// .acl(ObjectCannedACL.PUBLIC_READ) + .build(); + s3Client.putObject(putObjectRequest, RequestBody.fromInputStream(file.getInputStream(), file.getSize())); + + log.info("上传的位置:桶 - {},路径 - {}", bucketName, fileName); + return fileName; + } catch (Exception e) { + log.error("上传文件到S3失败 异常:{}", e.getMessage()); + } + return null; + } + + public String getPreSignedUrl(String path, int expiry) { + if (LocalCacheUtils.getPresignedUrlCache(path) != null) { + return LocalCacheUtils.getPresignedUrlCache(path); + } else { + if (!path.contains("/")) { + throw new BusinessException("The path is error!"); + } + int index = path.indexOf("/"); + String bucketName = path.substring(0, index); + String fileName = path.substring(index + 1); + String preSignedUrl = getPreSignatureUrl(bucketName, fileName, expiry); + LocalCacheUtils.setPresignedUrlCache(path, preSignedUrl); + return preSignedUrl; + } + } + + /** + * @description: 生成预签名URL + * @param keyName key名称: test/2022/06/123.pdf + * @param signatureDurationTime 有效期 单位:秒 + * @return java.lang.String + */ + public String getPreSignatureUrl(String bucket, String keyName, Integer signatureDurationTime) { + String preSignatureUrl = ""; + try { + S3Presigner s3PreSigner = getS3PreSigner(); + GetObjectRequest getObjectRequest = + GetObjectRequest.builder() + .bucket(bucket) + .key(keyName) + .build(); + //设置预签名URL可访问时间 + signatureDurationTime = Optional.ofNullable(signatureDurationTime) + .map(item -> { + if (item.intValue() > CommonConstant.Numbers.NUMBER_10080) { + item = CommonConstant.Numbers.NUMBER_10080; + } + return item; + }) + .orElse(CommonConstant.Numbers.NUMBER_10); + GetObjectPresignRequest getObjectPresignRequest = GetObjectPresignRequest.builder() + .signatureDuration(Duration.ofMinutes(signatureDurationTime)) + .getObjectRequest(getObjectRequest) + .build(); + + PresignedGetObjectRequest presignedGetObjectRequest = + s3PreSigner.presignGetObject(getObjectPresignRequest); + + preSignatureUrl = String.valueOf(presignedGetObjectRequest.url()); + + } catch (Exception e) { + log.error("生成预签名URL失败,异常:{}", e.getMessage()); + } + return preSignatureUrl; + } + + public InputStream download(String path) { + if (!path.contains("/")) { + throw new BusinessException("the.path.is.error"); + } + int index = path.indexOf("/"); + String bucketName = path.substring(0, index); + String objectName = path.substring(index + 1); + return download(bucketName, objectName); + } + + public InputStream download(String bucketName, String objectName){ + try { + S3Client s3Client = getS3Client(); + GetObjectRequest objectRequest = GetObjectRequest + .builder() + .key(objectName) + .bucket(bucketName) + .build(); + +// ResponseBytes objectBytes = s3.getObjectAsBytes(objectRequest); + ResponseBytes objectAsBytes = s3Client.getObjectAsBytes(objectRequest); + byte[] data = objectAsBytes.asByteArray(); + return new ByteArrayInputStream(data); + + /*// Write the data to a local file. + File myFile = new File("files/images.png"); + OutputStream os = new FileOutputStream(myFile); + os.write(data); + System.out.println("Successfully obtained bytes from an S3 object"); + os.close(); + return null;*/ + +// return minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(objectName).build()); + } catch (Exception e){ + log.error(""); + throw new BusinessException(""); + } + } + + public List listAllBucket(){ + S3Client s3Client = getS3Client(); + ListBucketsResponse listBucketsResponse = s3Client.listBuckets(); + List buckets = listBucketsResponse.buckets(); + return buckets.stream().map(Bucket::name).collect(Collectors.toList()); + } + +}