百积木文档
开发指南平台应用、模块与 Bundle 开发高级开发

Bundle 生命周期插件

明确插件注册、Bundle 资源授权和 Runtime 执行责任,按新的逻辑引用协议管理外部业务状态。

Bundle 插件为一次完整安装开通、更新、停止或解除外部业务实例。 请求、响应和按需访问解析以Bundle 生命周期与引用协议为准。

各方职责

责任方拥有的事实
插件目录稳定 pluginId、协议、执行地址和调用身份
Bundle 作者插件绑定、执行顺序、非敏感配置和资源属性授权
Runtime 安装器安装实例、当前版本、操作身份、阶段执行与失败处理
插件服务外部业务实例及其与平台安装身份的关联

Bundle 安装用户不需要再次注册插件。插件只返回授权业务输出,不能直接写安装账。 同一安装的重试应复用外部实例;不同安装的业务状态和凭据必须隔离。

注册与绑定

插件目录的 bundleExecution 声明 protocolVersion: "5.0.0"、HTTPS executeUrl, 以及 supportedStages: ["BEFORE_RESOURCES", "AFTER_RESOURCES"]。 执行时使用统一的 Bundle 生命周期请求,Module 的业务属性通过资源授权投影。

Bundle 绑定声明 pluginIdprotocolVersionorderfailurePolicyconfigurationresources。 作者清单中的资源授权使用 Owner 返回的领域对象 object,并指定 readPropertieswritePropertiescredentialProperties。Runtime 编译后才生成执行请求中的 ResourceLocator。 后者只允许插件对当前属性执行访问解析,不把平台密钥放入 Bundle。 Endpoint、平台 Token 和业务密钥不得复制到 Bundle 的插件配置中。

先确认 baijimu lifecycle-plugin update --help 包含 --bundle-executionbaijimu bundle manifest --help 包含 lifecycle-plugin;旧客户端应先升级。 以下地址只是结构示例,实际地址从插件提供方的服务登记取得。

将 Bundle 执行端声明保存为 bundle-execution.json

{
  "protocolVersion": "5.0.0",
  "executeUrl": "https://plugin.example/plugin/bundle/lifecycle",
  "supportedStages": ["BEFORE_RESOURCES", "AFTER_RESOURCES"],
  "finalization": {
    "contractVersion": "1.0.0",
    "executeUrl": "https://plugin.example/plugin/bundle/finalize"
  }
}

插件注册与管理完成插件记录创建后登记并回读:

baijimu lifecycle-plugin update "$PLUGIN_ID" --bundle-execution @bundle-execution.json
baijimu lifecycle-plugin get "$PLUGIN_ID"

Bundle 作者清单使用 schemaVersion: "2.0.0",插件绑定放在 definition.lifecyclePluginsdefinition 不带内部安装内容的版本号。先通过对象选择命令 纳入 Module,再将下面结构保存为 plugin-binding.json,使用目录返回的 Module 身份和已声明属性:

{
  "pluginId": "tenant-provider",
  "protocolVersion": "5.0.0",
  "order": 0,
  "failurePolicy": "FAIL_FAST",
  "configuration": {"schemaVersion": "1.0.0", "values": {}},
  "resources": [{
    "object": {"type": "MODULE", "moduleId": "a054ef60-f64c-47cf-8b63-4dbdd05e5ef1"},
    "readProperties": ["region"],
    "writeProperties": ["tenantId"],
    "credentialProperties": ["inventory"]
  }]
}

示例 Module 必须已在同一清单的 definition.modules 中纳入,inventory 是需要按需解析的引用属性。 configuration.schemaVersion 由插件定义,不随平台生命周期协议强制变化。

baijimu bundle manifest lifecycle-plugin add @baijimu.bundle.json \
  --binding @plugin-binding.json > baijimu.bundle.next.json
baijimu bundle manifest validate @baijimu.bundle.next.json
baijimu bundle manifest lifecycle-plugin list @baijimu.bundle.next.json

增删命令输出完整清单,核对后再用它更新项目源码并走正常 Bundle 版本发布。 CLI 使用 Bundle owner 的类型校验重复插件、缺失资源和引用领取/回写冲突;调整其他资源也会保留插件绑定。 发布端进一步校验资源确实归属该 Bundle。发布后回读不可变版本内容并完成实际安装验收。

