Springboot 整合aliyun.oss、huaweicloud.obs、azure.cloudblob、tencentcloud.cos、MinIO

一、Springboot 整合aliyun.oss

1. 官方文档

https://help.aliyun.com/product/31815.html?spm=a2c4g.11186623.6.540.517822372ASOvk

2. 代码

<!--生成缩略图-->
<dependency>
	<groupId>net.coobird</groupId>
	<artifactId>thumbnailator</artifactId>
	<version>0.4.8</version>
</dependency>
<dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
    <version>2.7.0</version>
</dependency>
#oss配置
spring.aliyun.endPoint=https://oss-cn-shanghai.aliyuncs.com
spring.aliyun.bucket=gaia-static
spring.aliyun.accessKeyID=
spring.aliyun.accessKeySecret=
@Configuration  
@ConfigurationProperties(prefix = "spring.aliyun")
public class AliYunConfig {
	
	@Value("${spring.aliyun.endPoint}")
    private String  endPoint;
	
	@Value("${spring.aliyun.accessKeyID}")
    private String  accessKeyID;
	
	@Value("${spring.aliyun.accessKeySecret}")
    private String  accessKeySecret;

    @Value("${cloud.switch}")
    private String cloudSwitch;

    @Bean
    public OSSClient getOOSClient() {
        if (!Constant.ALIYUN.equals(cloudSwitch)){
            return null;
        }
        return new OSSClient(endPoint, accessKeyID, accessKeySecret);
    }
}

@Component("aliyunCloudImpl")
public class AliyunCloudImpl implements CloudService{
	protected static Logger logger = LoggerFactory.getLogger(AliyunCloudImpl.class);


	@Autowired(required = false)
	private OSSClient ossClient;
	
    @Value("${spring.aliyun.bucket}")
	private String bucketName;

	@Override
	public void uploadFile(String aliyunFileKey, File file) throws Exception {
		InputStream in = null;
		try {
			in = new FileInputStream(file);
			//上传文件
			ossClient.putObject(bucketName, aliyunFileKey, in);
		}finally {
			if(in!=null) {
				try {
					in.close();
				}catch(Exception e) {
					logger.error(e.getMessage(),e);
				}
			}
		}
	}

	@Override
	public void download(String aliyunFileKey, OutputStream out) throws Exception {
		//获取对象应用
		OSSObject ossObject=ossClient.getObject(bucketName, aliyunFileKey);
		FileUtils.readFileContent(ossObject.getObjectContent(), out);
	}

	@Override
	public void delete(String aliyunFileKey) {
		//根据key删除对象
		ossClient.deleteObject(bucketName, aliyunFileKey);
		
	}

	@Override
	public String generateDownloadURL(String aliyunFileKey) {
		Date expiration = new Date(new Date().getTime() + 3600 * 1000);
		//获取对象访问链接
		return ossClient.generatePresignedUrl(bucketName, aliyunFileKey, expiration).toString();
	}

	@Override
	public void uploadAndCreateThumbnail(String aliyunFileKey, File imageFile) throws Exception {
		InputStream in = null;
		try {
			in = new FileInputStream(imageFile);
			//上传文件
			ossClient.putObject(bucketName, aliyunFileKey, in);
            logger.debug("Success upload file " + imageFile.getAbsolutePath() + ",aliyunFileKey:" + aliyunFileKey );
			//生成缩略图
			generateThumbnails(aliyunFileKey);
		}finally {
			if(in!=null) {
				try {
					in.close();
				}catch(Exception e) {
					logger.error(e.getMessage(),e);
				}
			}
		}
	}

	/**
	 * 阿里云生成缩略图命令
	 * @param aliyunFileKey
	 * @throws Exception
	 */
	private void generateThumbnails(String aliyunFileKey) throws Exception {
		GenericResult processResult=null;
		logger.debug("Start generating thumbnails");
		try {
			String thumbProcess = AliYunFileUtils.generateThumbProcess(bucketName,aliyunFileKey);
			ProcessObjectRequest request = new ProcessObjectRequest(bucketName, aliyunFileKey, thumbProcess);
			processResult = ossClient.processObject(request);
			String json = IOUtils.readStreamAsString(processResult.getResponse().getContent(), Constant.ENCODING_UTF8);
			logger.debug("End generating thumbnails:" + json);
		}finally {
			if(processResult!=null) {
				processResult.getResponse().getContent().close();
			}
		}
	}

