MinIO 的基本使用
MinIO 简介
MinIO是一个基于Apache License v2.0开源协议的分布式对象存储服务。兼容亚马逊S3云存储接口,它可以轻松地部署在本地、私有云或公共云环境中,并提供高性能的存储解决方案。
MinIO中的基础概念
- S3 ,是Simple Storage Service简单对存储的简称,S3提供了一个简单的服务接口,可随时的在web上的任何位置存储和检索任何数量的数据;
- Obejct ,MinIO存储的基本单位,任何存在MinIO中的事物都可以称之为一个对象(Object),如文档、图片等;
- Bucket,MinIO中一组对象的逻辑上的隔离单位,不同Bucket中的Object是相互隔离的;
- Drive,MinIO存储的物理磁盘位置,MinIO中的数据都存在Drive中;
- Set,一组Drive的集合,在分布式的环境中,自动规划一个或者多个Set,每个Set中的Drive分布在不同的位置,容灾处理。
MinIO安装
MinIO Server 安装
# 下载 minio server
wget https://dl.min.io/server/minio/release/linux-amd64/minio
# 添加可执行权限
chmod +x minio
sudo mv minio /usr/local/bin/
# 创建数据文件夹
mkdir ~/minio
# 启动minio server
minio server ~/minio --console-address :9090
# 启动输出结果
Formatting 1st pool, 1 set(s), 1 drives per set.
WARNING: Host local has more than 0 drives of set. A host failure will result in data becoming unavailable.
WARNING: Detected default credentials 'minioadmin:minioadmin', we recommend that you change these values with 'MINIO_ROOT_USER' and 'MINIO_ROOT_PASSWORD' environment variables
MinIO Object Storage Server
Copyright: 2015-2022 MinIO, Inc.
License: GNU AGPLv3 <https://www.gnu.org/licenses/agpl-3.0.html>
Version: RELEASE.2022-10-29T06-21-33Z (go1.19.2 linux/amd64)
Status: 1 Online, 0 Offline.
API: http://172.16.159.228:9000 http://172.17.0.1:9000 http://172.18.0.1:9000 http://127.0.0.1:9000
RootUser: minioadmin
RootPass: minioadmin
Console: http://172.16.159.228:9090 http://172.17.0.1:9090 http://172.18.0.1:9090 http://127.0.0.1:9090
RootUser: minioadmin
RootPass: minioadmin
Command-line: https://min.io/docs/minio/linux/reference/minio-mc.html#quickstart
$ mc alias set myminio http://172.16.159.228:9000 minioadmin minioadmin
Documentation: https://min.io/docs/minio/linux/index.html
访问web admin
从启动的日志输出中得到默认的用户名/密码(minioadmin/minioadmin)和web访问地址 http://127.0.0.1:9000, 使用用户和密码进行登录,第一次登录后建议修改默认的minioadmin密码,左侧菜单 Identity -> ServiceAccount
MinIO Client 安装
# 下载
wget https://dl.min.io/client/mc/release/linux-amd64/mc
# 添加执行权限
chmod +x mc
mv mc /usr/local/bin/mc
# 添加minio
mc alias set local http://localhost:9000 minioadmin minioadmin
# 添加成功输出信息
mc: Configuration written to `/root/.mc/config.json`. Please update your access credentials.
mc: Successfully created `/root/.mc/share`.
mc: Initialized share uploads `/root/.mc/share/uploads.json` file.
mc: Initialized share downloads `/root/.mc/share/downloads.json` file.
MinIO Client 操作
MinIO Client (mc)为ls,cat,cp,mirror,diff,find等UNIX命令提供了一种替代方案。它支持文件系统和兼容Amazon S3的云存储服务(AWS Signature v2和v4)。
mc命令
ls 列出文件和文件夹。
mb 创建一个存储桶或一个文件夹。
cat 显示文件和对象内容。
pipe 将一个STDIN重定向到一个对象或者文件或者STDOUT。
share 生成用于共享的URL。
cp 拷贝文件和对象。
mirror 给存储桶和文件夹做镜像。
find 基于参数查找文件。
diff 对两个文件夹或者存储桶比较差异。
rm 删除文件和对象。
events 管理对象通知。
watch 监听文件和对象的事件。
policy 管理访问策略。
session 为cp命令管理保存的会话。
config 管理mc配置文件。
update 检查软件更新。
version 输出版本信息。
mb 创建Bucket
# 在local上创建一个test的Bucket
mc mb local/test
Bucket created successfully `local/test`.
cp 拷贝一个对象到MinIO Server中
echo 'hello minio'> hellominio.txt
mc cp hellominio.txt local/test
/root/hellominio.txt: 12 B / 12 B
ls 查看Bucket和Obeject
mc ls local
# 刚刚创建的 test Bucket 中存在一个 hellominio.txt
[2022-11-05 20:32:30 CST] 12B STANDARD hellominio.txt
通过MinIO server web 查看
cat 显示对象的内容
mc cat local/test/hellominio.txt
hello minio
pipe 通过pipe将stdin输出到对象
echo 'pipe test'> pipe.txt
# 将输出重定向到local/test/pipe.txt
cat pipe.txt | mc pipe local/test/pipe.txt
# 查看生成的对象内容
mc cat local/test/pipe.txt
pipe test
find 查找Object
# 查找所有 txt 文本文件
mc find local/test --name "*.txt"
local/test/hellominio.txt
local/test/pipe.txt
share 将对象以带有认证和过期机制的URL机制共享
share download 共享下载
share download
命令生成不需要access key和secret key即可下载的URL,过期参数设置成最大有效期(不大于7天),过期之后权限自动回收。
# 为hellominio.txt生成有限期3天的URL
mc share download --expire 72h local/test/hellominio.txt
URL: http://localhost:9000/test/hellominio.txt
Expire: 3 days 0 hours 0 minutes 0 seconds
Share: http://localhost:9000/test/hellominio.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=minioadmin%2F20221105%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20221105T131412Z&X-Amz-Expires=259200&X-Amz-SignedHeaders=host&X-Amz-Signature=fd3df574faf2276ff47995a361ee1260093bee273d546c76d9ca9f955cc04cdd
share upload 共享上传
share upload
命令生成不需要access key和secret key即可上传的URL。过期参数设置成最大有效期(不大于7天),过期之后权限自动回收。 Content-type参数限制只允许上传指定类型的文件。
# 生成上传helloworld
mc share upload local/test/helloword.txt
RL: http://localhost:9000/test/helloword.txt
Expire: 7 days 0 hours 0 minutes 0 seconds
Share: curl http://localhost:9000/test/ -F x-amz-credential=minioadmin/20221105/us-east-1/s3/aws4_request -F x-amz-date=20221105T132630Z -F x-amz-signature=cfd000de2c2494c7fed1c232e5b0a41bb8fb4c7c96a4cb595506910bb7a6a23d -F bucket=test -F policy=eyJleHBpcmF0aW9uIjoiMjAyMi0xMS0xMlQxMzoyNjozMC41MjRaIiwiY29uZGl0aW9ucyI6W1siZXEiLCIkYnVja2V0IiwidGVzdCJdLFsiZXEiLCIka2V5IiwiaGVsbG93b3JkLnR4dCJdLFsiZXEiLCIkeC1hbXotZGF0ZSIsIjIwMjIxMTA1VDEzMjYzMFoiXSxbImVxIiwiJHgtYW16LWFsZ29yaXRobSIsIkFXUzQtSE1BQy1TSEEyNTYiXSxbImVxIiwiJHgtYW16LWNyZWRlbnRpYWwiLCJtaW5pb2FkbWluLzIwMjIxMTA1L3VzLWVhc3QtMS9zMy9hd3M0X3JlcXVlc3QiXV19 -F x-amz-algorithm=AWS4-HMAC-SHA256 -F key=helloword.txt -F file=@<FILE>
# 通过生成的URL上传
echo 'hello world' >helloworld.txt
# -F file=./helloworld.txt
curl http://localhost:9000/test/ -F x-amz-credential=minioadmin/20221105/us-east-1/s3/aws4_request -F x-amz-date=20221105T132630Z -F x-amz-signature=cfd000de2c2494c7fed1c232e5b0a41bb8fb4c7c96a4cb595506910bb7a6a23d -F bucket=test -F policy=eyJleHBpcmF0aW9uIjoiMjAyMi0xMS0xMlQxMzoyNjozMC41MjRaIiwiY29uZGl0aW9ucyI6W1siZXEiLCIkYnVja2V0IiwidGVzdCJdLFsiZXEiLCIka2V5IiwiaGVsbG93b3JkLnR4dCJdLFsiZXEiLCIkeC1hbXotZGF0ZSIsIjIwMjIxMTA1VDEzMjYzMFoiXSxbImVxIiwiJHgtYW16LWFsZ29yaXRobSIsIkFXUzQtSE1BQy1TSEEyNTYiXSxbImVxIiwiJHgtYW16LWNyZWRlbnRpYWwiLCJtaW5pb2FkbWluLzIwMjIxMTA1L3VzLWVhc3QtMS9zMy9hd3M0X3JlcXVlc3QiXV19 -F x-amz-algorithm=AWS4-HMAC-SHA256 -F key=helloword.txt -F file=./helloworld.txt
# 查看是否上传成功
mc ls local/test
[2022-11-05 20:52:32 CST] 12B STANDARD hellominio.txt
[2022-11-05 21:27:49 CST] 16B STANDARD helloword.txt
[2022-11-05 20:41:34 CST] 10B STANDARD pipe.txt
share list 查看当前的share列表
# share download list
mc share list download
# share upload list
mc share list upload
rm 删除Bucket和Object
# 删除一个对象
mc rm local/test/hellominio.txt
Removed `local/test/hellominio.txt`
# 删除一个Bucket及其中的所有对象
mc rm --recursive --force local/test
Removed `local/test/hellominio.txt`.
Removed `local/test/helloword.txt`.
Removed `local/test/pipe.txt`.
# 按时间删除
# 删除一天前的对象
mc rm --force --older-than=1d local/test/
更多命令使用参考官方使用文档,MinIO Client指南
SpringBoot集成MinIO
添加依赖
- minio 依赖
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.2.1</version>
</dependency>
- 完整 pom 文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.autumnin</groupId>
<artifactId>minio-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>minio-demo</name>
<description>minio-demo</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.2.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- application.yml
server:
port: 8080
spring:
application:
name: MinIO-demo
servlet:
multipart:
max-file-size: 100MB # 单个文件上传的大小
max-request-size: 100MB # 设置单次请求的文件的总大小
# MinIO配置
minio:
endpoint: http://182.92.0.107:9000
accessKey: minioadmin
secretKey: minioadmin
Java 代码
- MinIOConfig配置类
package com.geekyous.minio.config;
import io.minio.MinioClient;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* MinIO配置
*/
@Configuration
@EnableConfigurationProperties(MinIOProperties.class)
public class MinIOConfig {
private final MinIOProperties properties;
public MinIOConfig(MinIOProperties properties) {
this.properties = properties;
}
/**
* 注入 MinIOClient
*
* @return MinIOClient
*/
@Bean
public MinioClient minioClient() {
return MinioClient.builder().endpoint(properties.getEndpoint())
.credentials(properties.getAccessKey(), properties.getSecretKey())
.build();
}
}
- MinIOProperties 配置属性
package com.geekyous.minio.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* MinIO的配置属性
*/
@ConfigurationProperties(prefix = "minio")
public class MinIOProperties {
private String endpoint;
private String accessKey;
private String secretKey;
public String getEndpoint() {
return endpoint;
}
public void setEndpoint(String endpoint) {
this.endpoint = endpoint;
}
public String getAccessKey() {
return accessKey;
}
public void setAccessKey(String accessKey) {
this.accessKey = accessKey;
}
public String getSecretKey() {
return secretKey;
}
public void setSecretKey(String secretKey) {
this.secretKey = secretKey;
}
}
- BucketOperator 封装 MinIO 操作类
package com.geekyous.minio.bucket;
import com.geekyous.minio.config.MinIOProperties;
import io.minio.*;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* bucket 操作类
**/
@Component
public class BucketOperator {
private final static Logger logger = LoggerFactory.getLogger(BucketOperator.class);
private final MinioClient minioClient;
private final MinIOProperties properties;
public BucketOperator(MinioClient minioClient, MinIOProperties properties) {
this.minioClient = minioClient;
this.properties = properties;
}
/**
* 创建给定 bucketName的bucket
*
* @param bucketName bucket name
* @return Result
*/
public Result create(String bucketName) {
try {
if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
String url = String.format("%s/%s", properties.getEndpoint(), bucketName);
return Result.builder().url(url).type(Result.Type.BUCKET).state(Result.State.SUCCESS).build();
} else {
return Result.builder().type(Result.Type.BUCKET).state(Result.State.FAILED).exception(new RuntimeException(String.format("[%s] bucket already exists", bucketName))).build();
}
} catch (Exception e) {
e.printStackTrace();
return Result.builder().type(Result.Type.BUCKET).state(Result.State.FAILED).exception(e).build();
}
}
/**
* 创建给定 bucketName的bucket
*
* @param bucketName bucket name
* @return Result
*/
public Result createIfNotExists(String bucketName) {
try {
if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
} else {
logger.warn(String.format("[%s] bucket already exists", bucketName));
}
String url = String.format("%s/%s", properties.getEndpoint(), bucketName);
return Result.builder().url(url).type(Result.Type.BUCKET).state(Result.State.SUCCESS).build();
} catch (Exception e) {
return Result.builder().type(Result.Type.BUCKET).state(Result.State.FAILED).exception(e).build();
}
}
/**
* 获取所有的buket
*
* @return List<Bucket>
*/
public Result getAll() {
try {
List<Bucket> buckets = minioClient.listBuckets();
return Result.builder().buckets(buckets).type(Result.Type.BUCKET).state(Result.State.SUCCESS).build();
} catch (Exception e) {
e.printStackTrace();
return Result.builder().type(Result.Type.BUCKET).state(Result.State.FAILED).exception(e).build();
}
}
/**
* 根据 bucket name 获取指定的bucket
*
* @param bucketName bucket 名称
* @return Bucket
*/
public Result get(String bucketName) {
try {
Bucket bucket = minioClient.listBuckets().stream().filter(item -> item.name().equals(bucketName)).findFirst().orElse(null);
return Result.builder().bucket(bucket).type(Result.Type.BUCKET).state(Result.State.SUCCESS).build();
} catch (Exception e) {
e.printStackTrace();
return Result.builder().type(Result.Type.BUCKET).state(Result.State.FAILED).exception(e).build();
}
}
/**
* 移除给定bucket name的bucket
*
* @param bucketName bucket name
* @result Result
*/
public Result remove(String bucketName) {
try {
minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());
return Result.builder().type(Result.Type.BUCKET).state(Result.State.SUCCESS).build();
} catch (Exception e) {
e.printStackTrace();
return Result.builder().exception(e).build();
}
}
/**
* 获取给定bucket中的object
*
* @param bucketName bucket name
* @param objectName object name
* @return Result
*/
public Result getObject(String bucketName, String objectName) {
try {
GetObjectResponse response = minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(objectName).build());
return Result.builder().type(Result.Type.OBJECT).state(Result.State.SUCCESS).ins(response).build();
} catch (Exception e) {
return Result.builder().type(Result.Type.OBJECT).state(Result.State.FAILED).exception(e).build();
}
}
/**
* 获取对象的URL
*
* @param bucketName bucket name
* @param objectName object name
* @return
*/
public Result getObjectUrl(Method method, String bucketName, String objectName, int expire, TimeUnit unit) {
try {
String url = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().bucket(bucketName).object(objectName).expiry(expire, unit).method(method).build());
return Result.builder().url(url).type(Result.Type.OBJECT).state(Result.State.SUCCESS).build();
} catch (Exception e) {
e.printStackTrace();
return Result.builder().type(Result.Type.OBJECT).state(Result.State.FAILED).exception(e).build();
}
}
/**
* @param bucketName bucket name
* @param objectName object name
* @param ins 文件流
* @param size 文件大小
* @param contentType 文件类型
*/
public Result putObject(String bucketName, String objectName, InputStream ins, long size, String contentType) {
try {
Result exists = createIfNotExists(bucketName);
if (exists.getException() != null) {
return Result.builder().type(Result.Type.OBJECT).state(Result.State.FAILED).exception(exists.getException()).build();
}
minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName).stream(ins, size, -1).contentType(contentType).build());
String url = String.format("%s/%s%s", properties.getEndpoint(), bucketName, objectName);
return Result.builder().url(url).type(Result.Type.OBJECT).state(Result.State.SUCCESS).build();
} catch (Exception e) {
e.printStackTrace();
return Result.builder().type(Result.Type.OBJECT).state(Result.State.FAILED).exception(e).build();
}
}
/**
* @param bucketName bucket name
* @param objectName object name
* @param ins file input stream
*/
public Result putObject(String bucketName, String objectName, InputStream ins) {
try {
String contentType = objectName.substring(objectName.lastIndexOf("."));
int size = ins.available();
return putObject(bucketName, objectName, ins, size, contentType);
} catch (Exception e) {
e.printStackTrace();
return Result.builder().type(Result.Type.OBJECT).state(Result.State.FAILED).exception(e).build();
}
}
/**
* @param file
* @param bucketName
* @param objectName
*/
public Result putObject(MultipartFile file, String bucketName, String objectName) {
if (file == null) {
logger.error("file can not be null");
return Result.builder().type(Result.Type.OBJECT).state(Result.State.FAILED).exception(new Exception("file can not be null")).build();
}
if (objectName == null) {
objectName = file.getOriginalFilename();
}
try {
InputStream ins = file.getInputStream();
long size = file.getSize();
String contentType = file.getContentType();
return putObject(bucketName, objectName, ins, size, contentType);
} catch (IOException e) {
e.printStackTrace();
return Result.builder().type(Result.Type.OBJECT).state(Result.State.FAILED).exception(e).build();
}
}
/**
* 删除给定的 bucket的object
*
* @param bucketName bucket name
* @param objectName object name
*/
public Result removeObject(String bucketName, String objectName) {
try {
minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(objectName).build());
return Result.builder().type(Result.Type.OBJECT).state(Result.State.SUCCESS).build();
} catch (Exception e) {
e.printStackTrace();
return Result.builder().type(Result.Type.OBJECT).state(Result.State.FAILED).exception(e).build();
}
}
}
- 封装操作结果 Result
package com.geekyous.minio.bucket;
import io.minio.messages.Bucket;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.List;
/**
* bucket 操作结果
**/
public class Result {
private final String url;
private final Type type;
private final State state;
private final InputStream ins;
private final Bucket bucket;
private final List<Bucket> buckets;
private final Exception exception;
private final LocalDateTime updateTime;
private Result(Builder builder) {
this.url = builder.url;
this.type = builder.type;
this.state = builder.state;
this.bucket = builder.bucket;
this.buckets = builder.buckets;
this.ins = builder.ins;
this.exception = builder.exception;
this.updateTime = builder.updateTime;
}
public String getUrl() {
return url;
}
public Type getType() {
return type;
}
public State getState() {
return state;
}
public InputStream getIns() {
return ins;
}
public Bucket getBucket() {
return bucket;
}
public List<Bucket> getBuckets() {
return buckets;
}
public Exception getException() {
return exception;
}
public LocalDateTime getUpdateTime() {
return updateTime;
}
public static Builder builder() {
return new Builder();
}
protected static class Builder {
private String url;
private Type type;
private State state;
private InputStream ins;
private Bucket bucket;
private List<Bucket> buckets;
private Exception exception;
private LocalDateTime updateTime = LocalDateTime.now();
public Builder url(String url) {
this.url = url;
return this;
}
public Builder type(Type type) {
this.type = type;
return this;
}
public Builder state(State state) {
this.state = state;
return this;
}
public Builder updateTime(LocalDateTime updateTime) {
this.updateTime = updateTime;
return this;
}
public Builder bucket(Bucket bucket) {
this.bucket = bucket;
return this;
}
public Builder buckets(List<Bucket> buckets) {
this.buckets = buckets;
return this;
}
public Builder ins(InputStream ins) {
this.ins = ins;
return this;
}
public Builder exception(Exception exception) {
this.exception = exception;
return this;
}
public Result build() {
if (this.state == State.FAILED && this.exception == null) {
throw new RuntimeException("exception can not be null when state is failed");
}
return new Result(this);
}
}
enum State {
SUCCESS,
FAILED,
}
enum Type {
BUCKET,
OBJECT
}
@Override
public String toString() {
return "Result{" +
"url='" + url + '\'' +
", type=" + type +
", state=" + state +
", ins=" + ins +
", bucket=" + bucket +
", buckets=" + buckets +
", exception=" + exception +
", updateTime=" + updateTime +
'}';
}
}
- BucketOperatorTest 测试类
package com.geekyous.minio.bucket;
import io.minio.http.Method;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import java.io.*;
import java.util.concurrent.TimeUnit;
import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
class BucketOperatorTest {
private final static Logger logger = LoggerFactory.getLogger(BucketOperatorTest.class);
@Autowired
private BucketOperator bucketOperator;
@Test
void create() {
Result bucket = bucketOperator.create("bucket-test");
assertNull(bucket.getException());
}
@Test
void createIfNotExists() {
Result result = bucketOperator.create("bucket-test");
assertNotNull(result.getException());
assertEquals(result.getState(), Result.State.FAILED);
}
@Test
void getAll() {
Result result = bucketOperator.getAll();
assertNull(result.getException());
assertEquals(result.getState(), Result.State.SUCCESS);
assertTrue(result.getBuckets().stream().anyMatch(i -> i.name().equals("bucket-test")));
}
@Test
void get() {
Result result = bucketOperator.get("bucket-test");
assertNull(result.getException());
assertEquals(result.getState(), Result.State.SUCCESS);
assertEquals(result.getBucket().name(), "bucket-test");
}
@Test
void remove() {
Result result = bucketOperator.remove("bucket-test");
assertEquals(result.getState(), Result.State.SUCCESS);
assertNull(result.getException());
}
@Test
void putObject() {
try {
Resource resource = new ClassPathResource("object-test.txt");
InputStream ins = resource.getInputStream();
Result result = bucketOperator.putObject("bucket-test", "object.txt", ins);
assertNull(result.getException());
assertEquals(result.getState(), Result.State.SUCCESS);
assertNotNull(result.getUrl());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Test
void getObject() {
try {
Result result = bucketOperator.getObject("bucket-test", "object.txt");
assertEquals(result.getState(), Result.State.SUCCESS);
assertNull(result.getException());
FileOutputStream fos = null;
fos = new FileOutputStream("./object1.txt");
byte[] b = new byte[1024];
while ((result.getIns().read(b)) != -1) {
fos.write(b);
}
result.getIns().close();
fos.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Test
void getObjectUrl() {
Result result = bucketOperator.getObjectUrl(Method.GET, "bucket-test", "object.txt", 1, TimeUnit.HOURS);
assertNull(result.getException());
assertEquals(result.getState(), Result.State.SUCCESS);
logger.info(result.getUrl());
}
@Test
void removeObject() {
Result result = bucketOperator.removeObject("bucket-test", "object.txt");
assertEquals(result.getState(), Result.State.SUCCESS);
assertNull(result.getException());
}
}