refactor(common-oss): 优化 OSS 客户端生命周期与配置构建
- 下载 InputStream 回调后自动关闭响应流,避免底层连接释放不明确 - 统一解包异步调用异常,保留真实 S3 错误原因 - OssFactory 改为按 configKey 粒度加锁,降低多配置初始化阻塞 - OSS 配置更新和删除后主动移除本地旧客户端,释放相关资源 - 收敛 OSS region、ACL、路径风格和访问 URL 构建逻辑 - Options 新增 create 方法,保留 builder 兼容旧调用
This commit is contained in:
+32
-45
@@ -37,7 +37,9 @@ import java.util.Collection;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.CompletionException;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
@@ -119,10 +121,7 @@ public abstract class AbstractOssClientImpl implements OssClient {
|
|||||||
// 将状态转为已初始化
|
// 将状态转为已初始化
|
||||||
initialized.compareAndSet(false, true);
|
initialized.compareAndSet(false, true);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (e instanceof S3StorageException) {
|
throw toStorageException(e);
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
throw S3StorageException.form(e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,10 +167,7 @@ public abstract class AbstractOssClientImpl implements OssClient {
|
|||||||
.handleAsync(handleAsyncAction)
|
.handleAsync(handleAsyncAction)
|
||||||
.join();
|
.join();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (e instanceof S3StorageException ex) {
|
throw toStorageException(e);
|
||||||
throw ex;
|
|
||||||
}
|
|
||||||
throw S3StorageException.form(e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,10 +225,7 @@ public abstract class AbstractOssClientImpl implements OssClient {
|
|||||||
options.setLength(file.length());
|
options.setLength(file.length());
|
||||||
return bucketUpload(bucket, key, file.getChannel(), -1L, options);
|
return bucketUpload(bucket, key, file.getChannel(), -1L, options);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (e instanceof S3StorageException ex) {
|
throw toStorageException(e);
|
||||||
throw ex;
|
|
||||||
}
|
|
||||||
throw S3StorageException.form(e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,10 +246,7 @@ public abstract class AbstractOssClientImpl implements OssClient {
|
|||||||
}
|
}
|
||||||
return bucketUpload(bucket, key, in, size, options);
|
return bucketUpload(bucket, key, in, size, options);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (e instanceof S3StorageException ex) {
|
throw toStorageException(e);
|
||||||
throw ex;
|
|
||||||
}
|
|
||||||
throw S3StorageException.form(e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,10 +272,7 @@ public abstract class AbstractOssClientImpl implements OssClient {
|
|||||||
try (ByteArrayInputStream in = new ByteArrayInputStream(data)) {
|
try (ByteArrayInputStream in = new ByteArrayInputStream(data)) {
|
||||||
return bucketUpload(bucket, key, in, data.length, options);
|
return bucketUpload(bucket, key, in, data.length, options);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (e instanceof S3StorageException ex) {
|
throw toStorageException(e);
|
||||||
throw ex;
|
|
||||||
}
|
|
||||||
throw S3StorageException.form(e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -341,10 +328,7 @@ public abstract class AbstractOssClientImpl implements OssClient {
|
|||||||
.join()
|
.join()
|
||||||
.result();
|
.result();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (e instanceof S3StorageException ex) {
|
throw toStorageException(e);
|
||||||
throw ex;
|
|
||||||
}
|
|
||||||
throw S3StorageException.form(e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,25 +340,18 @@ public abstract class AbstractOssClientImpl implements OssClient {
|
|||||||
publisher.subscribe(downloadSubscriber).join();
|
publisher.subscribe(downloadSubscriber).join();
|
||||||
return getObjectResult;
|
return getObjectResult;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (e instanceof S3StorageException ex) {
|
throw toStorageException(e);
|
||||||
throw ex;
|
|
||||||
}
|
|
||||||
throw S3StorageException.form(e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T bucketDownload(String bucket, String key, BiFunction<GetObjectResult, InputStream, T> downloadTransformer) {
|
public <T> T bucketDownload(String bucket, String key, BiFunction<GetObjectResult, InputStream, T> downloadTransformer) {
|
||||||
try {
|
try (ResponseInputStream<GetObjectResponse> responseInputStream = doCustomDownload(builder -> builder.bucket(bucket).key(key), AsyncResponseTransformer.toBlockingInputStream(), null)) {
|
||||||
ResponseInputStream<GetObjectResponse> responseInputStream = doCustomDownload(builder -> builder.bucket(bucket).key(key), AsyncResponseTransformer.toBlockingInputStream(), null);
|
|
||||||
GetObjectResponse response = responseInputStream.response();
|
GetObjectResponse response = responseInputStream.response();
|
||||||
GetObjectResult getObjectResult = buildGetObjectResult(key, response);
|
GetObjectResult getObjectResult = buildGetObjectResult(key, response);
|
||||||
return downloadTransformer.apply(getObjectResult, responseInputStream);
|
return downloadTransformer.apply(getObjectResult, responseInputStream);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (e instanceof S3StorageException ex) {
|
throw toStorageException(e);
|
||||||
throw ex;
|
|
||||||
}
|
|
||||||
throw S3StorageException.form(e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -383,10 +360,7 @@ public abstract class AbstractOssClientImpl implements OssClient {
|
|||||||
try (OutputStream out = Files.newOutputStream(path)) {
|
try (OutputStream out = Files.newOutputStream(path)) {
|
||||||
return bucketDownload(bucket, key, out);
|
return bucketDownload(bucket, key, out);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (e instanceof S3StorageException ex) {
|
throw toStorageException(e);
|
||||||
throw ex;
|
|
||||||
}
|
|
||||||
throw S3StorageException.form(e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -395,10 +369,7 @@ public abstract class AbstractOssClientImpl implements OssClient {
|
|||||||
try (FileOutputStream out = new FileOutputStream(file)) {
|
try (FileOutputStream out = new FileOutputStream(file)) {
|
||||||
return bucketDownload(bucket, key, out);
|
return bucketDownload(bucket, key, out);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (e instanceof S3StorageException ex) {
|
throw toStorageException(e);
|
||||||
throw ex;
|
|
||||||
}
|
|
||||||
throw S3StorageException.form(e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -438,7 +409,7 @@ public abstract class AbstractOssClientImpl implements OssClient {
|
|||||||
s3AsyncClient.deleteObject(builder -> builder.bucket(bucket).key(key)).join();
|
s3AsyncClient.deleteObject(builder -> builder.bucket(bucket).key(key)).join();
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw S3StorageException.form(e);
|
throw toStorageException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -452,7 +423,7 @@ public abstract class AbstractOssClientImpl implements OssClient {
|
|||||||
.url()
|
.url()
|
||||||
.toExternalForm();
|
.toExternalForm();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw S3StorageException.form(e);
|
throw toStorageException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -466,7 +437,7 @@ public abstract class AbstractOssClientImpl implements OssClient {
|
|||||||
.url()
|
.url()
|
||||||
.toExternalForm();
|
.toExternalForm();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw S3StorageException.form(e);
|
throw toStorageException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -623,6 +594,22 @@ public abstract class AbstractOssClientImpl implements OssClient {
|
|||||||
return fileName.substring(index);
|
return fileName.substring(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private S3StorageException toStorageException(Throwable e) {
|
||||||
|
Throwable cause = unwrapAsyncException(e);
|
||||||
|
if (cause instanceof S3StorageException ex) {
|
||||||
|
return ex;
|
||||||
|
}
|
||||||
|
return S3StorageException.form(cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Throwable unwrapAsyncException(Throwable e) {
|
||||||
|
Throwable cause = e;
|
||||||
|
while ((cause instanceof CompletionException || cause instanceof ExecutionException) && cause.getCause() != null) {
|
||||||
|
cause = cause.getCause();
|
||||||
|
}
|
||||||
|
return cause;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws Exception {
|
public void close() throws Exception {
|
||||||
if (s3TransferManager != null) {
|
if (s3TransferManager != null) {
|
||||||
|
|||||||
+45
-39
@@ -166,38 +166,17 @@ public class OssClientConfig implements Config<OssClientConfig, OssClientConfig.
|
|||||||
* @return 客户端配置构造器
|
* @return 客户端配置构造器
|
||||||
*/
|
*/
|
||||||
public static OssClientConfigBuilder formPropertiesBuilder(OssProperties properties) {
|
public static OssClientConfigBuilder formPropertiesBuilder(OssProperties properties) {
|
||||||
String regionString = properties.getRegion();
|
|
||||||
Region region = Region.US_EAST_1;
|
|
||||||
if (StringUtils.isNotBlank(regionString)) {
|
|
||||||
region = Region.of(regionString);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 是否使用路径风格应当由使用者明确去配置,此处的配置只是为了适配旧的配置项
|
|
||||||
// MinIO 使用 HTTPS 限制使用域名访问,站点填域名。需要启用路径样式访问
|
|
||||||
boolean usePathStyleAccess = !StringUtils.containsAny(properties.getEndpoint(), OssConstant.CLOUD_SERVICE);
|
|
||||||
|
|
||||||
// 绝大多数的云厂商都是不允许操作ACL的,所以此处的默认配置也是禁用ACL的
|
|
||||||
AccessControlPolicyConfig accessControlPolicyConfig = AccessControlPolicyConfig.DEFAULT;
|
|
||||||
// 目前自定义实现的 Client 上传/下载/删除中并没有实际使用到ACL相关配置
|
|
||||||
// 仅有业务中的链接预签名使用到(SysOssServiceImpl#matchingUrl),更多只是作为一个扩展点保留,如有需要ACL的自行实现调用逻辑
|
|
||||||
String accessPolicyString = properties.getAccessPolicy();
|
|
||||||
if (StringUtils.isNotBlank(accessPolicyString)) {
|
|
||||||
accessControlPolicyConfig = AccessControlPolicyConfig.builder()
|
|
||||||
.enabled(true)
|
|
||||||
.accessPolicy(AccessPolicy.formType(accessPolicyString))
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
return builder()
|
return builder()
|
||||||
.endpoint(properties.getEndpoint())
|
.endpoint(properties.getEndpoint())
|
||||||
.domain(properties.getDomainUrl())
|
.domain(properties.getDomainUrl())
|
||||||
.accessKey(properties.getAccessKey())
|
.accessKey(properties.getAccessKey())
|
||||||
.secretKey(properties.getSecretKey())
|
.secretKey(properties.getSecretKey())
|
||||||
.bucket(properties.getBucketName())
|
.bucket(properties.getBucketName())
|
||||||
.region(region)
|
.region(parseRegion(properties.getRegion()))
|
||||||
.prefix(properties.getPrefix())
|
.prefix(properties.getPrefix())
|
||||||
.useHttps(SystemConstants.YES.equals(properties.getIsHttps()))
|
.useHttps(SystemConstants.YES.equals(properties.getIsHttps()))
|
||||||
.usePathStyleAccess(usePathStyleAccess)
|
.usePathStyleAccess(resolvePathStyleAccess(properties))
|
||||||
.accessControlPolicyConfig(accessControlPolicyConfig);
|
.accessControlPolicyConfig(resolveAccessControlPolicy(properties.getAccessPolicy()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -206,10 +185,7 @@ public class OssClientConfig implements Config<OssClientConfig, OssClientConfig.
|
|||||||
* @return 访问站点URL地址
|
* @return 访问站点URL地址
|
||||||
*/
|
*/
|
||||||
public String getEndpointUrl() {
|
public String getEndpointUrl() {
|
||||||
String endpoint = endpoint()
|
return BucketUrlUtil.rebuildUrlHeader(useHttps, getEndpoint());
|
||||||
.filter(s -> !s.isBlank())
|
|
||||||
.orElseThrow(() -> S3StorageException.form("endpoint is not configured."));
|
|
||||||
return BucketUrlUtil.rebuildUrlHeader(useHttps, endpoint);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -221,7 +197,7 @@ public class OssClientConfig implements Config<OssClientConfig, OssClientConfig.
|
|||||||
return domain()
|
return domain()
|
||||||
// 如果已经配置了自定义域名,则优先使用域名
|
// 如果已经配置了自定义域名,则优先使用域名
|
||||||
// 检查携带协议头
|
// 检查携带协议头
|
||||||
.filter(s -> HttpUtil.isHttp(s) || HttpUtil.isHttps(s))
|
.filter(OssClientConfig::hasHttpHeader)
|
||||||
// 否则使用站点
|
// 否则使用站点
|
||||||
.orElseGet(this::getEndpointUrl);
|
.orElseGet(this::getEndpointUrl);
|
||||||
}
|
}
|
||||||
@@ -245,20 +221,50 @@ public class OssClientConfig implements Config<OssClientConfig, OssClientConfig.
|
|||||||
* @return 桶URL地址
|
* @return 桶URL地址
|
||||||
*/
|
*/
|
||||||
public String getBucketUrl(String bucket) {
|
public String getBucketUrl(String bucket) {
|
||||||
// 如果已经配置了自定义域名,则优先使用域名
|
String url = getAccessBaseUrl();
|
||||||
String url = domain()
|
|
||||||
// 检查携带协议头
|
|
||||||
.filter(s -> HttpUtil.isHttp(s) || HttpUtil.isHttps(s))
|
|
||||||
// 否则使用站点
|
|
||||||
.orElseGet(() ->
|
|
||||||
endpoint()
|
|
||||||
.filter(s -> !s.isBlank())
|
|
||||||
.orElseThrow(() -> S3StorageException.form("endpoint is not configured."))
|
|
||||||
);
|
|
||||||
// 根据是否使用路径风格配置项决定存储桶的URL风格
|
// 根据是否使用路径风格配置项决定存储桶的URL风格
|
||||||
return usePathStyleAccess ? BucketUrlUtil.getPathStyleBucketUrl(useHttps, url, bucket) : BucketUrlUtil.getSiteStyleBucketUrl(useHttps, url, bucket);
|
return usePathStyleAccess ? BucketUrlUtil.getPathStyleBucketUrl(useHttps, url, bucket) : BucketUrlUtil.getSiteStyleBucketUrl(useHttps, url, bucket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Region parseRegion(String regionString) {
|
||||||
|
if (StringUtils.isBlank(regionString)) {
|
||||||
|
return Region.US_EAST_1;
|
||||||
|
}
|
||||||
|
return Region.of(regionString);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean resolvePathStyleAccess(OssProperties properties) {
|
||||||
|
// 旧配置没有显式路径风格字段,只能继续按内置云厂商 endpoint 做兼容推断。
|
||||||
|
return !StringUtils.containsAny(properties.getEndpoint(), OssConstant.CLOUD_SERVICE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static AccessControlPolicyConfig resolveAccessControlPolicy(String accessPolicyString) {
|
||||||
|
// 绝大多数云厂商不允许操作 ACL,默认禁用;当前业务只用访问策略判断是否生成预签名 URL。
|
||||||
|
if (StringUtils.isBlank(accessPolicyString)) {
|
||||||
|
return AccessControlPolicyConfig.DEFAULT;
|
||||||
|
}
|
||||||
|
return AccessControlPolicyConfig.builder()
|
||||||
|
.enabled(true)
|
||||||
|
.accessPolicy(AccessPolicy.formType(accessPolicyString))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getAccessBaseUrl() {
|
||||||
|
return domain()
|
||||||
|
.filter(OssClientConfig::hasHttpHeader)
|
||||||
|
.orElseGet(this::getEndpoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getEndpoint() {
|
||||||
|
return endpoint()
|
||||||
|
.filter(s -> !s.isBlank())
|
||||||
|
.orElseThrow(() -> S3StorageException.form("endpoint is not configured."));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean hasHttpHeader(String url) {
|
||||||
|
return HttpUtil.isHttp(url) || HttpUtil.isHttps(url);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ACL访问策略配置
|
* ACL访问策略配置
|
||||||
*/
|
*/
|
||||||
|
|||||||
+24
-7
@@ -26,7 +26,7 @@ import java.util.concurrent.locks.ReentrantLock;
|
|||||||
public class OssFactory {
|
public class OssFactory {
|
||||||
|
|
||||||
private static final Map<String, OssClient> CLIENT_CACHE = new ConcurrentHashMap<>();
|
private static final Map<String, OssClient> CLIENT_CACHE = new ConcurrentHashMap<>();
|
||||||
private static final ReentrantLock LOCK = new ReentrantLock();
|
private static final Map<String, ReentrantLock> CLIENT_LOCKS = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取默认实例
|
* 获取默认实例
|
||||||
@@ -44,13 +44,17 @@ public class OssFactory {
|
|||||||
* 根据类型获取实例
|
* 根据类型获取实例
|
||||||
*/
|
*/
|
||||||
public static OssClient instance(String configKey) {
|
public static OssClient instance(String configKey) {
|
||||||
|
if (StringUtils.isBlank(configKey)) {
|
||||||
|
throw S3StorageException.form("文件存储服务类型无法找到!");
|
||||||
|
}
|
||||||
String json = CacheUtils.get(CacheNames.SYS_OSS_CONFIG, configKey);
|
String json = CacheUtils.get(CacheNames.SYS_OSS_CONFIG, configKey);
|
||||||
if (json == null) {
|
if (json == null) {
|
||||||
throw S3StorageException.form("系统异常, '" + configKey + "'配置信息不存在!");
|
throw S3StorageException.form("系统异常, '" + configKey + "'配置信息不存在!");
|
||||||
}
|
}
|
||||||
OssProperties properties = JsonUtils.parseObject(json, OssProperties.class);
|
OssProperties properties = JsonUtils.parseObject(json, OssProperties.class);
|
||||||
OssClientConfig config = OssClientConfig.formProperties(properties);
|
OssClientConfig config = OssClientConfig.formProperties(properties);
|
||||||
LOCK.lock();
|
ReentrantLock lock = getClientLock(configKey);
|
||||||
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
OssClient client = CLIENT_CACHE.get(configKey);
|
OssClient client = CLIENT_CACHE.get(configKey);
|
||||||
if (client != null) {
|
if (client != null) {
|
||||||
@@ -63,7 +67,7 @@ public class OssFactory {
|
|||||||
CLIENT_CACHE.put(configKey, newClient);
|
CLIENT_CACHE.put(configKey, newClient);
|
||||||
return newClient;
|
return newClient;
|
||||||
} finally {
|
} finally {
|
||||||
LOCK.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,12 +75,25 @@ public class OssFactory {
|
|||||||
* 移除实例
|
* 移除实例
|
||||||
*/
|
*/
|
||||||
public static boolean remove(String configKey) {
|
public static boolean remove(String configKey) {
|
||||||
OssClient client = CLIENT_CACHE.remove(configKey);
|
if (StringUtils.isBlank(configKey)) {
|
||||||
if (client == null) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
closeClient(configKey, client);
|
ReentrantLock lock = getClientLock(configKey);
|
||||||
return true;
|
lock.lock();
|
||||||
|
try {
|
||||||
|
OssClient client = CLIENT_CACHE.remove(configKey);
|
||||||
|
if (client == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
closeClient(configKey, client);
|
||||||
|
return true;
|
||||||
|
} finally {
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ReentrantLock getClientLock(String configKey) {
|
||||||
|
return CLIENT_LOCKS.computeIfAbsent(configKey, key -> new ReentrantLock());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void closeClient(String configKey, OssClient client) {
|
private static void closeClient(String configKey, OssClient client) {
|
||||||
|
|||||||
@@ -74,6 +74,13 @@ public class Options {
|
|||||||
* 创建可选项对象
|
* 创建可选项对象
|
||||||
*/
|
*/
|
||||||
public static Options builder() {
|
public static Options builder() {
|
||||||
|
return create();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建可选项对象
|
||||||
|
*/
|
||||||
|
public static Options create() {
|
||||||
return new Options();
|
return new Options();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-3
@@ -17,6 +17,7 @@ import org.dromara.common.json.utils.JsonUtils;
|
|||||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||||
import org.dromara.common.mybatis.core.query.QueryBuilder;
|
import org.dromara.common.mybatis.core.query.QueryBuilder;
|
||||||
import org.dromara.common.oss.constant.OssConstant;
|
import org.dromara.common.oss.constant.OssConstant;
|
||||||
|
import org.dromara.common.oss.factory.OssFactory;
|
||||||
import org.dromara.common.redis.utils.CacheUtils;
|
import org.dromara.common.redis.utils.CacheUtils;
|
||||||
import org.dromara.common.redis.utils.RedisUtils;
|
import org.dromara.common.redis.utils.RedisUtils;
|
||||||
import org.dromara.system.domain.SysOssConfig;
|
import org.dromara.system.domain.SysOssConfig;
|
||||||
@@ -29,6 +30,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 对象存储配置Service业务层处理
|
* 对象存储配置Service业务层处理
|
||||||
@@ -130,6 +132,7 @@ public class SysOssConfigServiceImpl implements ISysOssConfigService {
|
|||||||
public Boolean updateByBo(SysOssConfigBo bo) {
|
public Boolean updateByBo(SysOssConfigBo bo) {
|
||||||
SysOssConfig config = MapstructUtils.convert(bo, SysOssConfig.class);
|
SysOssConfig config = MapstructUtils.convert(bo, SysOssConfig.class);
|
||||||
validEntityBeforeSave(config);
|
validEntityBeforeSave(config);
|
||||||
|
SysOssConfig oldConfig = ossConfigMapper.selectById(config.getOssConfigId());
|
||||||
boolean flag = ossConfigMapper.lambda()
|
boolean flag = ossConfigMapper.lambda()
|
||||||
.set(ObjectUtil.isNull(config.getPrefix()), SysOssConfig::getPrefix, "")
|
.set(ObjectUtil.isNull(config.getPrefix()), SysOssConfig::getPrefix, "")
|
||||||
.set(ObjectUtil.isNull(config.getRegion()), SysOssConfig::getRegion, "")
|
.set(ObjectUtil.isNull(config.getRegion()), SysOssConfig::getRegion, "")
|
||||||
@@ -140,7 +143,12 @@ public class SysOssConfigServiceImpl implements ISysOssConfigService {
|
|||||||
if (flag) {
|
if (flag) {
|
||||||
// 从数据库查询完整的数据做缓存
|
// 从数据库查询完整的数据做缓存
|
||||||
config = ossConfigMapper.selectById(config.getOssConfigId());
|
config = ossConfigMapper.selectById(config.getOssConfigId());
|
||||||
|
if (ObjectUtil.isNotNull(oldConfig) && !Objects.equals(oldConfig.getConfigKey(), config.getConfigKey())) {
|
||||||
|
CacheUtils.evict(CacheNames.SYS_OSS_CONFIG, oldConfig.getConfigKey());
|
||||||
|
OssFactory.remove(oldConfig.getConfigKey());
|
||||||
|
}
|
||||||
CacheUtils.put(CacheNames.SYS_OSS_CONFIG, config.getConfigKey(), JsonUtils.toJsonString(config));
|
CacheUtils.put(CacheNames.SYS_OSS_CONFIG, config.getConfigKey(), JsonUtils.toJsonString(config));
|
||||||
|
OssFactory.remove(config.getConfigKey());
|
||||||
}
|
}
|
||||||
return flag;
|
return flag;
|
||||||
}
|
}
|
||||||
@@ -174,12 +182,16 @@ public class SysOssConfigServiceImpl implements ISysOssConfigService {
|
|||||||
List<SysOssConfig> list = CollUtil.newArrayList();
|
List<SysOssConfig> list = CollUtil.newArrayList();
|
||||||
for (Long configId : ids) {
|
for (Long configId : ids) {
|
||||||
SysOssConfig config = ossConfigMapper.selectById(configId);
|
SysOssConfig config = ossConfigMapper.selectById(configId);
|
||||||
list.add(config);
|
if (ObjectUtil.isNotNull(config)) {
|
||||||
|
list.add(config);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
boolean flag = ossConfigMapper.deleteByIds(ids) > 0;
|
boolean flag = ossConfigMapper.deleteByIds(ids) > 0;
|
||||||
if (flag) {
|
if (flag) {
|
||||||
list.forEach(sysOssConfig ->
|
list.forEach(sysOssConfig -> {
|
||||||
CacheUtils.evict(CacheNames.SYS_OSS_CONFIG, sysOssConfig.getConfigKey()));
|
CacheUtils.evict(CacheNames.SYS_OSS_CONFIG, sysOssConfig.getConfigKey());
|
||||||
|
OssFactory.remove(sysOssConfig.getConfigKey());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return flag;
|
return flag;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user