	/**
	 * TODO 获取文件的二进制
	 *
	 * @param aliyunFileKey
	 * @return {@link byte[]}
	 * @throws
	 * @author Kuen.Hou
	 * @date 2021/10/22 11:02
	 */
	@Override
	public byte[] getFileBytes(String aliyunFileKey) throws Exception {
		//获取对象应用
		OSSObject ossObject=ossClient.getObject(bucketName, aliyunFileKey);
		byte[] imagesData = FileUtils.readFileContentToBytes(ossObject.getObjectContent());
		return imagesData;
	}
}
/*
 * 功能描述:com.gaiaworks.DeviceCloud.Service.util.AliYunFileUtils.java
 * 说   明:
 * 创建日期:2019年3月22日 上午10:03:32
 * 创 建 者:Andrew.Cai
 * Version : 1.0
 */
package com.gaiaworks.DeviceCloud.Service.utils;
@Component
public class AliYunFileUtils {
	protected static Logger logger = LoggerFactory.getLogger(AliYunFileUtils.class);

	@Autowired
	private CloudFactory cloudFactory;
	
    
    //缩略的比例
    private static String zoomStyle = "image/resize,m_fixed,w_300,h_400";
    
	/**
	 * 生成缩略图的指令字符串
	 * @param bucketName
	 * @param aliyunFileKey
	 * @return
	 * @throws IOException
	 */
	public static String generateThumbProcess(String bucketName,String aliyunFileKey) throws IOException {
		String newAliyunFileKey = aliyunFileKey.replace(".","_small.");
		StringBuilder sbStyle = new StringBuilder();
		Formatter styleFormatter = new Formatter(sbStyle);
		styleFormatter.format("%s|sys/saveas,o_%s,b_%s", zoomStyle,
				BinaryUtil.toBase64String(newAliyunFileKey.getBytes()),
				BinaryUtil.toBase64String(bucketName.getBytes()));
		styleFormatter.close();
		return sbStyle.toString();
	}
}

二、Springboot 整合huaweicloud.obs

1. 官方文档

https://support.huaweicloud.com/sdk-java-devg-obs/obs_21_0001.html

2. 代码

<!--生成缩略图-->
<dependency>
	<groupId>net.coobird</groupId>
	<artifactId>thumbnailator</artifactId>
	<version>0.4.8</version>
</dependency>
<!--添加华为云依赖 -->
<dependency>
    <groupId>com.huaweicloud</groupId>
    <artifactId>esdk-obs-java</artifactId>
    <version>3.0.3</version>
    <exclusions>
     <exclusion>
     	<groupId>org.apache.logging.log4j</groupId>
         <artifactId>log4j-api</artifactId>
     </exclusion>
     <exclusion>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
        </exclusion>
    </exclusions>
</dependency>
#华为云obs配置
spring.hwyun.endPoint=https://obs.cn-east-3.myhuaweicloud.com
spring.hwyun.bucket=
spring.hwyun.accessKeyID=
spring.hwyun.accessKeySecret=
spring.hwyun.folder=
@Configuration  
public class HuaWeiCloudConfig {
	
	@Value("${spring.hwyun.endPoint:''}")
    private String  endPoint;
	
	@Value("${spring.hwyun.accessKeyID:''}")
    private String  accessKeyID;
	
	@Value("${spring.hwyun.accessKeySecret:''}")
    private String  accessKeySecret;

    @Value("${cloud.switch}")
    private String cloudSwitch;
    

    @Bean
    public ObsClient getObsClient() {

        if (!Constant.HUAWEI.equals(cloudSwitch)){
            return null;
        }
        return new ObsClient(accessKeyID, accessKeySecret,endPoint);
    }
}
@Component("huaWeiCloudImpl")
public class HuaWeiCloudImpl implements CloudService{
	protected static Logger logger = LoggerFactory.getLogger(HuaWeiCloudImpl.class);

