首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >信创文件适配技术方案

信创文件适配技术方案

原创
作者头像
李福春
发布2025-10-28 16:59:28
发布2025-10-28 16:59:28
960
举报
文章被收录于专栏:研发管理经验研发管理经验

背景

当前的代码中,业务平台采用的是OSS,公有云版本的对象存储,如果做私有化交互,客户可能是在私网中,无法访问OSS或者指定使用别的厂商的对象存储,需要有平替的方案。

1. 技术架构

1.1 多存储后端支持架构

2.2 厂商SDK集成

  • 华为云: obs-java-sdk 3.22+
  • 阿里云: aliyun-sdk-oss 3.15+ + ice-sdk
  • 腾讯云: cos-java-sdk-v5 5.6+
  • 百度云: bce-java-sdk 0.10+
  • 京东云: jdcloud-sdk-java 1.6+
  • 天翼云: ctyun-oos-sdk 2.0+
  • 移动云: ecloud-java-sdk 1.0+
  • minio
  • 磁盘文件存储

2. 核心适配器实现

2.1 统一文件操作接口

代码语言:java
复制
public interface FileTemplate {
 // 基础文件操作
 String upload(InputStream inputStream, String objectName, String contentType);
 String upload(MultipartFile file, String pathType);
 String uploadBase64Image(String base64Data, String pathType);
 // URL和流式上传
 CompletableFuture<UploadTaskResult> uploadFromUrl(String sourceUrl, UploadOptions options);
 String uploadFromStream(InputStream stream, String pathType, String extension);
 // 文件管理
 FileInfo getFileInfo(String objectName);
 boolean deleteFile(String objectName);
 String copyFile(String sourceUrl, String targetPath);
 // 凭证管理
 StsCredential getStsCredential(String path, long expireSeconds, String country);
 UploadCredential getUploadCredential(String path, Date expireDate, long maxBytes);
 AssumeRoleCredential getAssumeRoleCredential(String sessionName, String allowedPath, int expireSeconds);
 // 媒体处理
 String extractVideoThumbnail(String videoUrl, int timestamp);
 MediaMetadata getMediaMetadata(String mediaUrl);
 // 健康检查
 boolean isHealthy();
 StorageMetrics getMetrics();
}

2.2 阿里云OSS适配器实现

代码语言:java
复制
@Component
@ConditionalOnProperty(name = "storage.provider", havingValue = "aliyun-oss")
public class AliyunOssAdapter implements FileTemplate {
 private final OSS ossClient;
 private final Client iceClient;
 private final AliyunOssProperties properties;
    @Override
 public String upload(InputStream inputStream, String objectName, String contentType) {
 ObjectMetadata metadata = new ObjectMetadata();
 metadata.setContentType(contentType);
 metadata.setObjectAcl(CannedAccessControlList.PublicRead);
 PutObjectRequest request = new PutObjectRequest(
 properties.getBucketName(), objectName, inputStream, metadata);
 ossClient.putObject(request);
 return buildPublicUrl(objectName);
    }
    @Override
 public String uploadBase64Image(String base64Data, String pathType) {
 // 解析base64数据
 String imageData = extractBase64Data(base64Data);
 byte[] bytes = Base64.decodeBase64(imageData);
 // 检测图片格式
 String extension = detectImageFormat(bytes);
 if (StringUtils.isBlank(extension)) {
 throw new IllegalArgumentException("不支持的图片格式");
        }
 String objectName = generateObjectName(pathType, extension);
 try (ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes)) {
 return upload(inputStream, objectName, "image/" + extension);
        } catch (IOException e) {
 throw new RuntimeException("上传失败", e);
        }
    }
    @Override
 public CompletableFuture<UploadTaskResult> uploadFromUrl(String sourceUrl, UploadOptions options) {
 return CompletableFuture.supplyAsync(() -> {
 try {
 // 创建ICE媒体上传任务
 CreateUploadMediaRequest request = new CreateUploadMediaRequest();
 request.setAppId(options.getAppName());
 request.setFileInfo(buildFileInfo(sourceUrl, options));
 request.setUserData(JsonUtils.toJson(options.getUserInfo()));
 CreateUploadMediaResponse response = iceClient.createUploadMedia(request);
 return UploadTaskResult.builder()
                    .jobId(response.getBody().getRequestId())
                    .mediaId(response.getBody().getMediaId())
                    .status("PENDING")
                    .build();
            } catch (Exception e) {
 log.error("URL上传失败: {}", sourceUrl, e);
 return UploadTaskResult.failed(e.getMessage());
            }
        });
    }
    @Override
 public StsCredential getStsCredential(String path, long expireSeconds, String country) {
 try {
 AssumeRoleRequest request = new AssumeRoleRequest();
 request.setDurationSeconds(expireSeconds);
 request.setRoleSessionName(generateSessionName());
 request.setRoleArn(properties.getRoleArn());
 request.setPolicy(buildUploadPolicy(path, expireSeconds));
 AssumeRoleResponse response = stsClient.getAcsResponse(request);
 return StsCredential.builder()
                .accessKeyId(response.getCredentials().getAccessKeyId())
                .accessKeySecret(response.getCredentials().getAccessKeySecret())
                .securityToken(response.getCredentials().getSecurityToken())
                .endpoint(selectEndpoint(country))
                .bucketName(properties.getBucketName())
                .path(path)
                .expiration(response.getCredentials().getExpiration())
                .build();
        } catch (Exception e) {
 throw new RuntimeException("获取STS凭证失败", e);
        }
    }
    @Override
 public String extractVideoThumbnail(String videoUrl, int timestamp) {
 try {
 String thumbnailUrl = videoUrl + String.format(
 "?x-oss-process=video/snapshot,t_%d,f_jpg,w_0,h_0,m_fast,ar_auto", timestamp);
 URL url = new URL(thumbnailUrl);
 try (InputStream inputStream = url.openConnection().getInputStream()) {
 String objectName = generateThumbnailName();
 return upload(inputStream, objectName, "image/jpeg");
            }
        } catch (Exception e) {
 log.error("提取视频缩略图失败: {}", videoUrl, e);
 return null;
        }
    }
 private String selectEndpoint(String country) {
 if (StringUtils.isNotBlank(country) && !"CN".equalsIgnoreCase(country)) {
 return properties.getAccelerateEndpoint();
        }
 return properties.getEndpoint();
    }
 private String buildPublicUrl(String objectName) {
 return properties.getReadEndpoint() + "/" + objectName;
    }
}

