diff --git a/schisandra-cloud-storage-oss/schisandra-cloud-storage-oss-application/schisandra-cloud-storage-oss-application-controller/src/main/java/com/schisandra/oss/application/controller/SchisandraOssMinioController.java b/schisandra-cloud-storage-oss/schisandra-cloud-storage-oss-application/schisandra-cloud-storage-oss-application-controller/src/main/java/com/schisandra/oss/application/controller/SchisandraOssMinioController.java index 8647f18..f697f03 100644 --- a/schisandra-cloud-storage-oss/schisandra-cloud-storage-oss-application/schisandra-cloud-storage-oss-application-controller/src/main/java/com/schisandra/oss/application/controller/SchisandraOssMinioController.java +++ b/schisandra-cloud-storage-oss/schisandra-cloud-storage-oss-application/schisandra-cloud-storage-oss-application-controller/src/main/java/com/schisandra/oss/application/controller/SchisandraOssMinioController.java @@ -2,19 +2,31 @@ package com.schisandra.oss.application.controller; import cn.hutool.extra.spring.SpringUtil; import com.alibaba.fastjson.JSON; +import com.amazonaws.util.IOUtils; import com.google.common.base.Preconditions; import com.schisandra.oss.application.convert.SchisandraOssMinioDTOConverter; import com.schisandra.oss.application.dto.SchisandraOssMinioDTO; import com.schisandra.oss.application.oss.core.minio.MinioOssClient; import com.schisandra.oss.application.oss.core.minio.MinioOssConfiguration; +import com.schisandra.oss.application.oss.core.minio.model.MinioOssConfig; +import com.schisandra.oss.application.oss.model.OssInfo; import com.schisandra.oss.common.entity.Result; -import com.schisandra.oss.domain.redis.RedisUtil; import com.schisandra.oss.domain.bo.SchisandraOssMinioBO; +import com.schisandra.oss.domain.redis.RedisUtil; import com.schisandra.oss.domain.service.SchisandraOssMinioDomainService; +import io.minio.errors.*; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.InputStream; +import java.net.URLEncoder; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; import java.util.List; /** @@ -60,7 +72,214 @@ public class SchisandraOssMinioController { log.error("用户: {}-> minio 初始化完成!", userId); } } + /** + * @description: 获取文件目录信息 + * @param: [target, userId, dirName] + * @return: com.schisandra.oss.common.entity.Result + * @author zlg + * @date: 2024/6/26 13:55 + */ + @GetMapping("listMinioDir") + public Result listMinioInfo(@RequestParam String target, @RequestParam String userId, @RequestParam String dirName,@RequestParam String bucket) throws Exception { + Preconditions.checkNotNull(target, "不能为空"); + Preconditions.checkNotNull(userId, "不能为空"); + MinioOssClient bean = SpringUtil.getBean(userId); + bean.getMinioOssConfig().setBucketName(bucket); + return Result.ok(bean.listDir(target, dirName)); + } + /** + * @description: 下载文件 + * @param: [schisandraOssMinioDTO] + * @return: void + * @author zlg + * @date: 2024/6/26 13:56 + */ + @GetMapping("downloadMinioFile") + public void getMinioFile(@RequestParam String bucket, @RequestParam String userId, @RequestParam String filePath, HttpServletResponse response) throws Exception { + Preconditions.checkNotNull(bucket, "不能为空"); + Preconditions.checkNotNull(userId, "不能为空"); + Preconditions.checkNotNull(filePath, "不能为空"); + MinioOssClient bean = SpringUtil.getBean(userId); + bean.getMinioOssConfig().setBucketName(bucket); + InputStream stream = bean.getMinioObject(bucket, filePath); + ServletOutputStream output = response.getOutputStream(); + response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filePath.substring(filePath.lastIndexOf("/") + 1), "UTF-8")); + response.setContentType("application/octet-stream"); + response.setCharacterEncoding("UTF-8"); + IOUtils.copy(stream, output); + } + + /** + * @description: 删除文件 + * @param: [schisandraOssMinioDTO] + * @return: void + * @author zlg + * @date: 2024/6/26 14:34 + */ + @PostMapping("deleteMinioFile") + public Result deleteMinioFile(@RequestParam String bucket, @RequestParam String userId, @RequestParam String filePath) { + Preconditions.checkNotNull(bucket, "不能为空"); + Preconditions.checkNotNull(userId, "不能为空"); + Preconditions.checkNotNull(filePath, "不能为空"); + MinioOssClient bean = SpringUtil.getBean(userId); + bean.getMinioOssConfig().setBucketName(bucket); + bean.delete(filePath); + return Result.ok(); + } + + /** + * @description: 上传文件 + * @param: [schisandraOssMinioDTO] + * @return: void + * @author zlg + * @date: 2024/6/26 14:34 + */ + @PostMapping("uploadMinioFile") + public Result uploadMinioFile(@RequestParam String userId, @RequestParam MultipartFile file, @RequestParam String fileName, @RequestParam String bucket) throws IOException { + Preconditions.checkNotNull(userId, "不能为空"); + Preconditions.checkNotNull(fileName, "不能为空"); + Preconditions.checkNotNull(bucket, "不能为空"); + // 获取文件输入流 + InputStream is = file.getInputStream(); + MinioOssClient bean = SpringUtil.getBean(userId); + bean.getMinioOssConfig().setBucketName(bucket); + return Result.ok(bean.upLoad(is, fileName, true)); + } + + + /** + * @description: 重命名文件 + * @param: [userId, bucket, oldFileName, newFileName] + * @return: com.schisandra.oss.common.entity.Result + * @author zlg + * @date: 2024/6/27 9:41 + */ + @PostMapping("renameMinioFile") + public Result renameMinioFile(@RequestParam String userId, @RequestParam String bucket, @RequestParam String oldFileName, @RequestParam String newFileName) throws IOException { + + Preconditions.checkNotNull(userId, "不能为空"); + Preconditions.checkNotNull(bucket, "不能为空"); + Preconditions.checkNotNull(oldFileName, "不能为空"); + Preconditions.checkNotNull(newFileName, "不能为空"); + MinioOssClient bean = SpringUtil.getBean(userId); + bean.getMinioOssConfig().setBucketName(bucket); + try { + bean.rename(oldFileName, newFileName); + }catch (Exception e){ + return Result.fail(e.getMessage()); + } + return Result.ok(); + } + /** + * @description: 拷贝文件 + * @param: [userId, bucket, oldFilePath, newFilePath] + * @return: com.schisandra.oss.common.entity.Result + * @author zlg + * @date: 2024/6/27 9:52 + */ + @PostMapping("copyMinioFile") + public Result copyMinioFile(@RequestParam String userId, @RequestParam String bucket, @RequestParam String oldFilePath, @RequestParam String newFilePath) throws IOException { + + Preconditions.checkNotNull(userId, "不能为空"); + Preconditions.checkNotNull(bucket, "不能为空"); + Preconditions.checkNotNull(oldFilePath, "不能为空"); + Preconditions.checkNotNull(newFilePath, "不能为空"); + MinioOssClient bean = SpringUtil.getBean(userId); + bean.getMinioOssConfig().setBucketName(bucket); + try { + bean.copy(oldFilePath, newFilePath); + }catch (Exception e){ + return Result.fail(e.getMessage()); + } + return Result.ok(); + } + /** + * @description: 预览文件 + * @param: [userId, bucket, filePath] + * @return: com.schisandra.oss.common.entity.Result + * @author zlg + * @date: 2024/6/27 10:14 + */ + @PostMapping("previewMinioFile") + public Result previewMinioFile(@RequestParam String userId, @RequestParam String bucket, @RequestParam String filePath) throws IOException { + Preconditions.checkNotNull(userId, "不能为空"); + Preconditions.checkNotNull(bucket, "不能为空"); + Preconditions.checkNotNull(filePath, "不能为空"); + MinioOssClient bean = SpringUtil.getBean(userId); + bean.getMinioOssConfig().setBucketName(bucket); + try { + return Result.ok(bean.getMinioPreviewUrl(filePath)); + } catch (Exception e) { + return Result.fail(e.getMessage()); + } + + } + /** + * @description: 分享文件 + * @param: [userId, bucket, filePath] + * @return: com.schisandra.oss.common.entity.Result + * @author zlg + * @date: 2024/6/27 10:17 + */ + @PostMapping("shareMinioFile") + public Result shareMinioFile(@RequestParam String userId, @RequestParam String bucket, @RequestParam String filePath, @RequestParam int time) throws IOException { + Preconditions.checkNotNull(userId, "不能为空"); + Preconditions.checkNotNull(bucket, "不能为空"); + Preconditions.checkNotNull(filePath, "不能为空"); + MinioOssClient bean = SpringUtil.getBean(userId); + bean.getMinioOssConfig().setBucketName(bucket); + try { + return Result.ok(bean.shareMinioFile(filePath,time)); + } catch (Exception e) { + return Result.fail(e.getMessage()); + } + } + + /** + * @description: 获取所有bucket + * @param: [userId, bucket] + * @return: com.schisandra.oss.common.entity.Result + * @author zlg + * @date: 2024/6/26 17:37 + */ + @PostMapping("seleteBucket") + public Result seleteBucket(@RequestParam String userId) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException { + Preconditions.checkNotNull(userId, "不能为空"); + MinioOssClient bean = SpringUtil.getBean(userId); + return Result.ok(bean.selectAllBucket()); + } + /** + * @description: 创建bucket + * @param: [userId, bucket] + * @return: com.schisandra.oss.common.entity.Result + * @author zlg + * @date: 2024/6/26 17:38 + */ + @PostMapping("createBucket") + public Result createBucket(@RequestParam String userId, @RequestParam String bucket) { + Preconditions.checkNotNull(userId, "不能为空"); + Preconditions.checkNotNull(bucket, "不能为空"); + MinioOssClient bean = SpringUtil.getBean(userId); + bean.getMinioOssConfig().setBucketName(bucket); + return Result.ok(bean.createBucket(bucket)); + } + + /** + * @description: 删除bucket + * @param: [userId, bucket] + * @return: com.schisandra.oss.common.entity.Result + * @author zlg + * @date: 2024/6/26 17:38 + */ + @PostMapping("deleteBucket") + public Result deleteBucket(@RequestParam String userId, @RequestParam String bucket) { + Preconditions.checkNotNull(userId, "不能为空"); + Preconditions.checkNotNull(bucket, "不能为空"); + MinioOssClient bean = SpringUtil.getBean(userId); + bean.getMinioOssConfig().setBucketName(bucket); + return Result.ok(bean.deleteBucket(bucket)); + } @PostMapping("get") public SchisandraOssMinioDTO getMinioOss(@RequestParam String userId) { return SchisandraOssMinioDTOConverter.INSTANCE.convertBOToDTO(schisandraOssMinioDomainService.getMinioConfig(Long.valueOf(userId))); @@ -146,6 +365,11 @@ public class SchisandraOssMinioController { } + + + + + private void parameterCheck(SchisandraOssMinioDTO schisandraOssMinioDTO) { Preconditions.checkNotNull(schisandraOssMinioDTO.getId(), "不能为空"); Preconditions.checkNotNull(schisandraOssMinioDTO.getUserId(), "不能为空"); diff --git a/schisandra-cloud-storage-oss/schisandra-cloud-storage-oss-application/schisandra-cloud-storage-oss-application-controller/src/main/java/com/schisandra/oss/application/oss/core/jd/JdOssClient.java b/schisandra-cloud-storage-oss/schisandra-cloud-storage-oss-application/schisandra-cloud-storage-oss-application-controller/src/main/java/com/schisandra/oss/application/oss/core/jd/JdOssClient.java index 506acb1..4bd854d 100644 --- a/schisandra-cloud-storage-oss/schisandra-cloud-storage-oss-application/schisandra-cloud-storage-oss-application-controller/src/main/java/com/schisandra/oss/application/oss/core/jd/JdOssClient.java +++ b/schisandra-cloud-storage-oss/schisandra-cloud-storage-oss-application/schisandra-cloud-storage-oss-application-controller/src/main/java/com/schisandra/oss/application/oss/core/jd/JdOssClient.java @@ -58,7 +58,7 @@ public class JdOssClient implements StandardOssClient { private JdOssConfig jdOssConfig; @Override - public OssInfo upLoad(InputStream is, String targetName, Boolean isOverride) { + public OssInfo upLoad(InputStream is, String targetName,Boolean isOverride) { String bucketName = getBucket(); String key = getKey(targetName, false); diff --git a/schisandra-cloud-storage-oss/schisandra-cloud-storage-oss-application/schisandra-cloud-storage-oss-application-controller/src/main/java/com/schisandra/oss/application/oss/core/jinshan/JinShanOssClient.java b/schisandra-cloud-storage-oss/schisandra-cloud-storage-oss-application/schisandra-cloud-storage-oss-application-controller/src/main/java/com/schisandra/oss/application/oss/core/jinshan/JinShanOssClient.java index 6bb971f..93784ca 100644 --- a/schisandra-cloud-storage-oss/schisandra-cloud-storage-oss-application/schisandra-cloud-storage-oss-application-controller/src/main/java/com/schisandra/oss/application/oss/core/jinshan/JinShanOssClient.java +++ b/schisandra-cloud-storage-oss/schisandra-cloud-storage-oss-application/schisandra-cloud-storage-oss-application-controller/src/main/java/com/schisandra/oss/application/oss/core/jinshan/JinShanOssClient.java @@ -58,7 +58,7 @@ public class JinShanOssClient implements StandardOssClient { private JinShanOssConfig jinShanOssConfig; @Override - public OssInfo upLoad(InputStream is, String targetName, Boolean isOverride) { + public OssInfo upLoad(InputStream is, String targetName,Boolean isOverride) { String bucket = getBucket(); String key = getKey(targetName, false); if (isOverride || !ks3.objectExists(bucket, key)) { diff --git a/schisandra-cloud-storage-oss/schisandra-cloud-storage-oss-application/schisandra-cloud-storage-oss-application-controller/src/main/java/com/schisandra/oss/application/oss/core/minio/MinioOssClient.java b/schisandra-cloud-storage-oss/schisandra-cloud-storage-oss-application/schisandra-cloud-storage-oss-application-controller/src/main/java/com/schisandra/oss/application/oss/core/minio/MinioOssClient.java index 79371c5..bb21958 100644 --- a/schisandra-cloud-storage-oss/schisandra-cloud-storage-oss-application/schisandra-cloud-storage-oss-application-controller/src/main/java/com/schisandra/oss/application/oss/core/minio/MinioOssClient.java +++ b/schisandra-cloud-storage-oss/schisandra-cloud-storage-oss-application/schisandra-cloud-storage-oss-application-controller/src/main/java/com/schisandra/oss/application/oss/core/minio/MinioOssClient.java @@ -6,11 +6,12 @@ import cn.hutool.core.date.DateUtil; import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.IoUtil; import cn.hutool.core.io.file.FileNameUtil; +import cn.hutool.core.io.unit.DataSizeUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.StrUtil; +import com.alibaba.druid.util.StringUtils; import com.aliyun.oss.common.utils.HttpHeaders; -import com.google.common.io.ByteStreams; import com.schisandra.oss.application.oss.constant.OssConstant; import com.schisandra.oss.application.oss.core.StandardOssClient; import com.schisandra.oss.application.oss.core.minio.model.MinioOssConfig; @@ -22,6 +23,9 @@ import com.schisandra.oss.application.oss.model.download.DownloadCheckPoint; import com.schisandra.oss.application.oss.model.download.DownloadObjectStat; import com.schisandra.oss.application.oss.utils.OssPathUtil; import io.minio.*; +import io.minio.errors.*; +import io.minio.http.Method; +import io.minio.messages.Bucket; import io.minio.messages.Item; import lombok.AllArgsConstructor; import lombok.Data; @@ -31,9 +35,13 @@ import okhttp3.Headers; import org.springframework.stereotype.Component; import java.io.File; +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; import java.util.*; +import java.util.concurrent.TimeUnit; /** * http://docs.minio.org.cn/docs/master/minio-monitoring-guide @@ -55,6 +63,138 @@ public class MinioOssClient implements StandardOssClient { private MinioClient minioClient; private MinioOssConfig minioOssConfig; + + public MinioOssConfig getMinioOssConfig() { + return minioOssConfig; + } + + public void setMinioOssConfig(MinioOssConfig minioOssConfig) { + this.minioOssConfig = minioOssConfig; + } + + + public String getMinioBucketSize(String bucket) { + Iterable> results = + minioClient.listObjects( + ListObjectsArgs.builder().bucket(bucket).recursive(true).build()); + final long[] totalSize = {0}; + final Item[] item = {null}; + results.forEach(result -> { + try { + item[0] = result.get(); + totalSize[0] = item[0].size() + totalSize[0]; + } catch (Exception e) { + log.error("listObjects error", e); + } + }); + return String.valueOf(DataSizeUtil.format(totalSize[0])); + } + + public String getMinioPreviewUrl(String fileName) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException { + String presignedUrl = null; + presignedUrl = minioClient.getPresignedObjectUrl( + GetPresignedObjectUrlArgs.builder() + .method(Method.GET) + .bucket(getBucket()) + .object(fileName) + .expiry(1, TimeUnit.DAYS) + .build()); + return presignedUrl; + } + + public String shareMinioFile(String fileName, int time) { + String presignedUrl = null; + try { + presignedUrl = minioClient.getPresignedObjectUrl( + GetPresignedObjectUrlArgs.builder() + .method(Method.GET) + .bucket(getBucket()) + .object(fileName) + .expiry(time) + .build()); + } catch (Exception e) { + e.printStackTrace(); + } + return presignedUrl; + } + + public String createBucket(String bucketName) { + try { + if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) { + minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build()); + } else { + return "bucket already exists"; + } + } catch (Exception e) { + e.printStackTrace(); + } + return bucketName; + } + + public String deleteBucket(String bucketName) { + try { + if (minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) { + minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build()); + } else { + return "bucket not exists"; + } + } catch (Exception e) { + e.printStackTrace(); + } + return "success"; + } + + public HashMap selectAllBucket() throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException { + List list = minioClient.listBuckets(); + HashMap names = new HashMap<>(); + list.forEach(bucket -> { + names.put(bucket.name(), getMinioBucketSize(bucket.name())); + }); + return names; + } + + /** + * @description: 获取目录文件信息 + * @param: [bucket, dirName] + * @return: java.util.List + * @author zlg + * @date: 2024/6/26 13:34 + */ + public List listDir(String bucket, String dirName) throws Exception { + Iterable> results = null; + if (StringUtils.isEmpty(dirName)) { + results = minioClient.listObjects( + ListObjectsArgs.builder().bucket(bucket).recursive(false).build()); + } else { + results = minioClient.listObjects( + ListObjectsArgs.builder().prefix(dirName).bucket(bucket).recursive(false).build()); + } + List infos = new ArrayList<>(); + results.forEach(r -> { + OssInfo info = new OssInfo(); + try { + Item item = r.get(); + if (item.isDir()) { + String[] directories = item.objectName().split("/"); + info.setName(directories[directories.length - 1]); + info.setPath(item.objectName()); + info.setIsDir(item.isDir()); + } else { + String[] files = item.objectName().split("/"); + info.setName(files[files.length - 1]); + info.setPath(item.objectName()); + info.setIsDir(item.isDir()); + info.setLength(String.valueOf(item.size())); + info.setCreateTime(String.valueOf(item.lastModified())); + } + infos.add(info); + } catch (Exception e) { + e.printStackTrace(); + } + }); + return infos; + } + @Override public OssInfo upLoad(InputStream is, String targetName, Boolean isOverride) { try { @@ -68,7 +208,7 @@ public class MinioOssClient implements StandardOssClient { } catch (Exception e) { throw new OssException(e); } - return getInfo(targetName); + return getBaseInfo(targetName); } @Override @@ -85,12 +225,13 @@ public class MinioOssClient implements StandardOssClient { public void downLoad(OutputStream os, String targetName) { GetObjectResponse is = null; try { + GetObjectArgs getObjectArgs = GetObjectArgs.builder() .bucket(getBucket()) .object(getKey(targetName, true)) .build(); is = minioClient.getObject(getObjectArgs); - ByteStreams.copy(is, os); + IoUtil.copy(is, os); } catch (Exception e) { throw new OssException(e); } finally { @@ -185,6 +326,13 @@ public class MinioOssClient implements StandardOssClient { } } + public InputStream getMinioObject(String bucket, String dirName) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException { + InputStream stream = minioClient.getObject( + GetObjectArgs.builder().bucket(bucket).object(dirName).build()); + return stream; + } + + @Override public OssInfo getInfo(String targetName, Boolean isRecursion) { try { @@ -278,4 +426,5 @@ public class MinioOssClient implements StandardOssClient { return ossInfo; } + } diff --git a/schisandra-cloud-storage-oss/schisandra-cloud-storage-oss-application/schisandra-cloud-storage-oss-application-controller/src/main/java/com/schisandra/oss/application/oss/model/OssInfo.java b/schisandra-cloud-storage-oss/schisandra-cloud-storage-oss-application/schisandra-cloud-storage-oss-application-controller/src/main/java/com/schisandra/oss/application/oss/model/OssInfo.java index 28396fd..75bc630 100644 --- a/schisandra-cloud-storage-oss/schisandra-cloud-storage-oss-application/schisandra-cloud-storage-oss-application-controller/src/main/java/com/schisandra/oss/application/oss/model/OssInfo.java +++ b/schisandra-cloud-storage-oss/schisandra-cloud-storage-oss-application/schisandra-cloud-storage-oss-application-controller/src/main/java/com/schisandra/oss/application/oss/model/OssInfo.java @@ -14,6 +14,10 @@ public class OssInfo { * 名称 */ private String name; + /** + * 是否是文件夹 + */ + private Boolean isDir; /** * 存储路径 */ diff --git a/schisandra-cloud-storage-oss/schisandra-cloud-storage-oss-common/pom.xml b/schisandra-cloud-storage-oss/schisandra-cloud-storage-oss-common/pom.xml index 021ba67..25d3ae9 100644 --- a/schisandra-cloud-storage-oss/schisandra-cloud-storage-oss-common/pom.xml +++ b/schisandra-cloud-storage-oss/schisandra-cloud-storage-oss-common/pom.xml @@ -9,7 +9,6 @@ schisandra-cloud-storage-oss-common jar - schisandra-cloud-storage-oss-common @@ -124,11 +123,12 @@ minio 8.2.1 + com.aliyun.oss aliyun-sdk-oss - 3.14.0 + 3.17.4