## 背景

苍穹默认实现了以磁盘文件的访问方式实现了文件存储服务，如果客户需要接入自己的文件存储实现，可以开次开发实现kd.bos.filestorage.spi.FileStorageService接口。

注：公有如阿里OSS，华为OBS，AWS S3等对象存储服务也可以映射为磁盘文件，无需二次开发即可利用苍穹默认的文件服务实现文件存取。

苍穹业务代码访问文件存储服务时，首先通过FileService-SDK包的kd.bos.fileservice.FileServiceFactory() 工厂类获取到FileStorageService具体的实现，然后执行实现类的上传下载删除接口的具体逻辑。

![](image/01.png)

## 配置

请在MC中配置以下参数：

| 属性                                   | 值                                  | 备注                                                   |
| ------------------------- | ------------------------- | --------------------------------------------------- |
| attachmentServer.fileStorage.className | com.xxxx.XXXXStorage                | 设置文件存储实现类（根据你具体的实现类替换本设置）     |
| attachmentServer.url                   | http://xxx.xxx.xxx/upload           | 文件存储服务器API地址                                  |
| imageServer.fileStorage.className      | com.xxxx.XXXXStorage                | 图像存储设置存储实现类（根据你具体的实现类替换本设置） |
| imageServer.url                        | http://172.17.2.188:12345/auth/v1.0 | 图像存储服务器API地址                                  |



## 接口实现

创建XXXXStorage实现类，实现kd.bos.filestorage.spi.FileStorageService接口类的以下逻辑：


```java
public interface FileStorageService extends Closeable {
    /**
     * 设置文件存储配置参数
     * @param fileStorageConfig
     */
    void setConfig(FileStorageConfig fileStorageConfig);

    /**
     * 返回文件服务器禁止的文件扩展名集合
     * @return
     */
    List<String> getForbiddenExtensions() throws Exception;

    /**
     * 返回文件服务器的Ticket
     * @return
     */
    String getTicket() throws Exception;


    /**
     * 上传文件
     * @param inputStream
     * @param path （相对路径包括文件名如：/testPath/testSubPath/testFileName.pdf)
     * @param fileName (文件名如 testFileName.pdf)
     * @param isCreateNewFileWhenExists
     * @param headers
     * @return
     */
    String upload(InputStream inputStream, String path, String fileName,boolean isCreateNewFileWhenExists, Map<String, String> headers) throws Exception;

    /**
     * 读取指定文件的文件流
     * @param path （相对路径包括文件名如：/testPath/testSubPath/testFileName.pdf)
     * @param userAgent
     * @return
     */
    InputStream getInputStream(String path,String userAgent) throws Exception;

    /**
     * 下载指定文件并输出到文件流中
     * @param path（相对路径包括文件名如：/testPath/testSubPath/testFileName.pdf)
     * @param out
     * @param userAgent
     */
    void download(String path, OutputStream out, String userAgent) throws Exception;

    /**
     * 删除指定文件 
     * @param path （相对路径包括文件名如：/testPath/testSubPath/testFileName.pdf)
     */
    void delete(String path) throws Exception;
}

```



## 示例工程

可以参考bos-filestorage-swift样例工程源码：

```java
//详见bos-filestorage-swift源码
public class SwiftStorage implements FileStorageService {
    public InputStream getInputStream(String path,String userAgent) throws Exception { }
    public void download(String path, OutputStream outputStream, String userAgent) throws Exception {}
    public void delete(String path) throws Exception {}
    public String upload(InputStream inputStream, String path, String fileName,boolean isCreateNewFileWhenExists, Map<String, String> headers) throws Exception{ }
    
    ... 
     
}
```

在MC中swift样板工程需要配置的属性：

| 属性                                   | 值                                  | 备注                                                   |
| ------------------------- | ------------------------- | --------------------------------------------------- |
| attachmentServer.container | upload         | 容器名，支持多个容器以平衡性能，用逗号隔开如 upload1,upload2,upload3将随机选择一个（容器先请用管理员账户创建好） |
| attachmentServer.authuser | test       | 用户名                               |
| attachmentServer.authpass | test   | 密码 |
| attachmentServer.authtype | none | swift认证模式如：none,tempauth,keystone                      |
| attachmentServer.upload.timeout | 600 | 上传超时时间默认600秒 |



## 部署

将文件存储实现类编译成jar包，打包上传到AppStore服务器部署。
