Skip to content

NexusDocs (Chinese)

Alvin Ma edited this page Nov 8, 2018 · 1 revision

English | 中文

gss-logo

GSS - General Storage Service,通用存储服务,该项目的目的在于实现一个可使用多个存储源、进行统一管理的文件存储服务,解决客户需要不同存储源存放私有文件的需求。GSS最终可演化为通用的存储服务,使应用项目无需关注具体文件存储服务的访问实现,而使用统一接口进行操作。

目录

名词词典

Word Explanation
GSS 通用存储接口(本服务)
CSP, provider Cloud Storage Provider 文件存储服务提供商,简称 provider,请参考 受支持的 provider
client 使用 GSS 应用服务,这里作为 GSS API 的客户端
bucket provider 服务的仓库,若该 provider 不提供仓库,则默认为default
namespace 存储资源命名空间,在应用中不同用途使用不同的provider及其子资源(bucket)
file 文件数据的存储对象,包含其相关的元信息

需求

  • 文件存储
    • 提供文件存储的上传、下载、访问(下载和访问操作可重定向到provider)、检索、删除等基本操作;
    • 提供文件的历史版本存储管理(待定);
    • 基于namespace管理不同类型的文件,每个命名空间可独立配置provider;
    • 文件统一上传至GSS,再根据配置分发至相应云存储空间;
    • 应用实例请求资源时,由GSS审查权限,并生成指向provider的安全URL;
    • 批量上传、批量下载(zip,rar,gz);
    • 为namespace创建、恢复snapshot,做到任意恢复;
    • 跨namespace操作,实现不同namespace之间文件的复制、移动操作;
  • 格式转换
    • 提供文件格式转换服务,将文档转换为PDF、图片等;
    • 提供Email附件提取及保存服务;

名词解释

应用实例(client)

指使用 GSS 服务的客户端程序,client 访问 GSS 服务时,必须声明其身份,GSS 将校验其身份并使用配置好的权限策略(ACL)约束其操作。

client 在访问 GSS API 时以 clientKey 声明其身份,并以和 clientSecret 进行验证。

命名空间(namespace)

命名空间使用正序(从左至右依次深入),以.分隔的字符串来描述存储仓库的逻辑划分,全部使用小写字母,例如:

document.private, user.files, avatar

命名空间可使用通配符 * 来描述多个实际的命名空间,但 * 只允许存在于最右端,而且只可出现1次。如 user.* 可包含 user.avataruser.image。 使用通配符时,优先级低于使用完整描述的条目。

命名空间可关联至指定 provider 的某个 bucket。

gss. 开头的命名空间为保留关键字,作为系统内部资源的引用:

Special Namespace Description
gss.namespaces 命名空间
gss.clients 应用实例管理
gss.providers CSP管理

URI

文件资源在应用内部可使用URI来定位,格式如下:

gss://<gss-server>/<namespace>/[path]/<file.fileId>.<file.extension>[?ver=<file.version>]

(其中 ver 参数为 可选 ,若没有则指定isCurrent字段的版本)

或使用对象:

{
  namespace: <string>,
  fileId: <ObjectId>,
  path: <string>       // Optional
  ver: <num>,          // Optional
}

服务架构

  • Gateway 层,校验client权限,处理请求参数分发到个模块;
  • Processers 层,提供文件数据处理、数据格式转换相关操作
    • Manager 层,提供资源、权限管理 namespaces,providers,clients,acl;
    • FileInfo 模块,对文件进行预处理,计算md5 hash,获取图片元数据等,并将文件存储于本地;
    • Transformer 模块,对文档格式进行转换,如 .doc 转换 .pdf
    • Parser 模块,对 email 进行分析,提取其中的附件并存储;
    • Commander 模块,对文件进行批量备份、还原操作;
  • Proxy 层,使用各个 provider 对应的驱动,链接CSP服务,进行相关操作;
  • TaskRunner 服务,提供各服务、模块操作的队列,并在执行完毕时通知已订阅该操作的 client;

软件资源访问路由图示:

gss-routing

软件实现

软件实现包含以下几部分

  • 部署在网络上的 API Service,为 GSS 的主要部分,用来响应 client 的请求;
  • 一个可在 GSS 所在 Server 上运行的 cli 版本,满足快捷的运维需求;
  • Javascript SDK,方便 client 访问 GSS API;

软件特性

订阅服务

订阅服务用于耗时较长的异步操作(如文档转换)的结果通知,或者其他 client 的操作通知

全局订阅

client 在使用订阅服务之前,需要配置 callback URL。全局订阅中,可设置该操作申请者者本身是否被通知;

单条订阅

