第一版华为obs的starter完成
This commit is contained in:
12
src/main/java/com/njcn/Main.java
Normal file
12
src/main/java/com/njcn/Main.java
Normal file
@@ -0,0 +1,12 @@
|
||||
package com.njcn;
|
||||
|
||||
/**
|
||||
* @author hongawen
|
||||
* @version 1.0.0
|
||||
* @date ${YEAR}年${MONTH}月${DAY}日 ${HOUR}:${MINUTE}
|
||||
*/
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
System.out.println("Hello world!");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
package com.njcn.huawei.obs.config;
|
||||
|
||||
import com.obs.services.ObsClient;
|
||||
import com.obs.services.exception.ObsException;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author hongawen
|
||||
* @version 1.0.0
|
||||
* @date 2023年03月01日 13:56
|
||||
*/
|
||||
@Data
|
||||
@Slf4j
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = HuaweiObsProperties.OBS_PREFIX)
|
||||
public class HuaweiObsProperties implements InitializingBean {
|
||||
|
||||
static final String OBS_PREFIX = "huawei";
|
||||
|
||||
private Obs obs;
|
||||
|
||||
/***
|
||||
* 华为云访问请求ak
|
||||
*/
|
||||
private String accessKey;
|
||||
|
||||
/***
|
||||
* 华为云访问请求sk
|
||||
*/
|
||||
private String securityKey;
|
||||
|
||||
|
||||
|
||||
@Data
|
||||
public static class Obs{
|
||||
|
||||
/***
|
||||
* 华为云OBS的桶名称
|
||||
*/
|
||||
private String bucket;
|
||||
|
||||
/***
|
||||
* 华为云OBS的终端节点访问路径
|
||||
*/
|
||||
private String endpoint;
|
||||
|
||||
/***
|
||||
* 文件对应url的生命周期,单位为秒
|
||||
*/
|
||||
private Long expire;
|
||||
|
||||
}
|
||||
|
||||
/***
|
||||
* 初始化连接客户端
|
||||
* @author hongawen
|
||||
* @date 2023/3/2 9:58
|
||||
* @return ObsClient
|
||||
*/
|
||||
public ObsClient getInstance(){
|
||||
return new ObsClient(accessKey, securityKey, getObs().getEndpoint());
|
||||
}
|
||||
|
||||
/***
|
||||
* 销毁客户端
|
||||
* @author hongawen
|
||||
* @date 2023/3/2 9:59
|
||||
*/
|
||||
public void destroy(ObsClient obsClient){
|
||||
if(Objects.isNull(obsClient)){
|
||||
return;
|
||||
}
|
||||
try {
|
||||
obsClient.close();
|
||||
} catch (ObsException e) {
|
||||
log.error("obs销毁异常", e);
|
||||
} catch (Exception e) {
|
||||
log.error("obs销毁发生非obs内部异常", e);
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
* 构建对象前,断言属性是否配置信息
|
||||
* @author hongawen
|
||||
* @date 2023/3/2 14:29
|
||||
*/
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
Assert.hasText(accessKey, "华为云accessKey信息必填!!");
|
||||
Assert.hasText(securityKey, "华为云securityKey信息必填!!");
|
||||
Assert.notNull(getObs(),"obs相关信息必填!!");
|
||||
Assert.hasText(getObs().bucket, "obs桶信息必填!!");
|
||||
Assert.hasText(getObs().endpoint, "obs终端节点访问路径必填!!");
|
||||
Assert.notNull(getObs().expire, "obs_url生命周期必填!!");
|
||||
}
|
||||
|
||||
}
|
||||
248
src/main/java/com/njcn/huawei/obs/util/OBSUtil.java
Normal file
248
src/main/java/com/njcn/huawei/obs/util/OBSUtil.java
Normal file
@@ -0,0 +1,248 @@
|
||||
package com.njcn.huawei.obs.util;
|
||||
|
||||
import com.njcn.huawei.obs.config.HuaweiObsProperties;
|
||||
import com.obs.services.ObsClient;
|
||||
import com.obs.services.exception.ObsException;
|
||||
import com.obs.services.model.*;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author hongawen
|
||||
* @version 1.0.0
|
||||
* @date 2023年03月01日 14:10
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class OBSUtil {
|
||||
|
||||
private final HuaweiObsProperties huaweiObsProperties;
|
||||
|
||||
|
||||
/**
|
||||
* 上传注意事项:文件名不能以 / 开头,
|
||||
* 比如错误名称:/comtrade/192.168.1.190/xxxx.dat
|
||||
* 正确名称为:comtrade/192.168.1.190/xxxx.dat
|
||||
* 上述文件名在上传文件到obs桶中时,会自动创建 comtrade、192.168.1.190两个文件夹
|
||||
* 不同的业务功能可以通过文件夹去区分,比如稳态、暂态等报表、波形文件等等
|
||||
* 前端form文件上传
|
||||
*
|
||||
* @author hongawen
|
||||
* @date 2023/3/1 20:50
|
||||
*/
|
||||
public String multiFileUpload(MultipartFile uploadFile, String fileName) {
|
||||
ObsClient obsClient = null;
|
||||
try {
|
||||
obsClient = huaweiObsProperties.getInstance();
|
||||
String bucketName = huaweiObsProperties.getObs().getBucket();
|
||||
// 判断桶是否存在
|
||||
judgeBucket(obsClient, bucketName);
|
||||
InputStream inputStream = uploadFile.getInputStream();
|
||||
long available = inputStream.available();
|
||||
PutObjectRequest request = new PutObjectRequest(bucketName, fileName, inputStream);
|
||||
ObjectMetadata objectMetadata = new ObjectMetadata();
|
||||
objectMetadata.setContentLength(available);
|
||||
request.setMetadata(objectMetadata);
|
||||
// 设置对象访问权限为公共读
|
||||
request.setAcl(AccessControlList.REST_CANNED_PUBLIC_READ);
|
||||
PutObjectResult result = obsClient.putObject(request);
|
||||
// 读取该已上传对象的URL
|
||||
log.info("已上传对象的URL" + result.getObjectUrl());
|
||||
return result.getObjectUrl();
|
||||
} catch (ObsException e) {
|
||||
log.error("obs上传失败", e);
|
||||
} catch (IOException e) {
|
||||
log.error("上传失败", e);
|
||||
} finally {
|
||||
huaweiObsProperties.destroy(obsClient);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/***
|
||||
* 流式文件上传
|
||||
* @author hongawen
|
||||
* @date 2023/3/2 10:18
|
||||
*/
|
||||
public String streamUpload(FileInputStream inputStream, String fileName) {
|
||||
ObsClient obsClient = null;
|
||||
try {
|
||||
obsClient = huaweiObsProperties.getInstance();
|
||||
String bucketName = huaweiObsProperties.getObs().getBucket();
|
||||
// 判断桶是否存在
|
||||
judgeBucket(obsClient, bucketName);
|
||||
long available = inputStream.available();
|
||||
PutObjectRequest request = new PutObjectRequest(bucketName, fileName, inputStream);
|
||||
ObjectMetadata objectMetadata = new ObjectMetadata();
|
||||
objectMetadata.setContentLength(available);
|
||||
request.setMetadata(objectMetadata);
|
||||
// 设置对象访问权限为公共读
|
||||
request.setAcl(AccessControlList.REST_CANNED_PUBLIC_READ);
|
||||
PutObjectResult result = obsClient.putObject(request);
|
||||
// 读取该已上传对象的URL
|
||||
log.info("已上传对象的URL" + result.getObjectUrl());
|
||||
return result.getObjectUrl();
|
||||
} catch (ObsException e) {
|
||||
log.error("obs上传失败", e);
|
||||
} catch (IOException e) {
|
||||
log.error("上传失败", e);
|
||||
} finally {
|
||||
huaweiObsProperties.destroy(obsClient);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/***
|
||||
* 获取文件上传后的url
|
||||
* @author hongawen
|
||||
* @date 2023/3/2 11:46
|
||||
*/
|
||||
public String getFileUrl(String fileName) {
|
||||
ObsClient obsClient = null;
|
||||
try {
|
||||
obsClient = huaweiObsProperties.getInstance();
|
||||
// URL有效期,3600秒
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
headers.put("Content-Type", "application/octet-stream");
|
||||
TemporarySignatureRequest request = new TemporarySignatureRequest(HttpMethodEnum.PUT, huaweiObsProperties.getObs().getExpire());
|
||||
request.setBucketName(huaweiObsProperties.getObs().getBucket());
|
||||
request.setObjectKey(fileName);
|
||||
request.setHeaders(headers);
|
||||
TemporarySignatureResponse response = obsClient.createTemporarySignature(request);
|
||||
return response.getSignedUrl();
|
||||
} catch (Exception e) {
|
||||
log.error("获取上传地址异常:{}", e.getMessage(), e);
|
||||
} finally {
|
||||
huaweiObsProperties.destroy(obsClient);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/***
|
||||
* 判断对象是否存在
|
||||
* @author hongawen
|
||||
* @date 2023/3/2 13:35
|
||||
*/
|
||||
public boolean judgeObjectExist(String fileName) {
|
||||
ObsClient obsClient = null;
|
||||
try {
|
||||
obsClient = huaweiObsProperties.getInstance();
|
||||
return obsClient.doesObjectExist(huaweiObsProperties.getObs().getBucket(), fileName);
|
||||
} catch (Exception e) {
|
||||
log.error("获取上传地址异常:{}", e.getMessage(), e);
|
||||
} finally {
|
||||
huaweiObsProperties.destroy(obsClient);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/***
|
||||
* 以流的形式下载文件
|
||||
* @author hongawen
|
||||
* @date 2023/3/1 20:56
|
||||
* @return InputStream
|
||||
*/
|
||||
public InputStream fileDownload(String fileName) {
|
||||
ObsClient obsClient = null;
|
||||
try {
|
||||
String bucketName = huaweiObsProperties.getObs().getBucket();
|
||||
ObsObject obsObject = obsClient.getObject(bucketName, fileName);
|
||||
return obsObject.getObjectContent();
|
||||
} catch (ObsException e) {
|
||||
log.error("obs文件下载失败", e);
|
||||
} finally {
|
||||
huaweiObsProperties.destroy(obsClient);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/***
|
||||
* 删除指定对象
|
||||
* @author hongawen
|
||||
* @date 2023/3/1 20:36
|
||||
*/
|
||||
public boolean delete(String fileName) {
|
||||
ObsClient obsClient = null;
|
||||
try {
|
||||
obsClient = huaweiObsProperties.getInstance();
|
||||
// obs删除
|
||||
obsClient.deleteObject(huaweiObsProperties.getObs().getBucket(), fileName);
|
||||
} catch (ObsException e) {
|
||||
log.error("obs删除保存失败", e);
|
||||
} finally {
|
||||
huaweiObsProperties.destroy(obsClient);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/***
|
||||
* 批量删除指定对象
|
||||
* @author hongawen
|
||||
* @date 2023/3/1 20:36
|
||||
*/
|
||||
public boolean deleteBatch(List<String> fileNames) {
|
||||
ObsClient obsClient = null;
|
||||
try {
|
||||
obsClient = huaweiObsProperties.getInstance();
|
||||
DeleteObjectsRequest deleteObjectsRequest = new DeleteObjectsRequest(huaweiObsProperties.getObs().getBucket());
|
||||
// obs批量删除
|
||||
fileNames.forEach(deleteObjectsRequest::addKeyAndVersion);
|
||||
obsClient.deleteObjects(deleteObjectsRequest);
|
||||
} catch (ObsException e) {
|
||||
log.error("obs批量删除保存失败", e);
|
||||
} finally {
|
||||
huaweiObsProperties.destroy(obsClient);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/***
|
||||
* 暂时未知河北现场的桶是否固定,将多个业务文件存在一个桶内也没问题
|
||||
* 判断是否存在桶,不存在则创建通
|
||||
* @author hongawen
|
||||
* @date 2023/3/2 10:08
|
||||
*/
|
||||
public void judgeBucket(ObsClient obsClient, String bucketName) {
|
||||
boolean exists = obsClient.headBucket(bucketName);
|
||||
if (!exists) {
|
||||
CreateBucketRequest request = new CreateBucketRequest();
|
||||
request.setBucketName(bucketName);
|
||||
// 设置桶访问权限为公共读,默认是私有读写
|
||||
request.setAcl(AccessControlList.REST_CANNED_PUBLIC_READ);
|
||||
// 设置桶的存储类型为归档存储
|
||||
request.setBucketStorageClass(StorageClassEnum.COLD);
|
||||
// 设置桶区域位置(以区域为华北-北京四为例)
|
||||
request.setLocation("cn-east-3");
|
||||
// 指定创建多AZ桶,如果不设置,默认创建单AZ桶
|
||||
request.setAvailableZone(AvailableZoneEnum.MULTI_AZ);
|
||||
// 创建桶
|
||||
try {
|
||||
// 创建桶成功
|
||||
ObsBucket bucket = obsClient.createBucket(request);
|
||||
log.info(bucket.getRequestId());
|
||||
} catch (ObsException e) {
|
||||
// 创建桶失败
|
||||
log.info("HTTP Code: " + e.getResponseCode());
|
||||
log.info("Error Code:" + e.getErrorCode());
|
||||
log.info("Error Message: " + e.getErrorMessage());
|
||||
log.info("Request ID:" + e.getErrorRequestId());
|
||||
log.info("Host ID:" + e.getErrorHostId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
5
src/main/resources/META-INF/spring.factories
Normal file
5
src/main/resources/META-INF/spring.factories
Normal file
@@ -0,0 +1,5 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
com.njcn.huawei.obs.config.HuaweiObsProperties,\
|
||||
com.njcn.huawei.obs.util.OBSUtil
|
||||
|
||||
|
||||
Reference in New Issue
Block a user