	@Autowired(required = false)
	private ObsClient container;
	
    @Value("${spring.hwyun.bucket:''}")
	private String bucketName;
    
    @Value("${spring.hwyun.folder:''}")
    String folder;

	@Override
	public void uploadFile(String key, File file) throws Exception {
		InputStream in = null;
		try {
			in = new FileInputStream(file);
			//上传文件
			container.putObject(bucketName, getHuaWeiKey(key), in);
		}finally {
			if(in!=null) {
				try {
					in.close();
				}catch(Exception e) {
					logger.error(e.getMessage(),e);
				}
			}
		}
	}

	@Override
	public void download(String key, OutputStream out) throws Exception {
		//获取对象应用
		ObsObject ossObject=container.getObject(bucketName, getHuaWeiKey(key));
		FileUtils.readFileContent(ossObject.getObjectContent(), out);
	}

	@Override
	public void delete(String key) throws Exception {
		container.deleteObject(bucketName, getHuaWeiKey(key));	
	}

	@Override
	public String generateDownloadURL(String key) throws Exception {
		TemporarySignatureRequest request = new TemporarySignatureRequest(HttpMethodEnum.GET, 3600);
        request.setBucketName(bucketName);
        request.setObjectKey(getHuaWeiKey(key));
        TemporarySignatureResponse response = container.createTemporarySignature(request);
 
        return response.getSignedUrl();
	}

	@Override
	public void uploadAndCreateThumbnail(String key, File imageFile) throws Exception {
		String newKey=getHuaWeiKey(key);
		InputStream in = null;
		try {
			in = new FileInputStream(imageFile);
			//上传文件
			container.putObject(bucketName, newKey, in);
            logger.debug("Success upload file " + imageFile.getAbsolutePath() + ",fileKey:" + key);
			//生成缩略图
			generateThumbnails(newKey, imageFile);
		}finally {
			if(in!=null) {
				try {
					in.close();
				}catch(Exception e) {
					logger.error(e.getMessage(),e);
				}
			}
		}
	}

	/**
	 * 生成缩略图命令
	 * @param newKey
	 * @param imageFile
	 * @throws Exception
	 */
	private void generateThumbnails(String newKey, File imageFile) throws Exception {
		InputStream in = null;
		try (InputStream input = new FileInputStream(imageFile)){
			Thumbnails.of(input).size(300, 400).toFile(imageFile);
			in = new FileInputStream(imageFile);
			//上传文件
			container.putObject(bucketName, newKey.replace(".", "_small."), in);
		} catch (Exception e) {
			logger.error("生成缩略图失败!", e);
			throw e;
		}finally {
			if(in!=null) {
				try {
					in.close();
				}catch(Exception e) {
					logger.error(e.getMessage(),e);
				}
			}
		}
	}
	
	private String getHuaWeiKey(String key) {
		return folder +"/" + key;
	}


	/**
	 * TODO 获取文件的二进制
	 *
	 * @param key
	 * @return {@link byte[]}
	 * @throws
	 * @author Kuen.Hou
	 * @date 2021/10/22 11:02
	 */
	@Override
	public byte[] getFileBytes(String key) throws Exception {
		//获取对象应用
		ObsObject ossObject=container.getObject(bucketName, getHuaWeiKey(key));
		byte[] imagesData = FileUtils.readFileContentToBytes(ossObject.getObjectContent());
		return imagesData;
	}
}

三、Springboot 整合 azure-storage

1. 官方文档

https://docs.azure.cn/zh-cn/storage/files/storage-java-how-to-use-file-storage?tabs=java

2. 代码

<!--生成缩略图-->
<dependency>
	<groupId>net.coobird</groupId>
	<artifactId>thumbnailator</artifactId>
	<version>0.4.8</version>
</dependency>
<!--微软云支持-->
<dependency>
	<groupId>com.microsoft.azure</groupId>
	<artifactId>azure-storage</artifactId>
	<version>5.0.0</version>
