Project startup requries adding configuration file scenning path
import com.example.config.ObsProperties;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@MapperScan("com.example.dao")
@SpringBootApplication
@EnableConfigurationProperties({ObsProperties.class})
public class DemoApplication {
public static void main(String[] args) {
System.out.println("----------Service startup begins----------");
SpringApplication.run(DemoApplication.class, args);
System.out.println("-----------Service started successfully----------");
}
}
ObsProperties
Initialize HuaWeiOBSUtil class when the project starts
import com.example.utils.HuaWeiOBSUtil;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
/**
* @description: Huawei Cloud OBS configuration information
*/
@ConfigurationProperties(prefix = "obs")
public class ObsProperties {
private String domainName;
private String bucketName;
private String accessKeyId;
private String accessKeySecret;
private String endPoint;
private String privateFile;
public String getDomainName() {
return domainName;
}
public void setDomainName(String domainName) {
this.domainName = domainName;
}
public String getBucketName() {
return bucketName;
}
public void setBucketName(String bucketName) {
this.bucketName = bucketName;
}
public String getAccessKeyId() {
return accessKeyId;
}
public void setAccessKeyId(String accessKeyId) {
this.accessKeyId = accessKeyId;
}
public String getAccessKeySecret() {
return accessKeySecret;
}
public void setAccessKeySecret(String accessKeySecret) {
this.accessKeySecret = accessKeySecret;
}
public String getEndPoint() {
return endPoint;
}
public void setEndPoint(String endPoint) {
this.endPoint = endPoint;
}
public String getPrivateFile() {
return privateFile;
}
public void setPrivateFile(String privateFile) {
this.privateFile = privateFile;
}
@Bean
public HuaWeiOBSUtil obsUtility() {
return new HuaWeiOBSUtil(bucketName, accessKeyId, accessKeySecret, endPoint, privateFile);
}
}
HuaWeiOBSUtil
package com.example.utils;
import com.exampleenums.IntegerValueEnum;
import com.example.enums.StringEnum;
import com.obs.services.ObsClient;
import com.obs.services.exception.ObsException;
import com.obs.services.model.*;
import io.micrometer.common.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
/**
* @description: Huawei Cloud OBS utility class
*/
public class HuaWeiOBSUtil {
/*** File external link expiration time, 7 days */
private static long linkExpire = 7 * 24 * 60 * 60;
/*** File external link access port */
private static String accessPort = ":443";
private static String storageBucket;
private static String accessKey;
private static String secretKey;
private static String endpoint;
private static String privateFolder;
/*** OBS operation client */
private static ObsClient obsClient = null;
private static final String PATH_SEPARATOR = StringEnum.STRING_RIGHT_SLASH.getValue();
private static Logger logger = LoggerFactory.getLogger(HuaWeiOBSUtil.class);
public HuaWeiOBSUtil(String storageBucket, String accessKey, String secretKey, String endpoint, String privateFolder) {
HuaWeiOBSUtil.storageBucket = storageBucket;
HuaWeiOBSUtil.accessKey = accessKey;
HuaWeiOBSUtil.secretKey = secretKey;
HuaWeiOBSUtil.endpoint = endpoint;
HuaWeiOBSUtil.privateFolder = privateFolder;
initializeObsClient();
}
public static String getStorageBucket() {
return storageBucket;
}
public static String getAccessKey() {
return accessKey;
}
public static String getSecretKey() {
return secretKey;
}
public static String getEndpoint() {
return endpoint;
}
/**
* Get OBS operation client
*/
private static void initializeObsClient() {
synchronized (ObsClient.class) {
try {
if (obsClient == null) {
obsClient = new ObsClient(accessKey, secretKey, endpoint);
}
createStorageBucket(storageBucket, endpoint);
} catch (Exception e) {
logger.error("Connection to Huawei Cloud storage server failed: " + e.getMessage(), e);
}
}
}
/**
* Create storage bucket
*
* @param bucketName
* @param endpoint
*/
public static void createStorageBucket(String bucketName, String endpoint) {
try {
if (!checkBucketExists(bucketName)) {
CreateBucketRequest request = new CreateBucketRequest();
// Set bucket name
request.setBucketName(bucketName);
// Set bucket region location, extracted from endpoint
request.setLocation(extractRegion(endpoint));
// Set bucket access permission to public read, default is private read-write
request.setAcl(AccessControlList.REST_CANNED_PUBLIC_READ);
// Bucket created successfully
ObsBucket bucket = obsClient.createBucket(request);
logger.info("Bucket created successfully, returned RequestId: {}", bucket.getRequestId());
}
} catch (ObsException e) {
// Bucket creation failed
logger.error("HTTP Code: {}", e.getResponseCode());
logger.error("Error Code: {}", e.getErrorCode());
logger.error("Error Message: {}", e.getErrorMessage());
logger.error("Request ID: {}", e.getErrorRequestId());
logger.error("Host ID: {}", e.getErrorHostId());
}
}
public AccessControlList getObjectAcl(String objectName) {
AccessControlList objectAcl = obsClient.getObjectAcl(storageBucket, objectName);
return objectAcl;
}
/**
* Get base URL for uploaded files
*
* @return
*/
public static String getBaseUploadUrl() {
// Example: http protocol + bucket name + . + endpoint + port + /
return extractHttpProtocol(endpoint)
+ StringEnum.STRING_TWO_RIGHT_SLASH.getValue() + storageBucket + StringEnum.STRING_POINT.getValue() + endpoint
.replace(extractHttpProtocol(endpoint) + StringEnum.STRING_TWO_RIGHT_SLASH.getValue(), StringEnum.STRING_EMPTY.getValue())
+ accessPort + PATH_SEPARATOR;
}
/**
* Get base URL for uploaded files
*
* @param bucketName
* @return
*/
public static String getBaseUploadUrl(String bucketName) {
// Example: http protocol + bucket name + . + endpoint + port + /
return extractHttpProtocol(endpoint)
+ StringEnum.STRING_TWO_RIGHT_SLASH.getValue() + bucketName + StringEnum.STRING_POINT.getValue() + endpoint
.replace(extractHttpProtocol(endpoint) + StringEnum.STRING_TWO_RIGHT_SLASH.getValue(), StringEnum.STRING_EMPTY.getValue())
+ accessPort + PATH_SEPARATOR;
}
/**
* Extract region
*
* @param endpoint
* @return
*/
public static String extractRegion(String endpoint) {
String substring = endpoint.substring(endpoint.indexOf(StringEnum.STRING_POINT.getValue()) + IntegerValueEnum.ONE.getValue());
return substring.substring(IntegerValueEnum.ZERO.getValue(), substring.indexOf(StringEnum.STRING_POINT.getValue()));
}
/**
* Extract HTTP protocol
*
* @param endpoint
* @return
*/
public static String extractHttpProtocol(String endpoint) {
return endpoint.substring(IntegerValueEnum.ZERO.getValue(), endpoint.indexOf(StringEnum.STRING_COLON.getValue()));
}
/***
* Delete storage bucket
* @param bucketName*
*
* @return
*/
public static HeaderResponse deleteStorageBucket(String bucketName) {
return obsClient.deleteBucket(bucketName);
}
/***
* Check if storage bucket exists
* @param bucketName*
*
* @return
*/
public static boolean checkBucketExists(String bucketName) {
return obsClient.headBucket(bucketName);
}
/**
* Upload string content
*
* @param bucketName
* @param objectName
* @param content
* @return
*/
public static PutObjectResult uploadStringContent(String bucketName, String objectName, String content) {
if (StringUtils.isBlank(content)) {
return null;
}
// Rebuild objectName
objectName = constructObjectName(objectName);
return obsClient.putObject(bucketName, objectName, new ByteArrayInputStream(content.getBytes()));
}
/**
* Upload byte array
*
* @param bucketName
* @param objectName
* @param content
* @return
*/
public static PutObjectResult uploadBytes(String bucketName, String objectName, byte[] content, String fileName) {
return uploadInputStream(bucketName, objectName, new ByteArrayInputStream(content), fileName);
}
/**
* Upload private byte array
*
* @param bucketName
* @param objectName
* @param content
* @return
*/
public static PutObjectResult uploadPrivateBytes(String bucketName, String objectName, byte[] content, String fileName) {
return uploadInputStream(bucketName, objectName, new ByteArrayInputStream(content), fileName);
}
/**
* Upload input stream
*
* @param bucketName
* @param objectName
* @param inputStream
* @return
*/
public static PutObjectResult uploadInputStream(String bucketName, String objectName, InputStream inputStream,
String fileName) {
String acl = "private";
// Rebuild objectName
objectName = constructObjectName(objectName);
PutObjectRequest putObjectRequest = setObjectMetadata(bucketName, objectName, fileName, acl);
putObjectRequest.setInput(inputStream);
return obsClient.putObject(putObjectRequest);
}
/**
* Upload file input stream
*
* @param bucketName
* @param objectName
* @param fileInputStream
* @return
*/
public static PutObjectResult uploadFileInputStream(String bucketName, String objectName,
FileInputStream fileInputStream) {
// Rebuild objectName
objectName = constructObjectName(objectName);
return obsClient.putObject(bucketName, objectName, fileInputStream);
}
/**
* Upload via MultipartFile
*
* @param bucketName
* @param objectName
* @param media
* @return
* @throws IOException
*/
public static PutObjectResult uploadMultipartFile(String bucketName, String objectName, MultipartFile media)
throws IOException {
// Rebuild objectName
objectName = constructObjectName(objectName);
return obsClient.putObject(bucketName, objectName, media.getInputStream());
}
/**
* Upload local file
*
* @param bucketName
* @param objectName Upload save path
* @param file
* @return
*/
public static PutObjectResult uploadLocalFile(String bucketName, String objectName, File file, String acl) {
// Rebuild objectName
objectName = constructObjectName(objectName);
PutObjectRequest putObjectRequest = setObjectMetadata(bucketName, objectName, file.getName(), acl);
putObjectRequest.setFile(file);
return obsClient.putObject(putObjectRequest);
}
/**
* Download file to local
*
* @param bucketName
* @param objectName
* @param filePath
* @return
* @throws Exception
*/
public static boolean downloadFile(String bucketName, String objectName, String filePath) throws Exception {
if (StringUtils.isBlank(filePath)) {
return false;
}
// Rebuild objectName
objectName = constructObjectName(objectName);
filePath = filePath.replace("\\", PATH_SEPARATOR);
InputStream input = null;
FileOutputStream fileOutputStream = null;
try {
// Get object
ObsObject obsObject = obsClient.getObject(bucketName, objectName);
// Read object content
input = obsObject.getObjectContent();
if (input == null) {
return false;
}
// Get folder path
if (filePath.contains(PATH_SEPARATOR)) {
String dir = filePath.substring(IntegerValueEnum.ZERO.getValue(), filePath.lastIndexOf(PATH_SEPARATOR));
File dirFile = new File(dir);
if (!dirFile.exists()) {
// Create folder
boolean created = dirFile.mkdirs();
}
}
File file = new File(filePath);
fileOutputStream = new FileOutputStream(file);
byte[] b = new byte[1024];
int len;
while ((len = input.read(b)) != IntegerValueEnum.NEGATIVE_ONE.getValue()) {
fileOutputStream.write(b, IntegerValueEnum.ZERO.getValue(), len);
}
return true;
} finally {
if (fileOutputStream != null) {
fileOutputStream.close();
}
if (input != null) {
input.close();
}
}
}
/**
* Get file content
*
* @param bucketName
* @param objectName
* @return
* @throws IOException
*/
public static String getFileContent(String bucketName, String objectName) throws IOException {
// Rebuild objectName
objectName = constructObjectName(objectName);
InputStream input = null;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
ObsObject obsObject = obsClient.getObject(bucketName, objectName);
// Read object content
input = obsObject.getObjectContent();
byte[] b = new byte[1024];
int len;
while ((len = input.read(b)) != IntegerValueEnum.NEGATIVE_ONE.getValue()) {
bos.write(b, IntegerValueEnum.ZERO.getValue(), len);
}
return new String(bos.toByteArray());
} finally {
bos.close();
if (input != null) {
input.close();
}
}
}
/**
* Get file input stream
*
* @param bucketName
* @param objectName
* @return
*/
public static InputStream getFileInputStream(String bucketName, String objectName) {
// Rebuild objectName
objectName = constructObjectName(objectName);
return obsClient.getObject(bucketName, objectName).getObjectContent();
}
/**
* List objects with specified number and prefix
*
* @param bucketName
* @param prefix
* @param maxKeys
* @return
*/
public static List<ObsObject> listObjectsWithPrefix(String bucketName, String prefix, Integer maxKeys) {
prefix = prefix.startsWith(StringEnum.STRING_RIGHT_SLASH.getValue()) ? prefix.substring(IntegerValueEnum.ONE.getValue()) : prefix;
ListObjectsRequest request = new ListObjectsRequest(bucketName);
// Set number of objects to list
request.setMaxKeys(maxKeys);
// Set prefix for objects to list
request.setPrefix(prefix);
ObjectListing result = obsClient.listObjects(request);
return result.getObjects();
}
/**
* List all objects with specified prefix
*
* @param bucketName
* @param prefix
* @return
*/
public static List<ObsObject> listAllObjectsWithPrefix(String bucketName, String prefix) {
prefix = prefix.startsWith(StringEnum.STRING_RIGHT_SLASH.getValue()) ? prefix.substring(IntegerValueEnum.ONE.getValue()) : prefix;
List<ObsObject> fileList = new ArrayList<>();
ListObjectsRequest request = new ListObjectsRequest(bucketName);
// Set number of objects to list
request.setMaxKeys(1000);
// Set prefix for objects to list
request.setPrefix(prefix);
ObjectListing result;
do {
result = obsClient.listObjects(request);
request.setMarker(result.getNextMarker());
fileList.addAll(result.getObjects());
} while (result.isTruncated());
return fileList;
}
/**
* Delete single object
*
* @param bucketName
* @param objectName
* @return
*/
public static DeleteObjectResult deleteFile(String bucketName, String objectName) {
// Rebuild objectName
objectName = constructObjectName(objectName);
return obsClient.deleteObject(bucketName, objectName);
}
/**
* Copy object
*
* @param sourceBucketName
* @param sourceObjectName
* @param destBucketName
* @param destObjectName
* @return
*/
public static CopyObjectResult copyFile(String sourceBucketName, String sourceObjectName, String destBucketName,
String destObjectName) {
return obsClient.copyObject(sourceBucketName, sourceObjectName, destBucketName, destObjectName);
}
/**
* Copy object with object name reconstruction
*
* @param sourceBucketName
* @param sourceObjectName
* @param destBucketName
* @param destObjectName
* @return
*/
public static CopyObjectResult copyFileWithReconstruction(String sourceBucketName, String sourceObjectName, String destBucketName,
String destObjectName) {
// Rebuild objectName
sourceObjectName = constructObjectName(sourceObjectName);
destObjectName = constructObjectName(destObjectName);
return obsClient.copyObject(sourceBucketName, sourceObjectName, destBucketName, destObjectName);
}
/**
* Check if object exists
*
* @param bucketName
* @param objectName
* @return
*/
public static boolean checkFileExists(String bucketName, String objectName) {
// Rebuild objectName
objectName = constructObjectName(objectName);
return obsClient.doesObjectExist(bucketName, objectName);
}
/**
* Get file external link
*
* @param bucketName
* @param objectName
* @param expires Integer >= 0, in seconds
* @return
*/
public static String generateSignedUrl(String bucketName, String objectName, Long expires) {
// Rebuild objectName
objectName = constructObjectName(objectName);
TemporarySignatureRequest request = new TemporarySignatureRequest(HttpMethodEnum.GET, expires);
request.setBucketName(bucketName);
request.setObjectKey(objectName);
TemporarySignatureResponse response = obsClient.createTemporarySignature(request);
return response.getSignedUrl();
}
/**
* Get file external link - expiration time defaults to 7 days
*
* @param bucketName
* @param objectName
* @return
*/
public static String generateSignedUrl(String bucketName, String objectName) {
return generateSignedUrl(bucketName, objectName, linkExpire);
}
/**
* Rebuild objectName
*
* @param objectName
* @return
*/
private static String constructObjectName(String objectName) {
if (StringUtils.isBlank(objectName)) {
return objectName;
}
// Remove leading /
objectName = objectName.startsWith(StringEnum.STRING_RIGHT_SLASH.getValue()) ? objectName.substring(IntegerValueEnum.ONE.getValue())
: objectName;
// Remove parameters after ?
objectName = objectName.contains(StringEnum.STRING_QUESTION.getValue())
? objectName.substring(IntegerValueEnum.ZERO.getValue(), objectName.indexOf(StringEnum.STRING_QUESTION.getValue())) : objectName;
return objectName;
}
/**
* Given file external link, return objectName
*
* @param url
* @return
*/
public static String getObjectNameFromUrl(String url) {
if (StringUtils.isBlank(url)) {
return url;
}
if (url.contains(getBaseUploadUrl())) {
// Remove base path
url = url.replace(getBaseUploadUrl(), StringEnum.STRING_EMPTY.getValue());
// Remove parameters after ?
url = url.contains(StringEnum.STRING_QUESTION.getValue())
? url.substring(IntegerValueEnum.ZERO.getValue(), url.indexOf(StringEnum.STRING_QUESTION.getValue())) : url;
}
return url;
}
public static String getContentType(String fileName) {
// File extension
if (fileName.lastIndexOf(StringEnum.STRING_POINT.getValue()) < IntegerValueEnum.ZERO.getValue()) {
// Default return type
return StringEnum.STRING_EMPTY.getValue();
}
String fileExtension = fileName.substring(fileName.lastIndexOf(StringEnum.STRING_POINT.getValue()));
if (".bmp".equalsIgnoreCase(fileExtension)) {
return "image/bmp";
}
if (".gif".equalsIgnoreCase(fileExtension)) {
return "image/gif";
}
if (".jpeg".equalsIgnoreCase(fileExtension) || ".jpg".equalsIgnoreCase(fileExtension)
|| ".png".equalsIgnoreCase(fileExtension)) {
return "image/jpeg";
}
if (".png".equalsIgnoreCase(fileExtension)) {
return "image/png";
}
if (".html".equalsIgnoreCase(fileExtension)) {
return "text/html";
}
if (".txt".equalsIgnoreCase(fileExtension)) {
return "text/plain";
}
if (".vsd".equalsIgnoreCase(fileExtension)) {
return "application/vnd.visio";
}
if (".ppt".equalsIgnoreCase(fileExtension) || "pptx".equalsIgnoreCase(fileExtension)) {
return "application/vnd.ms-powerpoint";
}
if (".doc".equalsIgnoreCase(fileExtension) || "docx".equalsIgnoreCase(fileExtension)) {
return "application/msword";
}
if (".xml".equalsIgnoreCase(fileExtension)) {
return "text/xml";
}
// Default return type
return StringEnum.STRING_EMPTY.getValue();
}
/**
* Get file path
*
* @param profiles
* @param fileName
* @return
*/
public static String generateFilePath(String profiles, String fileName) {
String acl = "private";
// Get file extension
String suffix = fileName.substring(fileName.lastIndexOf(StringEnum.STRING_POINT.getValue()));
// Create directory based on date
String date = DateUtils.dateToString(new Date(), "yyyyMMdd");
StringBuffer buffer = new StringBuffer();
if (StringUtils.isNotEmpty(acl) && AccessControlList.REST_CANNED_PRIVATE.equals(convertAcl(acl))) {
buffer.append(privateFolder);
}
buffer.append(profiles).append(StringEnum.STRING_RIGHT_SLASH.getValue()).append(date)
.append(StringEnum.STRING_RIGHT_SLASH.getValue());
buffer.append(UUID.randomUUID().toString().replace(StringEnum.STRING_MINUS.getValue(), StringEnum.STRING_EMPTY.getValue()))
.append(suffix);
return buffer.toString();
}
/**
* Get file access URL
*
* @param acl
* @param filePath
* @return
*/
public static String getFileAccessUrl(String filePath, Long expires) {
filePath = generateSignedUrl(storageBucket, filePath, expires);
return filePath;
}
/**
* Set upload object properties permissions
*
* @param fileName
* @param acl
* @return
*/
public static PutObjectRequest setObjectMetadata(String bucketName, String objectName, String fileName,
String acl) {
PutObjectRequest request = new PutObjectRequest();
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentType(getContentType(fileName));
request.setMetadata(metadata);
// Set file access permission, private in this case
if (StringUtils.isNotEmpty(acl) && AccessControlList.REST_CANNED_PRIVATE.equals(convertAcl(acl))) {
request.setAcl(AccessControlList.REST_CANNED_PRIVATE);
}
request.setBucketName(bucketName);
request.setObjectKey(objectName);
return request;
}
/**
* Convert string permission
*
* @param acl
* @return
*/
public static AccessControlList convertAcl(String acl) {
AccessControlList aclObj;
switch (acl) {
case "private":
aclObj = AccessControlList.REST_CANNED_PRIVATE;
break;
case "read_write":
aclObj = AccessControlList.REST_CANNED_PUBLIC_READ_WRITE;
break;
default:
aclObj = AccessControlList.REST_CANNED_PUBLIC_READ;
}
return aclObj;
}
}