Skip to content

Commit

Permalink
feat($OSS): get information of an object
Browse files Browse the repository at this point in the history
  • Loading branch information
johnnymillergh committed Aug 12, 2021
1 parent 4da6876 commit 3663f06
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 48 deletions.
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -42,4 +44,11 @@ public ResponseEntity<StreamingResponseBody> 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<SerializableStatObjectResponse> statSingleResource(@PathVariable String bucket,
@PathVariable String object) {
return ResponseBodyBean.ofSuccess(this.readResourceService.stateObject(bucket, object));
}
}
Original file line number Diff line number Diff line change
@@ -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<String, List<String>> headers;
private String bucket;
private String region;
private String object;
}
Original file line number Diff line number Diff line change
@@ -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<String, String> 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;
}
}
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -41,4 +42,13 @@ ResponseEntity<StreamingResponseBody> asyncStreamSingleResource(@NotBlank String
* @return the response entity
*/
ResponseEntity<StreamingResponseBody> 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);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -79,6 +80,11 @@ public ResponseEntity<StreamingResponseBody> asyncDownloadSingleResource(@NotBla
}));
}

@Override
public SerializableStatObjectResponse stateObject(@NotBlank String bucket, @NotBlank String object) {
return SerializableStatObjectResponse.build(this.minioHelper.statObject(bucket, object));
}

@SuppressWarnings("DuplicatedCode")
private ResponseEntity<StreamingResponseBody> asyncGetResourceRegion(String bucket, String object,
StatObjectResponse statObjectResponse,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand All @@ -94,11 +94,11 @@ public List<Bucket> 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
Expand All @@ -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<String> listObjectNames(@NotBlank String bucketName) {
public List<String> listObjectNames(@NotBlank String bucket) {
val listObjectNames = new LinkedList<String>();
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());
Expand All @@ -126,55 +126,55 @@ public List<String> listObjectNames(@NotBlank String bucketName) {
}

@SneakyThrows
public Iterable<Result<Item>> listObjects(@NotBlank String bucketName) {
if (!this.bucketExists(bucketName)) {
public Iterable<Result<Item>> 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<String> removeObject(String bucketName, List<String> objectNames) {
public List<String> removeObject(String bucket, List<String> objects) {
val deleteErrorNameList = new LinkedList<String>();
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());
Expand All @@ -184,36 +184,36 @@ public List<String> removeObject(String bucketName, List<String> 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());
}
}

0 comments on commit 3663f06

Please sign in to comment.