</dependency>
azure.storagepath=DefaultEndpointsProtocol=https;AccountName=;AccountKey=;EndpointSuffix=
azure.container=
@Configuration
public class AzureConfig {
	
	private final Logger logger = LoggerFactory.getLogger(this.getClass());
	
	@Value("${azure.storagepath}")
	private String azureStorageConnectionString;
	
	@Value("${azure.container}")
	private String containerName;

	@Value("${cloud.switch}")
	private String cloudSwitch;
	
	@Bean
	public CloudBlobContainer getAzureContainer() {
        CloudStorageAccount storageAccount = null;
		try {
			if (!Constant.AZURE.equals(cloudSwitch)){
				return null;
			}
		    //连接微软云,获取访问权限
			storageAccount = CloudStorageAccount.parse(azureStorageConnectionString);
			CloudBlobClient blobClient = storageAccount.createCloudBlobClient();
			CloudBlobContainer container = blobClient.getContainerReference(containerName);
			container.createIfNotExists(BlobContainerPublicAccessType.CONTAINER,  new BlobRequestOptions(), new OperationContext());
			return container;
		} catch (Exception e) {
			logger.error("Azure初始化失败");
			logger.error(e.getMessage(), e);
			return null;
		}
	}
}
@Component("azureCloudImpl")
public class AzureCloudImpl implements CloudService{
	protected static Logger logger = LoggerFactory.getLogger(AzureCloudImpl.class);

	@Autowired(required = false)
	private CloudBlobContainer container;

	@Override
	public void uploadFile(String azureKey, File file) throws Exception {
		InputStream in = null;
		try {
			//获取储存blob对象
			CloudBlockBlob blob = container.getBlockBlobReference(azureKey);
			in = new FileInputStream(file);
			//上传文件
			blob.upload(in, file.length());
		}finally {
			if(in!=null) {
				try {
					in.close();
				}catch(Exception e) {
					logger.error(e.getMessage(),e);
				}
			}
		}

	}

	@Override
	public void download(String azureKey, OutputStream out) throws Exception {
		//获取储存blob对象
		CloudBlockBlob blob = container.getBlockBlobReference(azureKey);
		//文件下载
		blob.download(out);
	}

	@Override
	public void delete(String azureKey) throws Exception {
		container.getBlockBlobReference(azureKey).deleteIfExists();
		
	}

	@Override
	public String generateDownloadURL(String azureKey) throws Exception {
		String url = null;
		//获取储存blob对象
		CloudBlockBlob blob = container.getBlockBlobReference(azureKey);
		if (null != blob){
			//获取对象链接
			url = blob.getUri().toString();
		}
		return url;
	}

	@Override
	public void uploadAndCreateThumbnail(String azureKey, File imageFile) throws Exception {

		//获取储存blob对象
		CloudBlockBlob blob = container.getBlockBlobReference(azureKey);
		//上传文件
		blob.uploadFromFile(imageFile.getPath());
		logger.debug("Success upload file " + imageFile.getAbsolutePath() + ",azureFileKey:" + azureKey );
		//生成缩略图
		//当执行完 try/catch后需要关闭流
		try (InputStream input = new FileInputStream(imageFile)){
			Thumbnails.of(input).size(300, 400).toFile(imageFile);
		} catch (Exception e) {
			logger.error("生成缩略图失败!", e);
			throw e;
		}

		blob = container.getBlockBlobReference(azureKey.replace(".", "_small."));
		blob.uploadFromFile(imageFile.getPath());
	}

	/**
	 * TODO 获取文件的二进制
	 *
	 * @param azureKey
	 * @return {@link byte[]}
	 * @throws
	 * @author Kuen.Hou
	 * @date 2021/10/22 11:02
	 */
	@Override
	public byte[] getFileBytes(String azureKey) throws Exception {
		//获取对象应用
		CloudBlockBlob blob = container.getBlockBlobReference(azureKey);
		byte[] imagesData = FileUtils.readFileContentToBytes(blob.openInputStream());
		return imagesData;
	}
}

四、Springboot 整合 tencentcloud

1. 官方文档

2. 代码

