From 3663f06912efda4edb04e410ac7bb272c9818582 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johnny=20Miller=20=28=E9=94=BA=E4=BF=8A=29?= Date: Thu, 12 Aug 2021 17:43:02 +0800 Subject: [PATCH] feat($OSS): get information of an object --- .../controller/ReadResourceController.java | 9 ++ .../entity/SerializableGenericResponse.java | 22 +++++ .../SerializableStatObjectResponse.java | 45 +++++++++ .../read/service/ReadResourceService.java | 10 ++ .../service/impl/ReadResourceServiceImpl.java | 6 ++ .../springcloudstarter/minio/MinioHelper.java | 96 +++++++++---------- 6 files changed, 140 insertions(+), 48 deletions(-) create mode 100644 oss-center/src/main/java/com/jmsoftware/maf/osscenter/read/entity/SerializableGenericResponse.java create mode 100644 oss-center/src/main/java/com/jmsoftware/maf/osscenter/read/entity/SerializableStatObjectResponse.java diff --git a/oss-center/src/main/java/com/jmsoftware/maf/osscenter/read/controller/ReadResourceController.java b/oss-center/src/main/java/com/jmsoftware/maf/osscenter/read/controller/ReadResourceController.java index 3d54bdd9..86991c4a 100644 --- a/oss-center/src/main/java/com/jmsoftware/maf/osscenter/read/controller/ReadResourceController.java +++ b/oss-center/src/main/java/com/jmsoftware/maf/osscenter/read/controller/ReadResourceController.java @@ -1,5 +1,7 @@ package com.jmsoftware.maf.osscenter.read.controller; +import com.jmsoftware.maf.common.bean.ResponseBodyBean; +import com.jmsoftware.maf.osscenter.read.entity.SerializableStatObjectResponse; import com.jmsoftware.maf.osscenter.read.service.ReadResourceService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -42,4 +44,11 @@ public ResponseEntity downloadSingleResource(@PathVariabl @PathVariable String object) { return this.readResourceService.asyncDownloadSingleResource(bucket, object); } + + @GetMapping("/stat/{bucket}/{object}") + @ApiOperation(value = "Get the information of single resource", notes = "Get the information of single resource") + public ResponseBodyBean statSingleResource(@PathVariable String bucket, + @PathVariable String object) { + return ResponseBodyBean.ofSuccess(this.readResourceService.stateObject(bucket, object)); + } } diff --git a/oss-center/src/main/java/com/jmsoftware/maf/osscenter/read/entity/SerializableGenericResponse.java b/oss-center/src/main/java/com/jmsoftware/maf/osscenter/read/entity/SerializableGenericResponse.java new file mode 100644 index 00000000..23c829b3 --- /dev/null +++ b/oss-center/src/main/java/com/jmsoftware/maf/osscenter/read/entity/SerializableGenericResponse.java @@ -0,0 +1,22 @@ +package com.jmsoftware.maf.osscenter.read.entity; + +import lombok.AccessLevel; +import lombok.Data; +import lombok.Setter; + +import java.util.List; +import java.util.Map; + +/** + * Description: SerializableGenericResponse, change description here. + * + * @author Johnny Miller (锺俊), email: johnnysviva@outlook.com, date: 8/12/2021 5:07 PM + **/ +@Data +@Setter(AccessLevel.PROTECTED) +public class SerializableGenericResponse { + private Map> headers; + private String bucket; + private String region; + private String object; +} diff --git a/oss-center/src/main/java/com/jmsoftware/maf/osscenter/read/entity/SerializableStatObjectResponse.java b/oss-center/src/main/java/com/jmsoftware/maf/osscenter/read/entity/SerializableStatObjectResponse.java new file mode 100644 index 00000000..075e959d --- /dev/null +++ b/oss-center/src/main/java/com/jmsoftware/maf/osscenter/read/entity/SerializableStatObjectResponse.java @@ -0,0 +1,45 @@ +package com.jmsoftware.maf.osscenter.read.entity; + +import io.minio.StatObjectResponse; +import io.minio.messages.LegalHold; +import io.minio.messages.RetentionMode; +import lombok.*; + +import java.time.ZonedDateTime; +import java.util.Map; + +/** + * Description: SerializableStatObjectResponse, change description here. + * + * @author Johnny Miller (锺俊), email: johnnysviva@outlook.com, date: 8/12/2021 5:04 PM + **/ +@Data +@Setter(AccessLevel.NONE) +@EqualsAndHashCode(callSuper = true) +public class SerializableStatObjectResponse extends SerializableGenericResponse { + private String etag; + private long size; + private ZonedDateTime lastModified; + private RetentionMode retentionMode; + private ZonedDateTime retentionRetainUntilDate; + private LegalHold legalHold; + private boolean deleteMarker; + private Map userMetadata; + + public static SerializableStatObjectResponse build(StatObjectResponse statObjectResponse) { + val serializableStatObjectResponse = new SerializableStatObjectResponse(); + serializableStatObjectResponse.setHeaders(statObjectResponse.headers().toMultimap()); + serializableStatObjectResponse.setBucket(statObjectResponse.bucket()); + serializableStatObjectResponse.setRegion(statObjectResponse.region()); + serializableStatObjectResponse.setObject(statObjectResponse.object()); + serializableStatObjectResponse.etag = statObjectResponse.etag(); + serializableStatObjectResponse.size = statObjectResponse.size(); + serializableStatObjectResponse.lastModified = statObjectResponse.lastModified(); + serializableStatObjectResponse.retentionMode = statObjectResponse.retentionMode(); + serializableStatObjectResponse.retentionRetainUntilDate = statObjectResponse.retentionRetainUntilDate(); + serializableStatObjectResponse.legalHold = statObjectResponse.legalHold(); + serializableStatObjectResponse.deleteMarker = statObjectResponse.deleteMarker(); + serializableStatObjectResponse.userMetadata = statObjectResponse.userMetadata(); + return serializableStatObjectResponse; + } +} diff --git a/oss-center/src/main/java/com/jmsoftware/maf/osscenter/read/service/ReadResourceService.java b/oss-center/src/main/java/com/jmsoftware/maf/osscenter/read/service/ReadResourceService.java index c5021724..6ee5b7dc 100644 --- a/oss-center/src/main/java/com/jmsoftware/maf/osscenter/read/service/ReadResourceService.java +++ b/oss-center/src/main/java/com/jmsoftware/maf/osscenter/read/service/ReadResourceService.java @@ -1,5 +1,6 @@ package com.jmsoftware.maf.osscenter.read.service; +import com.jmsoftware.maf.osscenter.read.entity.SerializableStatObjectResponse; import org.springframework.http.ResponseEntity; import org.springframework.lang.Nullable; import org.springframework.util.unit.DataSize; @@ -41,4 +42,13 @@ ResponseEntity asyncStreamSingleResource(@NotBlank String * @return the response entity */ ResponseEntity asyncDownloadSingleResource(@NotBlank String bucket, @NotBlank String object); + + /** + * Gets resource information. + * + * @param bucket the bucket + * @param object the object + * @return the resource detail + */ + SerializableStatObjectResponse stateObject(@NotBlank String bucket, @NotBlank String object); } diff --git a/oss-center/src/main/java/com/jmsoftware/maf/osscenter/read/service/impl/ReadResourceServiceImpl.java b/oss-center/src/main/java/com/jmsoftware/maf/osscenter/read/service/impl/ReadResourceServiceImpl.java index 9f9488d8..9a0390c2 100644 --- a/oss-center/src/main/java/com/jmsoftware/maf/osscenter/read/service/impl/ReadResourceServiceImpl.java +++ b/oss-center/src/main/java/com/jmsoftware/maf/osscenter/read/service/impl/ReadResourceServiceImpl.java @@ -2,6 +2,7 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.io.IoUtil; +import com.jmsoftware.maf.osscenter.read.entity.SerializableStatObjectResponse; import com.jmsoftware.maf.osscenter.read.service.ReadResourceService; import com.jmsoftware.maf.springcloudstarter.minio.MinioHelper; import io.minio.StatObjectResponse; @@ -79,6 +80,11 @@ public ResponseEntity asyncDownloadSingleResource(@NotBla })); } + @Override + public SerializableStatObjectResponse stateObject(@NotBlank String bucket, @NotBlank String object) { + return SerializableStatObjectResponse.build(this.minioHelper.statObject(bucket, object)); + } + @SuppressWarnings("DuplicatedCode") private ResponseEntity asyncGetResourceRegion(String bucket, String object, StatObjectResponse statObjectResponse, diff --git a/spring-cloud-starter/src/main/java/com/jmsoftware/maf/springcloudstarter/minio/MinioHelper.java b/spring-cloud-starter/src/main/java/com/jmsoftware/maf/springcloudstarter/minio/MinioHelper.java index 1c83d6f7..438e11e0 100644 --- a/spring-cloud-starter/src/main/java/com/jmsoftware/maf/springcloudstarter/minio/MinioHelper.java +++ b/spring-cloud-starter/src/main/java/com/jmsoftware/maf/springcloudstarter/minio/MinioHelper.java @@ -43,41 +43,41 @@ public class MinioHelper { private final MinioClient minioClient; @SneakyThrows - public boolean bucketExists(@NotBlank String bucketName) { - return this.minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build()); + public boolean bucketExists(@NotBlank String bucket) { + return this.minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucket).build()); } @SneakyThrows @SuppressWarnings("UnusedReturnValue") - public boolean makeBucket(@NotBlank String bucketName) { - if (this.bucketExists(bucketName)) { - log.warn("The bucket named '{}' exists", bucketName); + public boolean makeBucket(@NotBlank String bucket) { + if (this.bucketExists(bucket)) { + log.warn("The bucket named '{}' exists", bucket); return false; } - this.minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build()); + this.minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucket).build()); return true; } @SneakyThrows - public ObjectWriteResponse put(@NotBlank String bucketName, @NotBlank String objectName, + public ObjectWriteResponse put(@NotBlank String bucket, @NotBlank String object, @NotNull MultipartFile multipartFile) { return this.minioClient.putObject( PutObjectArgs.builder() - .bucket(bucketName) - .object(objectName) + .bucket(bucket) + .object(object) .stream(multipartFile.getInputStream(), multipartFile.getSize(), -1) .contentType(multipartFile.getContentType()) .build()); } @SneakyThrows - public ObjectWriteResponse putObject(@NotBlank String bucketName, @NotBlank String objectName, + public ObjectWriteResponse putObject(@NotBlank String bucket, @NotBlank String object, @NotNull InputStream inputStream, @NotBlank String contentType) { return this.minioClient.putObject( PutObjectArgs .builder() - .bucket(bucketName) - .object(objectName) + .bucket(bucket) + .object(object) .stream(inputStream, inputStream.available(), -1) .contentType(contentType) .build()); @@ -94,11 +94,11 @@ public List listBuckets() { } @SneakyThrows - public boolean removeBucket(@NotBlank String bucketName) { - if (!this.bucketExists(bucketName)) { + public boolean removeBucket(@NotBlank String bucket) { + if (!this.bucketExists(bucket)) { return false; } - val myObjects = this.listObjects(bucketName); + val myObjects = this.listObjects(bucket); for (val result : myObjects) { val item = result.get(); // If item has files, fail to remove @@ -107,17 +107,17 @@ public boolean removeBucket(@NotBlank String bucketName) { } } // If bucket is empty, then it can be removed - this.minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build()); - return !this.bucketExists(bucketName); + this.minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucket).build()); + return !this.bucketExists(bucket); } @SneakyThrows - public List listObjectNames(@NotBlank String bucketName) { + public List listObjectNames(@NotBlank String bucket) { val listObjectNames = new LinkedList(); - if (!this.bucketExists(bucketName)) { + if (!this.bucketExists(bucket)) { return listObjectNames; } - val myObjects = this.listObjects(bucketName); + val myObjects = this.listObjects(bucket); for (val result : myObjects) { val item = result.get(); listObjectNames.add(item.objectName()); @@ -126,55 +126,55 @@ public List listObjectNames(@NotBlank String bucketName) { } @SneakyThrows - public Iterable> listObjects(@NotBlank String bucketName) { - if (!this.bucketExists(bucketName)) { + public Iterable> listObjects(@NotBlank String bucket) { + if (!this.bucketExists(bucket)) { return null; } - return this.minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).build()); + return this.minioClient.listObjects(ListObjectsArgs.builder().bucket(bucket).build()); } @SneakyThrows - public GetObjectResponse getObject(@NotBlank String bucketName, @NotBlank String objectName) { - if (!this.bucketExists(bucketName)) { + public GetObjectResponse getObject(@NotBlank String bucket, @NotBlank String object) { + if (!this.bucketExists(bucket)) { return null; } - val statObjectResponse = this.statObject(bucketName, objectName); + val statObjectResponse = this.statObject(bucket, object); if (ObjectUtil.isNull(statObjectResponse) || statObjectResponse.size() == 0) { return null; } - return this.minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(objectName).build()); + return this.minioClient.getObject(GetObjectArgs.builder().bucket(bucket).object(object).build()); } @SneakyThrows - public GetObjectResponse getObject(@NotBlank String bucketName, @NotBlank String objectName, @Min(0L) long offset, + public GetObjectResponse getObject(@NotBlank String bucket, @NotBlank String object, @Min(0L) long offset, @NotNull @Min(0L) Long length) { - if (!this.bucketExists(bucketName)) { + if (!this.bucketExists(bucket)) { return null; } - val statObjectResponse = this.statObject(bucketName, objectName); + val statObjectResponse = this.statObject(bucket, object); if (ObjectUtil.isNull(statObjectResponse) || statObjectResponse.size() == 0) { return null; } return this.minioClient.getObject( - GetObjectArgs.builder().bucket(bucketName).object(objectName).offset(offset).length(length).build()); + GetObjectArgs.builder().bucket(bucket).object(object).offset(offset).length(length).build()); } @SneakyThrows - public boolean removeObject(String bucketName, String objectName) { - if (!this.bucketExists(bucketName)) { + public boolean removeObject(String bucket, String object) { + if (!this.bucketExists(bucket)) { return false; } - this.minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(objectName).build()); + this.minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucket).object(object).build()); return true; } @SneakyThrows - public List removeObject(String bucketName, List objectNames) { + public List removeObject(String bucket, List objects) { val deleteErrorNameList = new LinkedList(); - if (this.bucketExists(bucketName)) { - val deleteObjectList = objectNames.stream().map(DeleteObject::new).collect(Collectors.toList()); + if (this.bucketExists(bucket)) { + val deleteObjectList = objects.stream().map(DeleteObject::new).collect(Collectors.toList()); val results = this.minioClient.removeObjects( - RemoveObjectsArgs.builder().bucket(bucketName).objects(deleteObjectList).build()); + RemoveObjectsArgs.builder().bucket(bucket).objects(deleteObjectList).build()); for (val result : results) { val error = result.get(); deleteErrorNameList.add(error.objectName()); @@ -184,36 +184,36 @@ public List removeObject(String bucketName, List objectNames) { } @SneakyThrows - public String getPresignedObjectUrl(@NotBlank String bucketName, @NotBlank String objectName, + public String getPresignedObjectUrl(@NotBlank String bucket, @NotBlank String object, @NotNull Method method, @NotNull @Min(1L) @Max(DEFAULT_EXPIRY_TIME) Integer expiration) { - if (!this.bucketExists(bucketName)) { + if (!this.bucketExists(bucket)) { return null; } return this.minioClient.getPresignedObjectUrl( GetPresignedObjectUrlArgs .builder() - .bucket(bucketName) - .object(objectName) + .bucket(bucket) + .object(object) .method(method) .expiry(expiration) .build()); } @SneakyThrows - public StatObjectResponse statObject(@NotBlank String bucketName, @NotBlank String objectName) { - if (!this.bucketExists(bucketName)) { + public StatObjectResponse statObject(@NotBlank String bucket, @NotBlank String object) { + if (!this.bucketExists(bucket)) { return null; } - return this.minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(objectName).build()); + return this.minioClient.statObject(StatObjectArgs.builder().bucket(bucket).object(object).build()); } @SneakyThrows - public String getPresignedObjectUrl(@NotBlank String bucketName, @NotBlank String objectName) { - if (!this.bucketExists(bucketName)) { + public String getPresignedObjectUrl(@NotBlank String bucket, @NotBlank String object) { + if (!this.bucketExists(bucket)) { return null; } return this.minioClient.getPresignedObjectUrl( - GetPresignedObjectUrlArgs.builder().bucket(bucketName).object(objectName).build()); + GetPresignedObjectUrlArgs.builder().bucket(bucket).object(object).build()); } }