移除绑定使用 baijimu bundle manifest lifecycle-plugin remove @baijimu.bundle.json --plugin-id "$PLUGIN_ID", 同样需要发布后继 Bundle 版本再升级安装,不会直接改变已有安装。

安装与恢复

Runtime 在 BEFORE_RESOURCESAFTER_RESOURCES 阶段调用插件,并按实际请求发送 APPLYINSPECTCOMPENSATE。插件必须验证安装、操作、阶段和资源授权,查询和改变自己拥有的外部状态。

结果不确定时返回可准确表达事实的结果,由 Runtime 检查后决定后续动作。 不能把重试伪装成新安装,也不能把外部调用超时当成外部操作已撤销。 DETACHDELETE 按请求和业务所有权处理,不能删除其他安装共享或用户自有的资源。

验收

  1. 安装、升级、配置变更、停止和卸载均正确关联同一业务实例。
  2. 同一次操作重放不会重复创建外部租户,两个安装互不覆盖。
  3. 生命周期引用不含地址或密钥,输出只写入授权资源属性。
  4. 业务调用前从当前绑定解析 access,重绑与授权撤销立即影响下一次解析。
  5. Map 业务键和 List 顺序按当前引用保留,同目标访问材料去重。
  6. 请求、响应的身份不匹配以及未授权属性均被拒绝。
  7. 插件故障或未知结果不能被标记为安装成功;检查和补偿保留可审计结果。

外部实例标识声明

作者协议 2.0.0 使用 Owner 目录返回的领域对象选择;下面的 object.moduleId 由工具写入,不拼装通用资源引用。

instanceRefProperty 要求编译后的 Bundle 内容 schemaVersion: "12.1.0",并要求安装环境已升级至支持该声明的 Runtime。历史 12.0.0 内容仍按原版本读取,不能在 12.0.0 中加入这一声明。

Rust 插件 SDK baijimu-bundle-plugin 2.1.0 通过新增 BundlePluginBindingV2BundlePluginResourceGrantV2 支持该声明。原有类型与方法继续保持兼容;新类型可从原有声明转换或从 JSON 反序列化,再显式设置 instance_ref_property。使用 validate_bundle_plugin_bindings_v2 检查写入者唯一性, 使用 V2 绑定上的 validate_lifecycle_requestvalidate_lifecycle_responsevalidate_reference_request 检查生命周期及凭据请求权限。实例值不可变和安装归属仍分别由 Runtime 与外部组件校验。

有持久外部实例的插件,在对应资源授权中声明 instanceRefProperty,其值是该 Module 定义中的属性名。 该声明可省略;平台不会按 tenantIdaccountId 等名称猜测哪个属性是实例标识。 属性名仍须符合插件已发布的业务输入、输出合同;该声明不提供业务字段重命名或映射。

{
  "object": {"type": "MODULE", "moduleId": "owner-returned-module-id"},
  "readProperties": ["tenantName", "tenantId"],
  "writeProperties": ["tenantId"],
  "credentialProperties": [],
  "instanceRefProperty": "tenantId"
}

声明的属性必须是无预置实例值的字符串 Data 属性,同时授权当前插件读取和写入,且不能是凭据引用。 同一资源的该属性只能有一个插件写入者。不同插件管理不同外部实例时,可以声明不同属性。

首次创建时属性可以缺失或为 null。插件应根据完整安装身份创建或查找外部实例,并在成功响应中返回 非空实例标识。标识不包含首尾空白;失败结果不应伪造实例标识。后续操作可以省略输出以保留原值, 但不能返回 null、空字符串或另一个实例标识。

普通属性更新不能初始化、更换或删除此属性;普通 Bundle 升级不能移除、改名或转移仍受管理的实例标识声明。 重新绑定不属于普通配置更新;在正式重新绑定合同提供前,应拒绝此类请求。

移除资源前,插件只接收必要的实例标识,不接收整份业务配置或引用凭据。资源移除后的验证阶段可能已没有 属性,插件必须仍能根据完整安装身份检查解绑结果,不能要求 Runtime 另存一份实例标识。

实例标识由外部组件拥有;Runtime 的属性是其稳定引用。平台安装身份仍由安装环境、Runtime、Bundle 安装、 资源定位和插件身份共同限定。插件必须验证实例归属,不能仅凭一个合法格式的实例 ID 操作资源。 访问凭据继续通过独立凭据协议取得,实例标识不授予访问权限。

本页内容