<!--生成缩略图-->
<dependency>
	<groupId>net.coobird</groupId>
	<artifactId>thumbnailator</artifactId>
	<version>0.4.8</version>
</dependency>
<!-- 腾讯云sdk的 -->
<dependency>
     <groupId>com.qcloud</groupId>
     <artifactId>cos_api</artifactId>
     <version>5.6.8</version>          
 </dependency>
 <dependency>
     <groupId>com.tencentcloudapi</groupId>
     <artifactId>tencentcloud-sdk-java</artifactId>
     <version>3.1.83</version><!-- 注:这里只是示例版本号,请获取并替换为 最新的版本号 -->
     <exclusions>
      <exclusion>
      	<groupId>log4j</groupId>
          <artifactId>log4j</artifactId>
      </exclusion>	            
     </exclusions>
 </dependency>
spring.tencent.endPoint=https://cos.na-toronto.myqcloud.com
spring.tencent.bucket=
spring.tencent.accessKeyID=
spring.tencent.accessKeySecret=
spring.tencent.region=
spring.tencent.appId=
@Configuration  
public class TencentCloudConfig {
	
    @Value("${spring.tencent.region:''}")
    private String region;//区域

    @Value("${spring.tencent.accessKeyID:''}")
    private String secretId;

    @Value("${spring.tencent.accessKeySecret:''}")
    private String secretKey;

    @Value("${spring.tencent.appId:''}")
    private String appId;

    @Value("${cloud.switch}")
    private String cloudSwitch;


    @Bean
    public COSClient getCOSClient() {
        if (!Constant.TENCENT.equals(cloudSwitch)) {
            return null;
        }

        //初始化腾讯云

        //1.初始化用户身份信息(secretId, secretKey)
        COSCredentials credentials = new BasicCOSCredentials(secretId, secretKey);
        // 2 设置 bucket 的区域, COS 地域的简称请参照 https://cloud.tencent.com/document/product/436/6224
        // clientConfig 中包含了设置 region, https(默认 http), 超时, 代理等 set 方法, 使用可参见源码或
        com.qcloud.cos.region.Region r = new Region(region);
        ClientConfig clientConfig = new ClientConfig(r);
        clientConfig.setSignExpired(3600);
        clientConfig.setSocketTimeout(30000);
        clientConfig.setConnectionTimeout(30000);

        COSClient cosClient = new COSClient(credentials, clientConfig);
        return cosClient;
    }

}
@Component("tencentCloudImpl")
public class TencentCloudImpl implements CloudService {
    protected static Logger logger = LoggerFactory.getLogger(TencentCloudImpl.class);

    @Autowired(required = false)
    private COSClient cosClient;

    @Value("${spring.tencent.bucket:''}")
    private String bucketName1;


    @Override
    public void uploadFile(String tencentFileKey, File file) throws Exception {
        InputStream inputStream = new FileInputStream(file);
        //文件上传
        ObjectMetadata metadata = new ObjectMetadata();
        cosClient.putObject(bucketName1,tencentFileKey,inputStream,metadata);
    }

    @Override
    public void download(String tencentFileKey, OutputStream out) throws Exception {
        //获取应用对象
        COSObject cosObject = cosClient.getObject(bucketName1,tencentFileKey);
        FileUtils.readFileContent(cosObject.getObjectContent(),out);
    }

    @Override
    public void delete(String tencentFileKey) throws Exception {
        //根据key删除对象
        cosClient.deleteObject(bucketName1,tencentFileKey);
    }

    @Override
    public String generateDownloadURL(String tencentFileKey) throws Exception {
        //获取对象访问链接
        Date expiration = new Date(new Date().getTime() + 3600 *1000);
        return cosClient.generatePresignedUrl(bucketName1,tencentFileKey,expiration).toString();
    }

    @Override
    public void uploadAndCreateThumbnail(String tencentFileKey, File file) throws Exception {

        InputStream inputStream = null;

        inputStream = new FileInputStream(file);
        ObjectMetadata metadata = new ObjectMetadata();
        cosClient.putObject(bucketName1,tencentFileKey,inputStream,metadata);
        logger.debug("Success upload file " + file.getAbsolutePath() + ",qcloudFileKey:" + tencentFileKey );
        //生成缩略图
        generateThumbnails(tencentFileKey, file);
    }
    