2.3 华为云OBS适配器实现

代码语言:java
复制
@Component
@ConditionalOnProperty(name = "storage.provider", havingValue = "huawei-obs")
public class HuaweiObsAdapter implements FileTemplate {
 private final ObsClient obsClient;
 private final HuaweiObsProperties properties;
    @Override
 public String upload(InputStream inputStream, String objectName, String contentType) {
 ObjectMetadata metadata = new ObjectMetadata();
 metadata.setContentType(contentType);
 PutObjectRequest request = new PutObjectRequest(
 properties.getBucketName(), objectName, inputStream, metadata);
 request.setAcl(AccessControlList.REST_CANNED_PUBLIC_READ);
 obsClient.putObject(request);
 return buildPublicUrl(objectName);
    }
    @Override
 public StsCredential getStsCredential(String path, long expireSeconds, String country) {
 // 华为云STS实现
 try {
 CreateTemporaryAccessKeyByTokenRequest request = new CreateTemporaryAccessKeyByTokenRequest();
 request.setDurationSeconds((int) expireSeconds);
 // 构建权限策略
 Policy policy = buildObsPolicy(path, expireSeconds);
 request.setPolicy(JsonUtils.toJson(policy));
 CreateTemporaryAccessKeyByTokenResponse response = iamClient.createTemporaryAccessKeyByToken(request);
 return StsCredential.builder()
                .accessKeyId(response.getCredential().getAccess())
                .accessKeySecret(response.getCredential().getSecret())
                .securityToken(response.getCredential().getSecuritytoken())
                .endpoint(properties.getEndpoint())
                .bucketName(properties.getBucketName())
                .path(path)
                .expiration(response.getCredential().getExpiresAt())
                .build();
        } catch (Exception e) {
 throw new RuntimeException("获取华为云STS凭证失败", e);
        }
    }
 // 其他方法实现...
}

3. 总结

本技术方案通过以下关键设计实现了信创适配文件存储服务的快速切换:

3.1 核心优势

  1. 统一抽象: 通过FileTemplate接口统一所有存储服务的操作
  2. 配置驱动: 支持通过配置文件动态切换存储提供商
  3. 信创兼容: 支持主流国产云存储服务3.2 扩展性设计
  4. 插件化架构: 新增存储服务只需实现FileTemplate接口
  5. 配置标准化: 统一的配置格式支持任意存储服务 该方案能够满足不同公司对文件存储服务的差异化需求,同时提供快速、可靠的切换能力,确保业务连续性和数据安全。 参考实现: OSS的实现使用S3标准,主流的对象存储直接改配置即可,如果不是s3协议,扩展一个实现方式即可支持配置。

评审意见

minio版本作为默认实现;

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
    • 1. 技术架构
      • 1.1 多存储后端支持架构
      • 2.2 厂商SDK集成
    • 2. 核心适配器实现
      • 2.1 统一文件操作接口
      • 2.2 阿里云OSS适配器实现
      • 2.3 华为云OBS适配器实现
    • 3. 总结
      • 3.1 核心优势
    • 评审意见
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档