在单次操作中,可只订阅该操作的结果,并可配置独立的 callback URL

订阅类型

Subscription Type Description
file-operation 文件操作(上传、修改、删除、访问)
file-transform 文档转换结果(当使用异步方式时)
file-command 文件归档,复制,快照,恢复
email-attatchment 邮件附件解析成功

目录浏览

当文件被上传时,path 字段所指定的目录结构将被自动创建,你也可以手动创建一个子目录。

Operation Description
列表 列出该目录下的子目录和文件
删除 删除一个目录,将删除它下面的所有子目录和文件

参考: API: 目录操作DB: gss.dirs

访问控制(ACL)

ACL 配置描述了 client 对应 namespace,或 file 的可进行操作的权限

最终 ACL 的应用策略如下:

  • 遵循“配置即可用”原则,即配置了该权限则可访问,若配置为不可访问或未配置则不可访问;
  • 配置优先级:带有通配符的 namespace ← 指定的 namespace ← 基于 file;

参考:API: ACL 相关操作, DB Collection gss.clients.acl

快照(snapshot)

可为 namespace 创建当前状态的快照,将当前全部文件及其关联的信息保存,以便于稍后进行还原操作

快照还原操作将自动进行还原前快照的创建,以免误操作造成文件丢失。

用户也可从快照批量备份(打包下载)

跨命名空间操作

跨命名空间操作实现不同 namespace 之间文件的复制、移动,或整体镜像

参考:API: 附加指令 中的 /command/cp, /command/mv/command/mirror

CSP支持列表

Name Description SDK
AliOSS 阿里云 OSS 服务 https://github.com/ali-sdk/ali-oss
CubeFS 现有依赖 MongoDB GridFS 的文件存储方式 @nexushubs/cube
AmazonS3 Amazon云存储服务 https://github.com/aws/aws-sdk-js
Qiniu 七牛云 https://github.com/qiniu/nodejs-sdk
GSSForward 代理到另一台 GSS 服务器
... ... ...

API

本部分描述 GSS RESTful API

接口样式

GSS 使用 RESTful API 提供服务

[POST|PUT|GET|DELETE|OPTIONS] https://<gss-server>/api/<module>/<path>?e=<timestamp>&token=<token>

OPTIONS 请求将根据 ACL 返回可以使用何种 HTTP动词

API列表

以下文档 URL 路径以 /api 之后为例展示,并且省略url参数 e, token

Provider 相关操作

GET /providers

获取可用的 provider 列表

POST /providers

新增 provider 实例

PUT /providers/:providerId

更新 provider

DELETE /providers/:providerId

删除 provider

Namespace 相关操作

GET /namespaces

获取可用 namespace 列表

POST /namespaces

创建 namespace

PUT /namespaces/:namespace

更新 namespace

DELETE /namespaces/:namespace

删除 namespace

GET /namespaces/:namespace/snapshots

获取可用 namespace snapshot 列表

POST /namespaces/:namespace/snapshots

创建 namespace snapshot 项目

GET /namespaces/:namespace/snapshots/:snapshotId

获取快照详情

GET /namespaces/:namespace/snapshots/:snapshotId/files

获取快照文件列表

POST /namespaces/:namespace/snapshots/:snapshotId/restore

从 namespace snapshot 还原全部文件,该操作将自动创建一个新的 snapshot

DELETE /namespaces/:namespace/snapshots/:snapshotId

删除 namespace snapshot

Clients 相关操作

GET /clients

获取可用 client 列表

POST /clients

创建 client

PUT /clients/:clientId

更新 client

DELETE /clients/:clientId

删除 client

ACL 相关操作

GET /clients/:clientId/acl

获取 client 权限列表

GET /clients/:clientId/acl/:namespace/:fileId?

获取 client 对应 namespace(或其中某个文件)的权限

PUT /clients/:clientId/acl/:namespace/:fileId?

设置 client 对应 namespace(或其中某个文件)的权限

INPUT:

{
  <auth-key>: <bool>,
}
// or
[<auth-key>...]

请参考 gss.clients.acl

DELETE /clients/:clientId/acl/:namespace/:fileId?

删除 client 对应 namespace(或其中某个文件)的全部权限

GET /namespace/:namespace/acl

获取 namespace 对应各 client 的权限列表

目录操作

GET /dir/:namespace/:path

获取当前目录的子文件夹、文件列表

OUTPUT:

{
  dirs: [<string>...],
  files: [{
    fileId: <ObjectId>,
    name: <string>,
    contentType: <string>,
    size: <num>,
  }...],
}
POST /dir/:namespace/:path

在当前目录创建新目录

INPUT:

{
  name: <string>,
}
DELETE /dir/:namespace/:path

删除所有该目录下的子文件夹和文件.

文件操作

POST /files/:namespace/

上传文件

GET /files/:namespace/:fileId[/download[/:filename]]

获取文件(用于显示或下载)

RESPONSE: bin data

GET /files/:namespace/:fileId/meta

获取文件元信息

RESPONSE: JSON

GET /files/:namespace/:fileId/link[/download[/:filename]]

获取文件显示(下载)地址

RESPONSE: URL

DELETE /files/:namespace/:fileId

删除文件

POST /files/:namespace/:fileId/transform/:type

文档格式转换

附加指令

POST /command/cp

跨 namespace 复制文件

INPUT:

{
  source: {
    namespace: <string>,
    files: [<ObjectId>...],
  },
  dist: {
    namespace: <string>,
    path: <string>,         // Optional
  }
  callback: <string>     // Optional
}
POST /command/mv

跨 namespace 移动文件

INPUT:

{
  source: {
    namespace: <string>,
    files: [<ObjectId>...],
  },
  dist: {
    namespace: <string>,
    path: <string>,         // Optional
  }
  callback: <string>     // Optional
}
POST /command/mirror/:namespace1/:namespace2

镜像 namespace,若 namespace2 中 已存在文件,则在操作前创建快照

POST /command/archive/:namespace

执行批量备份操作

INPUT:

{
  files: [<fileId>...],
  path: <string>,        // Optional
  callback: <string>     // Optional
}
POST /command/archive/:namespace/restore

执行批量恢复操作

INPUT(multipart/form-data):

{
  path: <string>,        // Optional
  archive: <file>,
}

支持 .tar.gz, .zip, .rar

订阅服务

GET /notification

获取当前订阅消息

POST /notification/subscribe

订阅消息

POST /notification/unsubscribe

取消订阅

...

数据库设计

GSS 使用 Mongodb 作为主要数据库,并可使用 Redis 作为缓存服务

数据词典

Collection gss.namespaces

存储服务命名空间,用来服务不同应用模块

{
  _id: <ObjectId>,
  name: <string>,
  description: <string>,
  providerId: <ObjectId>,
  bucket: <string>,
}

Collection gss.providers

存储CSP配置,可关联至多个命名空间

{
  _id: <ObjectId>,
  type: <string>,          // 对应CSS提供商所列举的
  name: <string>,
  authInfo: {
    accessKey: <string>,
    acesssSecret: <string>,
                          // 对应不同CSS提供商的安全访问参数
  },
  buckets: <string array>, // 列举可用的bucket
  dateExpire: <timestamp>,
}

Collection gss.files

存储文件信息,设计参照了GridFS

{
  _id: <ObjectId>,
  fileId: <uuid>,
  version: <num>,
  isCurrent: <bool>,
  namespace: <string>,
  length: <num>,
  uploadDate: <timestamp>,
  md5: <hash>,
  path: <string>,
  filename: <string>,
  contentType: <string>,
  aliases: [<string>...],
  isDelete: <bool>,
  metadata: <any>,
}

Collection gss.dirs

存储虚拟的目录信息.

{
  _id: <ObjectId>,
  namespace: <string>,
  path: <string>,
  name: <string>,
}

Collection gss.snapshots

文件快照

{ _id: , namespace: , dateCreate: , }

Collection gss.snapshots.files

文件快照

{ _id: , snapshotId: , <filefields...>, }

Collection gss.clients

应用配置

{
  _id: <ObjectId>,
  clientId: <string>,
  clientKey: <string>,
  clientSecret: <string>,
  name: <string>,            // Optional
  description: <string>,     // Optional
  callbackUrl: <string>,
  namespaces: [<string>...],
}

Collection gss.clients.acl

应用权限配置

{
  _id: <ObjectId>,
  clientId: <ObjectId>,
  fileId: <ObjectId>,           // Optional
  namespace: <string>,          // (1)
  access: [<string:enums>...]   // (2)
}

(1) 命名空间可使用通配符*, *.abc

(2) 不同关键字对应的操作:

Key Action Description
M Manage 修改元信息、设置当前版本等操作
G Get 获取文件
A Add 上传文件(仅针对 namespace)
U Update 上传文件(创建新版本版本)
D Delete 删除文件
B Backup 批量备份(仅针对 namespace)
R Restore 批量还原(仅针对 namespace)

Collection gss.urlcache

存储provider访问、下载链接,可使用Redis替代

{
  _id: <ObjectId>,
  namespace: <string>,
  fileId: <uuid>, //uniq indexed
  url: <string>,
  dateExpires: <timestamp>,
}
Clone this wiki locally