	/**
	 * 生成缩略图命令
	 * @param newKey
	 * @param imageFile
	 * @throws Exception
	 */
	private void generateThumbnails(String newKey, File imageFile) throws Exception {
		InputStream in = null;
		try (InputStream input = new FileInputStream(imageFile)){
			Thumbnails.of(input).size(300, 400).toFile(imageFile);
			in = new FileInputStream(imageFile);
			//上传文件
			ObjectMetadata metadata = new ObjectMetadata();
			cosClient.putObject(bucketName1, newKey.replace(".", "_small."), in,metadata);
		} catch (Exception e) {
			logger.error("生成缩略图失败!", e);
			throw e;
		}finally {
			if(in!=null) {
				try {
					in.close();
				}catch(Exception e) {
					logger.error(e.getMessage(),e);
				}
			}
		}
	}

	@Override
	public byte[] getFileBytes(String key) throws Exception {
		//获取对象应用
		COSObject cosObject = cosClient.getObject(bucketName1,key);
		byte[] imagesData = FileUtils.readFileContentToBytes(cosObject.getObjectContent());
		return imagesData;
	}
	
/*	public static void main(String[] args) throws Exception{
		TencentCloudImpl test=new TencentCloudImpl();
		test.cosClient=test.getCOSClient();
		test.uploadAndCreateThumbnail("/test/tt.jpg", new File("d:/cai.jpg"));
		
		
	}
    public COSClient getCOSClient() {

        //初始化腾讯云

        //1.初始化用户身份信息(secretId, secretKey)
        COSCredentials credentials = new BasicCOSCredentials("AKID4zhJfmsdQyPYcSCQX6QbfW7fxzmKZ2Zq", "KSK4XwM8drodS4WMzLSIrFSUXQ2SilaG");
        // 2 设置 bucket 的区域, COS 地域的简称请参照 https://cloud.tencent.com/document/product/436/6224
        // clientConfig 中包含了设置 region, https(默认 http), 超时, 代理等 set 方法, 使用可参见源码或
        com.qcloud.cos.region.Region r = new Region("na-toronto");
        ClientConfig clientConfig = new ClientConfig(r);
        clientConfig.setSignExpired(3600);
        clientConfig.setSocketTimeout(30000);
        clientConfig.setConnectionTimeout(30000);

        COSClient cosClient = new COSClient(credentials, clientConfig);
        return cosClient;
    }*/
}

五、Springboot 整合MinIO

1. 参考博客

https://blog.csdn.net/qq_41604890/article/details/114310259

2. 代码

<!--生成缩略图-->
<dependency>
	<groupId>net.coobird</groupId>
	<artifactId>thumbnailator</artifactId>
	<version>0.4.8</version>
</dependency>
<!-- minio sdk -->
<dependency>
	<groupId>io.minio</groupId>
	<artifactId>minio</artifactId>
	<version>7.0.2</version>
</dependency>
##########################上传文件大小限制###########
spring.servlet.multipart.maxFileSize=10MB
spring.servlet.multipart.maxRequestSize=100MB	
#minio
spring.minio.endpoint=
spring.minio.accessKey=
spring.minio.secretKey=
package com.gaiaworks.DeviceCloud.Runtime.config;

import com.gaiaworks.DeviceCloud.Service.common.Constant;
import io.minio.MinioClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;

/**
 * TODO
 *
 * @author Kuen.Hou
 * @date 2022/4/1 10:14
 */
@Configurable
public class MinIOConfig {
    private final Logger logger = LoggerFactory.getLogger(MinIOConfig.class);

    @Value("${spring.minio.endpoint:''}")
    private String endpoint;

    @Value("${spring.minio.accessKey:''}")
    private String accessKey;

    @Value("${spring.minio.secretKey:''}")
    private String secretKey;

    @Value("${cloud.switch}")
    private String cloudSwitch;

