# 对象存储扩展适配

# 前言

在协同中,产品的附件、动态资源文件都需要存储管理,产品默认提供了文件存储(共享存储)的方式,自V8.1SP2开始产品又提供了华为云OBS对象存储的标准支持(直接配置使用),但并未标准提供阿里OSS、亚马逊对象存储等其它厂商的对象存储(此类厂商均需要参考本文档做二次开发)。

但针对不同公司的对象存储可能有不同的需求,如使用不同的对象存储厂商、存储在云端或存储在自己的私有存储服务上,因此需要抽象对象存储的接口,让客户在使用时,仅通过实现对象存储的接口即可在协同应用中使用自己的存储服务。本手册提供V5产品对象存储接口文档,供项目上参考适配,以应对不同对象存储厂商二次开发适配。

# 三方对象存储集成实现方法

# 三方对象存储二次开发适配案例

如有三方对象存储二次开发适配诉求,可通过CTP-STUDIO平台检索相似修改接口,看别的项目如何接入实现。

1767509637178.png

# 1、实现RemoteFileHandler接口

接口名称:com.seeyon.ctp.common.file.remote.RemoteFileHandler

说明:对象存储的处理实现类,包含对象的存、改、查等。

不同版本接口方法可能存在变化,需要继承实现当前接口,具体继承实现方案可参考标准的 ctp-file/src/main/java/com/seeyon/ctp/common/file/HuaWeiObsHandler.java

接口方法详细说明:

/**
 * 三方文件存储操作
 * 主要上传,下载文件
 */
public interface RemoteFileHandler {
    /**
     * 获取文件元信息
     * @param fileName  对象存储key
     * @return 文件的元信息
     */
    CtpMetaData headFile(String fileName) throws IOException;

    /**
     * 下载文件为流
     * @param fileName 对象存储key
     * @return 返回文件流
     * @throws IOException
     */
    InputStream downLoadFile(String fileName) throws IOException;

    /**
     * 上传文件
     * @param fileName 保存的对象存储key
     * @param inputStream 上传的数据流
     * @throws IOException
     */
    void uploadFile(String fileName, InputStream inputStream) throws IOException;

    /**
     * 上传文件
     * @param fileName 保存的对象存储key
     * @param file 上传的文件对象
     * @throws IOException
     */
    void uploadFile(String fileName, File file) throws IOException;

    /**
     * 上传文件
     * @param fileName 保存的对象存储key
     * @param file 上传的文件对象
     * @param metaData 文件的元数据信息
     * @throws IOException
     */
    void uploadFile(String fileName, File file, CtpMetaData metaData) throws IOException;

    /**
     * 上传文件
     * @param fileName 保存的对象存储key
     * @param inputStream 上传的数据流
     * @param metaData 文件的元数据信息
     * @throws IOException
     */
    void uploadFile(String fileName, InputStream inputStream, CtpMetaData metaData) throws IOException;

    /**
     * 创建一个空文件
     * @param fileName 保存的对象存储key
     * @return 返回创建成功(true),创建失败 false
     * @throws IOException
     */
    boolean createNewFile(String fileName) throws IOException;

    /**
     * 删除文件
     * @param fileName 删除的对象存储key
     * @return 返回删除成功(true),删除失败 false
     * @throws IOException
     */
    boolean deleteFile(String fileName) throws IOException;

    /**
     * 创建文件目录
     * @param fileName 对象存储key
     * @return 返回创建成功(true),创建失败 false
     * @throws IOException
     */
    boolean mkdir(String fileName) throws IOException;

    /**
     * 上传文件 (以file的绝对路径作为对象存储key )
     * @param file 待上传的文件
     * @throws IOException
     */
    void uploadFile(File file) throws IOException;

    /**
     * 追加写文件
     * @param fileName 待追加写的对象存储key
     * @param inputStream 待追加写入的数据流
     * @throws IOException
     */
    void appendUploadFile(String fileName, InputStream inputStream) throws IOException;

    /**
     * 文件重名名
     * @param srcFile 原对象存储key
     * @param tarFile 修改后对象存储key
     * @return 返回修改成功(true),修改失败 false
     * @throws IOException
     */
    boolean renameTo(String srcFile, String tarFile) throws IOException;

