# OIP-Data **Repository Path**: orginone/OIP-Data ## Basic Information - **Project Name**: OIP-Data - **Description**: OIP-Data 是奥集能开放架构的 数据服务端(L2 可信数据空间) - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 2 - **Created**: 2026-09-25 - **Last Updated**: 2026-10-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # OIP-Data · 可信数据空间(数据核) > **文档版本**:v1.1 | **更新**:2026-09-26 | **状态**:正式发布 > **关联**:[OIP-Data-Design.md](../OIP/docs/OIP-Data-Design.md) · [OIP-Protocol.md](../OIP/docs/OIP-Protocol.md) · [OIP.md](../OIP/docs/OIP.md) `OIP-Data` 是开放互联协议(Open Interconnect Protocol, OIP)的 **L2 可信数据空间(数据核)** 的 Rust 实现,承载数据域的存储、变动与权限控制,功能与 C# 参考实现(外部仓库 `oiocns-data`)对齐,并以 OIP 架构设计原则持续演进。 ## 定位 `OIP-Data` 提供「用户对数据标准与存储方式自主可控」的数据空间能力:自主选择存储资源,自定义数据标准、业务模型与管理流程,无代码配置应用,便捷迁移外部数据,并提供通用文件系统管理能力。 `OIP-Data` 也是进程内嵌(OIP 形态Ⅱ 桌面端编排层)的装配单元:`src/lib.rs` 同时导出独立启动入口与嵌入式装配入口,二者复用同一套装配代码。 ## 技术特性 | 类别 | 技术选型 | | ------ | ---------- | | 语言 / 版本 | Rust(edition 2024) | | Web 框架 | Axum 0.7 | | 异步运行时 | Tokio 1.0 | | 数据库 | MongoDB 2.0 驱动;可选 PostgreSQL(sqlx 0.7,`db_type=postgresql`) | | 实时通信 | SignalR 协议(WebSocket)+ SSE | | 身份验证 | JWT(jsonwebtoken) | | 面向平台 | KernelHub(SignalR Client 连接关系核主服务) | | 公式/表达式 | Rhai 脚本引擎 | | 序列化 | serde + serde_json + serde_yaml + bson | | 文件存储 | 本地文件系统(`BucketManager`:分片上传/断点续传/缩略图/HLS,按组织分目录隔离) | ## 项目结构 ```text OIP-Data/ ├── Cargo.toml # 工程清单(edition 2024) ├── config.example.yaml # 配置模板(复制为 config.yaml 使用;config.yaml 不入库) ├── AGENTS.md # 面向开发者/AI 代理的迭代指南 │ ├── src/ │ ├── main.rs # 二进制入口(薄壳,下沉至 lib::run) │ ├── lib.rs # 库入口:assemble / build_routes / run + 路由装配 │ ├── config.rs # 全局配置单例(对齐 C# GlobalFile.cs)+ 环境变量覆盖 │ ├── policies.rs # 通道闸门:append-only 集合 / db-command 命令白名单 / HttpForward 出站策略 │ ├── entitys/ # 实体层(EntityBase + X* 实体) │ ├── providers/ # 数据提供者(DataProvider 多文件 impl) │ ├── services/ # 业务服务(折旧/锁/指派/接收/转换/规则/VCS/认证) │ ├── loaders/ # 查询引擎(DevExtreme → 聚合管道) │ ├── realtime/ # 实时通信(Hub / KernelHub / SignalR / WebSocket / SSE / 流管理) │ ├── handlers/ # HTTP 请求处理器 │ ├── storage/ # 存储层(IStorage 抽象 + MongoDB + PostgreSQL + BucketManager) │ ├── models/ # 数据模型层 │ ├── workers/ # 后台工作者(KernelHub 连接 / 定时触发) │ └── utils/ # 工具模块(BSON/JSON、聚合、压缩、时序转换) │ ├── doc/ # 开发文档(how2read.md / modules.md) └── .github/workflows/ # CI:构建测试 + 契约面漂移校验 ``` ### 核心模块 - **providers/(DataProvider 中央调度)** - `data_provider.rs`:`get_object_async` / `db_info_async` / `command_async` / `duplicate_async` / `snapshot_async` / `depreciation_async` / `perfect_async` / `destroy_async` / `create_order_async` / `replace_order_async` - `collection_data.rs`:集合 CRUD(`list_async` / `load_async` / `aggregate_async` / `summary_async` / `insert_async` / `replace_async` / `set_fields_async` / `update_async` / `remove_async` / `thing_collect_async`) - `object_data.rs`:对象 CRUD(`object_list_async` / `object_get_async` / `object_set_async` / `object_delete_async`) - `provider_extensions.rs`:`find_form` / `load_instance_things_by_form` / `stage_things` / `get_thing_ids` + 财务与操作扩展方法 - **services/**:`ThingDepreciationService`(折旧)、`ThingLockService`(锁定)、`ThingConvertService`(字段转换)、`AssignTaskService`(指派同步)、`ReceptionExecutorHook`(接收挂载)、`RuleService`(规则)、`VcsManager`(版本控制)、`AuthService`(认证) - **realtime/**:`hub.rs` 实现 C# DataHub 的 19 个方法(`TokenAuth` + 18 个业务方法);`signalr_hub.rs` 提供 SignalR 协议端点;`websocket.rs` / `sse.rs` 提供降级通道;`kernel_hub.rs` 作为 SignalR Client 连接关系核;`stream_manager.rs` 管理文件流 - **workers/**:`kernel_hub_worker.rs`(作为 SignalR Client 连接关系核主服务)、`time_trigger_worker.rs`(定时触发) - **storage/**:`IStorage` 存储抽象(`storage_provider.rs`),`MongoStorage` / `PgStorage` 驱动封装,`BucketManager` 文件系统管理(分片上传/断点续传/缩略图/HLS) - **policies.rs(通道闸门)**:`append_only_collections`(只允许新增,拒绝就地改写)、`db_command_extra_commands`(`db-command` 只放行平台数据面命令,服务端管理与逃逸类命令显式拒绝)、`http_forward`(`HttpForward` 仅 http(s)、主机白名单、内网与保留段拦截、解析后钉地址、不跟随重定向)。三者均为「内置默认 ∪ 配置追加」,启动期打印生效清单 ## 环境要求 - Rust stable(edition 2024),推荐 rustup 管理工具链 - Windows 构建需 MinGW-w64(`dlltool`),示例: ```powershell $env:PATH = "C:\msys64\mingw64\bin;$env:PATH" ``` - MongoDB 4.4+(本地或远程);使用 `db_type=postgresql` 时需 PostgreSQL ## 安装与运行 1. **克隆项目** ```bash git clone cd OIP-Data ``` 2. **获取关系核认证信息** 登录前端,新建存储群,获取群代码 `storeCode`。通过接口获取 `KernelAuth` 字符串,或在平台存储群中点击「获取认证码」: ```bash POST https://ocia.orginone.cn/orginone/kernel/rest/auth HTTP/1.1 Content-Type: application/json { "module": "auth", "action": "GetDataKey", "params": { "account": "账号", "password": "密码", // 可选:密码/手机验证码/私钥三选一 "dynamicId": "手机验证码编号", // 可选:使用手机验证码时必填 "dynamicCode": "手机验证码", // 可选 "privateKey": "私钥", // 可选 "storeCode": "存储群代码" } } ``` 3. **配置 config.yaml** 仓库内 `config.example.yaml` 为配置模板(不含敏感值),复制为本地 `config.yaml` 后按需填写;`config.yaml` 由 `.gitignore` 排除,不入库: ```bash cp config.example.yaml config.yaml ``` 模板键位(下表「模板值」列与 `config.example.yaml` 逐键一致,「代码默认值」列取自 `src/config.rs`): | 键 | 模板值 | 代码默认值 | 说明 | | --- | --- | --- | --- | | `env` | `development` | `development` | 运行环境:`production` / `development`。`production` 下启动期**拒绝**三类"缺失即静默降级"的形态:`internal_token` 为空(入站内部令牌门未启用)、数据库连接为空(存储退回默认/临时实例)、`http_forward.allow_private=true`(SSRF 防护主体失效)。不写本键按 `development` 处理(既有部署不受影响) | | `kernel_addr` | `https://assetcloud.zj.gov.cn/orginone/resource/hub` | `""` | 关系核(平台 Hub)地址,数据核作为 SignalR Client 连接的 Kernel 主服务端点(分号分隔多个) | | `kernel_auth` | `""` | `""` | 连接平台所用认证密钥(敏感项,可被环境变量 `KernelAuth` 覆盖) | | `storeCode` | `""` | `""` | 平台下发的存储群代码。规范键名为 camelCase(`#[serde(rename = "storeCode")]`),`store_code` 为兼容别名;其他拼写(如 `store_codes`)会被拒绝 | | `bucket` | `""` | `/opt/bucket` | 本地存储根目录(按组织分目录隔离) | | `db_type` | `mongo` | `mongo` | 数据库类型:`mongo` / `postgresql` | | `connection_string` | `""` | `""` | 数据库连接串(敏感项,可被环境变量 `ConnectionString` 覆盖)。已明文连接串原样使用;否则长度 > 5 时去掉前 5 个字符再做 Base64 解码 | | `jwt_secret` | `""` | `""` | JWT 签发密钥(敏感项,可被环境变量 `JwtSecret` 覆盖)。长度必须 ≥ 32 字符,否则装配阶段拒绝启动 | | `urls` | `127.0.0.1:8080` | `http://localhost:80` | 服务监听地址(解析时去除 `http://` / `https://` 前缀) | | `sandbox_allowed_domains` | 模板不含 | —(代码未声明该字段) | **不得写入**:C# 参考实现模板中的同名键在本实现中无对应字段,解析启用未知键拒绝(`deny_unknown_fields`),写入即加载失败 | | `python_command` | 模板不含 | —(代码未声明该字段) | **不得写入**:同上,写入即加载失败 | | `ffmpeg_path` | `ffmpeg` | `""` | 文件转码 / 媒体处理所用 ffmpeg 可执行文件路径(缩略图与转码路径均读取该键;为空或文件不存在时跳过转码) | | `cors_origins` | `""` | `""` | CORS 允许来源白名单(逗号分隔,留空则仅允许同源),可被环境变量 `CorsOrigins` 覆盖 | `src/config.rs` 另支持以下键(模板未列出,均有默认值):`worker_id`(0)、`datacenter_id`(0)、`kernel_num`(1)、`log_level`(`Information`)、`allowed_hosts`(`*`)、`access_expire`(7200 秒)、`keep_timeout`(12000 ms)、`keep_alive_interval`(2000 ms)、`executor_timeout`(10000 ms)、`connection_key`(`null`,`connection_string` 为空时回退读取该文件)。 配置文件路径可用 `OIP_DATA_CONFIG` 覆盖,默认 `config.yaml`。启动日志经 `Config::safe_summary()` 脱敏,不输出 `jwt_secret` / `kernel_auth` / `connection_string` 内容。 4. **启动服务** ```bash cargo run ``` ## API 端点 `src/lib.rs` 的 `build_routes()` 为全部路由的唯一装配点。 ### 数据 REST(`/orginone/anydata/*`,对齐 C# Collection/Object/Public Controller) | 方法 | 路径 | 说明 | | --- | --- | --- | | GET / POST | `/orginone/anydata/Collection/List` | 集合列表 | | POST | `/orginone/anydata/Collection/Load/:collectName` | 加载集合数据 | | POST | `/orginone/anydata/Collection/Aggregate/:collectName` | 聚合查询 | | POST | `/orginone/anydata/Collection/Insert/:collectName` | 插入 | | POST | `/orginone/anydata/Collection/SetFields/:collectName` | 设置字段 | | POST | `/orginone/anydata/Collection/Update/:collectName` | 更新 | | POST | `/orginone/anydata/Collection/Remove/:collectName` | 删除 | | POST | `/orginone/anydata/Collection/Replace/:collectName` | 替换 | | POST | `/orginone/anydata/Collection/Summary` | 汇总 | | POST | `/orginone/anydata/Collection/LoadThing` | 加载事物 | | POST | `/orginone/anydata/Collection/CreateThing` | 创建事物 | | POST | `/orginone/anydata/Collection/DestroyThing` | 销毁事物 | | POST | `/orginone/anydata/Thing/Snapshot` | 事物快照 | | POST | `/orginone/anydata/Thing/Depreciation` | 事物折旧 | | POST | `/orginone/anydata/Thing/Perfect` | 实体完善 | | POST | `/orginone/anydata/Thing/Collect` | 事物归集 | | POST | `/orginone/anydata/Thing/Destroy` | 事物销毁 | | GET / POST | `/orginone/anydata/Disk/Info` | 磁盘信息 | | POST | `/orginone/anydata/Bucket/Operate` | 桶操作 | | GET / POST | `/orginone/anydata/Object/List/:objectName` | 对象列表 | | GET / POST | `/orginone/anydata/Object/Get/:objectName` | 获取对象 | | POST | `/orginone/anydata/Object/Set/:objectName` | 设置对象 | | DELETE / POST | `/orginone/anydata/Object/Delete/:objectName` | 删除对象 | | POST | `/orginone/anydata/Public/CreateOrder` | 创建订单 | | POST | `/orginone/anydata/Public/HttpForward` | HTTP 转发代理 | ### 文件流与版本控制(`/api/oip/v1/*`,对齐 C# FileStream/Vcs Controller) | 方法 | 路径 | 说明 | | --- | --- | --- | | POST | `/api/oip/v1/storage/filestream/os` | 文件流操作 | | GET | `/api/oip/v1/storage/filestream/stat/:key` | 文件流状态 | | GET | `/api/oip/v1/storage/filestream/download` | 文件下载 | | POST | `/api/oip/v1/vcs/os` | 版本控制操作 | | GET | `/api/oip/v1/vcs/repos` | 版本库列表 | | POST | `/api/oip/v1/storage/db-command` | 数据库命令 | ### 实时通信与静态资源 | 方法 | 路径 | 说明 | | --- | --- | --- | | POST | `/orginone/kernel/hub/negotiate` | SignalR 连接协商(`SignalRHub` 的 `config.path` 默认 `/orginone/kernel/hub`) | | GET | `/orginone/kernel/hub` | SignalR WebSocket 通道 | | GET | `/ws` | WebSocket 通道 | | GET | `/sse` | SSE 通道(`Authorization: Bearer` 鉴权) | | GET | `/health` | 健康检查 | | GET | `/orginone/kernel/load/*path` | 文件加载 | | GET | `/orginone/anydata/Bucket/Share/{link}` | 桶分享(C# 兼容路由) | ### DataHub 方法(`realtime/hub.rs`) `handle_invocation` 覆盖 19 个方法:`TokenAuth`、`BucketShare`,以及需先鉴权的 17 个业务方法——`ThingLoad`、`ThingCreate`、`ThingDestroy`、`CollectionList`、`CollectionLoad`、`CollectionAggregate`、`CollectionInsert`、`CollectionUpdate`、`CollectionReplace`、`CollectionSetFields`、`CollectionRemove`、`ObjectList`、`ObjectGet`、`ObjectSet`、`ObjectDelete`、`BucketOpreate`、`BucketStream`。未鉴权调用返回 `请先鉴权`;未知方法返回 `未知方法: `。 > **身份口径**:实时通道(SignalR Hub / WebSocket / SSE)的身份与租户恒取自验签令牌 claims(`user_id` / `belong_id`),MUST NOT 由请求参数(如 `belongId`)构造或改写。WS / SSE 在连接建立时经 `Authorization: Bearer` 验签写入连接态;SSE 消息面(`/sse/message`)不承载身份,调用方自报的身份一律不予采信。 ## 测试 ```bash cargo check # 快速类型检查 cargo test # 运行单元/集成测试 ``` - 数据库相关用例(`storage/mongo_storage_test.rs`、`storage/pg_storage_test.rs`、`storage/storage_provider_test.rs`)直接连接 `mongodb://127.0.0.1:27017`;设置环境变量 `SKIP_DB_TESTS` 时跳过实际读写。 - CI 以 `mongo:7` 服务容器提供真实 MongoDB,不设置 `SKIP_DB_TESTS`,因此数据库用例在 CI 中执行真实读写。 > **Windows 注意**:编译/测试前确保 `dlltool`(MinGW-w64)在 PATH 中,否则会在链接依赖(如 `getrandom`、`windows-sys`)时报 `dlltool.exe program not found`。 ## 持续集成 `.github/workflows/ci.yml` 在 push(`master`/`main`)与 `pull_request` 时执行,运行于 `ubuntu-latest`,工具链 Rust `1.98.1`(含 `rustfmt`、`clippy`),并以服务容器提供 `mongo:7`: ```bash cargo fmt --all --check cargo clippy --all-targets -- -D warnings cargo test --all-targets cargo build --release --locked ``` `.github/workflows/contract-check.yml` 执行契约面漂移校验,且为 **fail-closed**:若同级目录不存在 `../OIP/tools/gen_protocol.py`,先尝试 `git clone --depth 1 https://gitee.com/orginone/OIP.git ../OIP`;克隆后仍不可用则报错退出(非跳过)。可用时执行 `python3 ../OIP/tools/gen_protocol.py --check`,任何漂移即失败。 ## 参与贡献 1. fork 项目并克隆到本地。 2. 按照 OIP 的编码规则进行开发,功能与 C# 参考实现对齐(外部仓库 `oiocns-data`,`.NET 6 / ASP.NET Core / MongoDB / SignalR`)。 3. 提交前执行 `cargo check` 保证编译通过,必要时同步更新 `AGENTS.md`、`README.md` 与 `doc/`。 4. 通过 Pull Request 提交,经维护者审核后合并。 ## 开发组构成 - **贡献者 Contributor**:完成一次 PR 的提交和合并。 - **提交者 Committer**:完成至少 5 个 PR 并得到 mentor 邀请,可 review 和 accept PR。 - **维护者 Maintainer**:长期维护项目,有权合并 PR 入主分支。@realVeer @Socket_Captain - **导师 Mentor**:决定项目发展方向。导师 @panzhaohui ## 相关文档 - [OIP-Data-Design.md](../OIP/docs/OIP-Data-Design.md)(L2 可信数据空间设计,单一真相源) - [OIP-Protocol.md](../OIP/docs/OIP-Protocol.md)(协议规范) - [OIP/AGENTS.md](../OIP/AGENTS.md)(OIP 全部仓库协作规范) - [开发者/AI 代理迭代指南](AGENTS.md) - [项目阅读指南](doc/how2read.md) - [模块说明](doc/modules.md) - License: MIT