    @Bean
    public MinioClient getMinioClient() {
        try {
            if (!Constant.MINIO.equals(cloudSwitch)){
                return null;
            }
            return new MinioClient(endpoint, accessKey, secretKey);
        } catch (Exception e) {
            logger.error("minio初始化失败");
            logger.error(e.getMessage(), e);
            return null;
        }
    }
}
package com.gaiaworks.DeviceCloud.Service.cloud;

import com.gaiaworks.DeviceCloud.Service.util.FileUtils;
import io.minio.MinioClient;
import io.minio.PutObjectOptions;
import net.coobird.thumbnailator.Thumbnails;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * TODO
 *
 * @author Kuen.Hou
 * @date 2022/4/1 9:18spring.tencent.bucket
 */
@Component("minIOCloudImpl")
public class MinIOCloudImpl implements CloudService{
    protected static Logger logger = LoggerFactory.getLogger(MinIOCloudImpl.class);

    @Autowired(required = false)
    private MinioClient minioClient;

    @Value("spring.minio.bucket:''")
    private String bucketName;

    /**
     * 文件上传
     *
     * @param minIoKey
     * @param file
     * @throws Exception
     */
    @Override
    public void uploadFile(String minIoKey, File file) throws Exception {
        try (InputStream inputStream = new FileInputStream(file)) {
            minioClient.putObject(bucketName, minIoKey, inputStream, new PutObjectOptions(inputStream.available(), -1));
        } catch (Exception e) {
            throw e;
        }
    }

    /**
     * 文件下载
     *
     * @param minIoKey
     * @param out
     * @throws Exception
     */
    @Override
    public void download(String minIoKey, OutputStream out) throws Exception {
        try (InputStream inputStream = minioClient.getObject(bucketName, minIoKey)) {
            FileUtils.readFileContent(inputStream,out);
        } catch (Exception e) {
            throw e;
        }
    }

    /**
     * 文件删除
     *
     * @param minIoKey
     * @throws Exception
     */
    @Override
    public void delete(String minIoKey) throws Exception {
        minioClient.removeObject(bucketName, minIoKey);
    }

    /**
     * 生成访问链接
     *
     * @param minIoKey
     * @return
     * @throws Exception
     */
    @Override
    public String generateDownloadURL(String minIoKey) throws Exception {
        return minioClient.presignedGetObject(bucketName, minIoKey, 3600);
    }

    /**
     * 上传文件并生成缩略图
     *
     * @param minIoKey
     * @param file
     * @throws Exception
     */
    @Override
    public void uploadAndCreateThumbnail(String minIoKey, File file) throws Exception {
        try (InputStream inputStream = new FileInputStream(file)) {
            minioClient.putObject(bucketName, minIoKey, inputStream, new PutObjectOptions(inputStream.available(), -1));
            logger.debug("Success upload file " + file.getAbsolutePath() + ",minIoKey:" + minIoKey );
            generateThumbnails(minIoKey, file);
        } catch (Exception e) {
            throw e;
        }
    }

    /**
     * 生成缩略图命令
     * @param newKey
     * @param imageFile
     * @throws Exception
     */
    private void generateThumbnails(String newKey, File imageFile) throws Exception {
        InputStream in = null;
        try (InputStream input = new FileInputStream(imageFile)){
            Thumbnails.of(input).size(300, 400).toFile(imageFile);
            in = new FileInputStream(imageFile);
            //上传文件
            minioClient.putObject(bucketName, newKey.replace(".", "_small."), in, new PutObjectOptions(in.available(), -1));
        } catch (Exception e) {
            logger.error("生成缩略图失败!", e);
            throw e;
        }finally {
            if(in!=null) {
                try {
                    in.close();
                }catch(Exception e) {
                    logger.error(e.getMessage(),e);
                }
            }
        }
    }

    /**
     * TODO 获取文件的二进制
     *
     * @param minIoKey
     * @return {@link byte[]}
     * @throws
     * @author Kuen.Hou
     * @date 2021/10/22 11:02
     */
    @Override
    public byte[] getFileBytes(String minIoKey) throws Exception {
        InputStream inputStream = minioClient.getObject(bucketName, minIoKey);
        return FileUtils.readFileContentToBytes(inputStream);
    }
}