feat:存储配置添加测试连接功能

This commit is contained in:
czhqwer
2025-03-27 23:59:04 +08:00
parent a867376581
commit 7f121a0d6d
11 changed files with 190 additions and 44 deletions
@@ -2,18 +2,15 @@ package cn.czh.advice;
import cn.czh.base.BusinessException;
import cn.czh.base.Result;
import org.springframework.http.HttpStatus;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Result<?> handleValidationException(MethodArgumentNotValidException ex) {
FieldError fieldError = ex.getBindingResult().getFieldErrors().get(0);
String errorMessage = fieldError.getDefaultMessage();
@@ -21,7 +18,6 @@ public class GlobalExceptionHandler {
}
@ExceptionHandler(BusinessException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public Result<?> handleBusinessException(BusinessException e) {
return Result.error(500, e.getMessage());
}
@@ -26,4 +26,9 @@ public class ConfigController {
return Result.success();
}
@PostMapping("/test")
public Result<?> testConfig(@Valid @RequestBody StorageConfig config) {
storageConfigService.testStorageConfig(config);
return Result.success();
}
}
@@ -14,4 +14,9 @@ public interface IStorageConfigService {
*/
void updateStorageConfig(StorageConfig config);
/**
* 测试存储配置
*/
void testStorageConfig(StorageConfig config);
}
@@ -4,18 +4,26 @@ import cn.czh.base.BusinessException;
import cn.czh.context.StorageConfigUpdateEvent;
import cn.czh.entity.StorageConfig;
import cn.czh.mapper.StorageConfigMapper;
import cn.czh.mapper.UploadFileMapper;
import cn.czh.service.IStorageConfigService;
import cn.hutool.core.util.StrUtil;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.minio.BucketExistsArgs;
import io.minio.MinioClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@Slf4j
@Service
public class StorageConfigServiceImpl extends ServiceImpl<StorageConfigMapper, StorageConfig> implements IStorageConfigService {
@@ -45,4 +53,87 @@ public class StorageConfigServiceImpl extends ServiceImpl<StorageConfigMapper, S
eventPublisher.publishEvent(new StorageConfigUpdateEvent(this, config)); // 发布事件
}
@Override
public void testStorageConfig(StorageConfig config) {
switch (config.getType().toLowerCase()) {
case StorageConfig.LOCAL:
testLocalStorage(config);
break;
case StorageConfig.MINIO:
testMinioStorage(config);
break;
case StorageConfig.OSS:
testOSSStorage(config);
break;
default:
throw new IllegalArgumentException("不支持的存储类型: " + config.getType());
}
}
private void testLocalStorage(StorageConfig config) {
Path path = Paths.get(config.getBucket());
if (!Files.exists(path)) {
try {
Files.createDirectories(path);
} catch (IOException e) {
throw new BusinessException("无法创建目录: " + e.getMessage());
}
}
if (!Files.isDirectory(path)) {
throw new BusinessException("指定路径不是目录: " + config.getBucket());
}
if (!Files.isWritable(path)) {
throw new BusinessException("路径不可写: " + config.getBucket());
}
Path testFile = path.resolve("test.txt");
try {
Files.write(testFile, "test".getBytes());
Files.delete(testFile);
} catch (IOException e) {
throw new BusinessException("读写测试失败: " + e.getMessage());
}
}
private void testMinioStorage(StorageConfig config) {
if (config.getAccessKey() == null || config.getSecretKey() == null) {
throw new BusinessException("MinIO 需要提供 AccessKey 和 SecretKey");
}
MinioClient minioClient = MinioClient.builder()
.endpoint(config.getEndpoint())
.credentials(config.getAccessKey(), config.getSecretKey())
.build();
try {
BucketExistsArgs args = BucketExistsArgs.builder().bucket(config.getBucket()).build();
boolean exists = minioClient.bucketExists(args);
if (!exists) {
throw new BusinessException("Bucket 不存在: " + config.getBucket());
}
} catch (Exception e) {
throw new BusinessException("MinIO 测试失败: " + e.getMessage());
}
}
private void testOSSStorage(StorageConfig config) {
if (config.getAccessKey() == null || config.getSecretKey() == null) {
throw new BusinessException("OSS 需要提供 AccessKey 和 SecretKey");
}
OSS ossClient = new OSSClientBuilder()
.build(config.getEndpoint(), config.getAccessKey(), config.getSecretKey());
try {
ossClient.listBuckets();
} catch (Exception e) {
throw new BusinessException("OSS 测试失败: " + e.getMessage());
} finally {
ossClient.shutdown();
}
}
}