OSS 结果文件下载分流:新增 aiimage.oss.download-endpoint 配置,result/ 前缀对象生成独立下载域名直链(默认未配置时回退原行为)
Build Backend JAR / build (push) Has been cancelled
Build Backend JAR / build (push) Has been cancelled
This commit is contained in:
@@ -9,6 +9,7 @@ public class OssProperties {
|
||||
private String region;
|
||||
private String endpoint;
|
||||
private String publicEndpoint;
|
||||
private String downloadEndpoint;
|
||||
private String bucket;
|
||||
private String imageVideoBucket;
|
||||
private String digitalHumanBucket;
|
||||
|
||||
+29
-1
@@ -302,8 +302,12 @@ public class OssStorageService {
|
||||
}
|
||||
|
||||
public String generateFreshDownloadUrl(String value) {
|
||||
StorageLocation location = resolveStorageLocation(value);
|
||||
if (location == null) {
|
||||
return getPublicUrl(value);
|
||||
}
|
||||
return buildDownloadPublicUrl(location.objectKey(), location.bucket());
|
||||
}
|
||||
|
||||
private void uploadFile(File file, String bucket, String objectKey) {
|
||||
if (file == null || !file.isFile()) {
|
||||
@@ -321,6 +325,22 @@ public class OssStorageService {
|
||||
}
|
||||
|
||||
private String getPublicUrl(String objectKey, String bucket) {
|
||||
return buildPublicUrl(trimTrailingSlash(publicEndpoint()), objectKey, bucket);
|
||||
}
|
||||
|
||||
/**
|
||||
* 结果文件(objectKey 以 {@code result/} 开头)的下载直链。
|
||||
* 配置了 download-endpoint 时走下载域名(独立出口/缓存节点),否则回退到公开 endpoint。
|
||||
*/
|
||||
private String buildDownloadPublicUrl(String objectKey, String bucket) {
|
||||
String base = downloadEndpoint();
|
||||
if (base == null || objectKey == null || !objectKey.startsWith("result/")) {
|
||||
return getPublicUrl(objectKey, bucket);
|
||||
}
|
||||
return buildPublicUrl(base, objectKey, bucket);
|
||||
}
|
||||
|
||||
private String buildPublicUrl(String baseUrl, String objectKey, String bucket) {
|
||||
String encodedPath;
|
||||
try {
|
||||
encodedPath = new URI(null, null, "/" + bucket + "/" + trimLeadingSlash(objectKey), null)
|
||||
@@ -328,7 +348,7 @@ public class OssStorageService {
|
||||
} catch (Exception ex) {
|
||||
encodedPath = "/" + bucket + "/" + trimLeadingSlash(objectKey).replace(" ", "%20");
|
||||
}
|
||||
return trimTrailingSlash(publicEndpoint()) + encodedPath;
|
||||
return trimTrailingSlash(baseUrl) + encodedPath;
|
||||
}
|
||||
|
||||
private StorageLocation resolveStorageLocation(String value) {
|
||||
@@ -488,6 +508,14 @@ public class OssStorageService {
|
||||
return withScheme(firstNonBlank(ossProperties.getPublicEndpoint(), ossProperties.getEndpoint()));
|
||||
}
|
||||
|
||||
private String downloadEndpoint() {
|
||||
String configured = ossProperties.getDownloadEndpoint();
|
||||
if (configured == null || configured.isBlank()) {
|
||||
return null;
|
||||
}
|
||||
return withScheme(configured.trim());
|
||||
}
|
||||
|
||||
private String resultObjectKey(File file, String moduleType) {
|
||||
return String.format("result/%s/%s/%s", normalizeModuleType(moduleType), UUID.randomUUID(), file.getName());
|
||||
}
|
||||
|
||||
@@ -97,6 +97,7 @@ aiimage:
|
||||
region: ${AIIMAGE_OSS_REGION:us-east-1}
|
||||
endpoint: ${AIIMAGE_OSS_ENDPOINT:https://oss.aishufu.top}
|
||||
public-endpoint: ${AIIMAGE_OSS_PUBLIC_ENDPOINT:https://oss.aishufu.top}
|
||||
download-endpoint: ${AIIMAGE_OSS_DOWNLOAD_ENDPOINT:}
|
||||
bucket: ${AIIMAGE_OSS_BUCKET:nanri-ai-images}
|
||||
image-video-bucket: ${AIIMAGE_IMAGE_VIDEO_OSS_BUCKET:shufu-video}
|
||||
digital-human-bucket: ${AIIMAGE_DIGITAL_HUMAN_OSS_BUCKET:nanri-ai-digital-human}
|
||||
|
||||
+35
-1
@@ -12,10 +12,11 @@ import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
class OssStorageServiceTest {
|
||||
|
||||
private OssStorageService storageService;
|
||||
private OssProperties properties;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
OssProperties properties = new OssProperties();
|
||||
properties = new OssProperties();
|
||||
properties.setEndpoint("https://oss.aishufu.top");
|
||||
properties.setPublicEndpoint("https://oss.aishufu.top");
|
||||
properties.setBucket("nanri-ai-images");
|
||||
@@ -93,4 +94,37 @@ class OssStorageServiceTest {
|
||||
assertNull(storageService.normalizeManagedPublicUrl(null));
|
||||
assertEquals(" ", storageService.normalizeManagedPublicUrl(" "));
|
||||
}
|
||||
|
||||
@Test
|
||||
void resultFilesUseDownloadEndpointWhenConfigured() {
|
||||
properties().setDownloadEndpoint("https://download.aishufu.top");
|
||||
assertEquals(
|
||||
"https://download.aishufu.top/nanri-ai-images/result/similar_asin/1/%E9%87%8D%E6%96%B0-result.xlsx",
|
||||
storageService.generateFreshDownloadUrl("result/similar_asin/1/重新-result.xlsx"));
|
||||
assertEquals(
|
||||
"https://download.aishufu.top/nanri-ai-images/result/similar_asin/1/re.xlsx",
|
||||
storageService.generateFreshDownloadUrl("https://oss.aishufu.top/nanri-ai-images/result/similar_asin/1/re.xlsx"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void nonResultAndUnmanagedValuesKeepPublicEndpoint() {
|
||||
properties().setDownloadEndpoint("https://download.aishufu.top");
|
||||
assertEquals(
|
||||
"https://oss.aishufu.top/nanri-ai-images/supply_images/main.jpg",
|
||||
storageService.generateFreshDownloadUrl("supply_images/main.jpg"));
|
||||
assertEquals(
|
||||
"https://download.aishufu.top/shufu-video/result/image_video/demo.mp4",
|
||||
storageService.generateFreshDownloadUrl("shufu-video/result/image_video/demo.mp4"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void downloadEndpointDisabledFallsBackToPublicEndpoint() {
|
||||
assertEquals(
|
||||
"https://oss.aishufu.top/nanri-ai-images/result/similar_asin/1/re.xlsx",
|
||||
storageService.generateFreshDownloadUrl("result/similar_asin/1/re.xlsx"));
|
||||
}
|
||||
|
||||
private OssProperties properties() {
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user