    /**
     * 获取文件的访问url
     * 此方法有安全风险,可跟进情况看是否需要实现
     * @param fileName
     * @return url方式访问的地址
     * @throws IOException
     */
    String getUrl(String fileName) throws IOException;

    /**
     * 列举出以fileName开头的所有文件(类似于文件操作中递归列举目录下所有文件)
     * @param fileName 对象存储key的前缀
     * @return 文件列表
     * @throws IOException
     */
    List<String> listAll(String fileName) throws IOException;

    /**
     * 列举前缀目录下的所有obs对象(等价文件操作中列举目录下文件)
     * @param fileDir obs对象的key的前缀
     * @param recursion  是否递归查找 ,true 表示递归查找,false不递归
     * @return 文件列表
     * @throws IOException
     */
    List<String> listDir(String fileDir, boolean recursion) throws IOException;

    /**
     * 更新文件的元信息
     * @param fileName 待更新的obs对象key
     * @param meta 更新的文件元信息
     * @return 返回修改成功(true),修改失败 false
     * @throws IOException
     */
    boolean updateMeta(String fileName, Map<String, String> meta) throws IOException;

    /**
     * 更新文件的最后一次修改时间
     * @param fileName 待更新的obs对象key
     * @param newModify 更新的文件修改时间
     * @return 返回修改成功(true),修改失败 false
     * @throws IOException
     */
    boolean updateLastModify(String fileName, long newModify) throws IOException;

    /**
     * 获取obs桶的整个容量(单位:byte)
     * @return 返回容量
     * @throws IOException
     */
    long getTotalSpace() throws IOException;

    /**
     * 获取obs桶的剩余可用容量 (单位:byte)
     * @return 返回容量
     * @throws IOException
     */
    long getUsableSpace() throws IOException;

    /**
     * 复制文件
     * @param srcFileName 待复制的原文件(对象存储key)
     * @param tarFileName 复制后的的目标文件(对象存储key)
     * @return 返回复制成功(true),复制失败 false
     * @throws IOException
     */
    boolean copyFile(String srcFileName, String tarFileName) throws IOException;
}

# 2、实现HealthChecker接口

接口名称:com.seeyon.ctp.common.file.remote.HealthChecker

说明:服务启动时检查存储服务是否正常

需要继承实现当前接口,具体继承实现方案可参考标准的 ctp-file/src/main/java/com/seeyon/ctp/common/file/HuaWeiObsHealthChecker.java

方法详细说明:

public interface HealthChecker {

   /**
    * 心跳检查(OBS服务正常则无返回,否则抛出异常)
    * @return
    * @throws IOException
    */
   boolean health() throws IOException;
}

# 3、修改seeyon-ctp-file.jar中的META-INF

协同OA程序目录下,找到文件webapps\seeyon\WEB-INF\lib\seeyon-ctp-file.jar,使用压缩工具打开并分别修改如下两个文件的内容,将如下两个文件中的对象存储实现类改成前面客开实现的对象存储类:

  • \META-INF\services\com.seeyon.ctp.common.file.remote.HealthChecker
  • \META-INF\services\com.seeyon.ctp.common.file.remote.RemoteFileHandler

1767508471506.png

# 4、设置对象存储参数

参考对应版本部署手册-对象存储章节,打开SeeyonConfig,在OBS配置页开启远程对象存储(设置为ture),并填写OBS需要的Access Key、Security Key、Endpoint、桶名和配置路径等,随后启动验证功能,参考说明如下图:

1767508519750.png

# 文件存储数据迁移对象存储

发布对象存储程序后,新产生的数据会按对象存储形式保存,但原历史文件不会自动迁移。

如项目上有历史附件资源文件迁移对象存储的需求,需要联合对象存储厂商一起,针对产品的存储格式、存储风格,进行迁移规划,这个一般存在不少工作量,甚至迁移工具的开发。

研发有华为云对象存储的项目化迁移工具,有华为云迁移项目,可发起支持单从研发侧获取项目化迁移工具。

编撰人:het