Bundle 生命周期与引用协议
使用 Bundle 安装身份、资源授权和按需访问解析,实现跨资源的外部业务生命周期。
Bundle 生命周期协议 6.0.0 以整个安装实例为操作边界,访问解析协议为 4.0.0。
所有自定义插件统一使用这一机制,Module 作为 Bundle 资源接受显式属性授权。
安装身份与执行语义
installation 包含安装环境 environmentKey、applicationRuntimeId、workspaceId、
bundleInstallId 和 Bundle 来源 bundle.environmentKey + bundle.bundleId。
安装环境与 Bundle 来源可以不同,所有定位均由 Runtime 提供。
operationType + stage 表达操作与资源执行时机:
| 字段 | 允许值 |
|---|---|
operation.operationType | INSTALL、UPGRADE、CONFIGURE、DETACH |
stage | BEFORE_RESOURCES、AFTER_RESOURCES |
operation.operationId、安装身份、插件身份和阶段由平台关联。插件按这些身份协调自己的业务状态,
不能另造安装记录或改变平台的操作结果。调用结果不确定时,Runtime 使用相同的操作身份和阶段
重复调用同一生命周期请求。插件必须安全处理重复执行并返回相应属性;已完成的业务变更不得重复创建资源。
executionSequence 是 Runtime 的正整数操作顺序,同一操作重试保持不变。
失败保留 Runtime 占用;DETACH 可以串行接管失败操作。所有者的顺序校验必须覆盖实际业务写入。
详见失败与重试。
配置变更的参与范围
Module 属性、完整配置、网关域名和 Bundle 内 Agent/Timer 配置统一进入 CONFIGURE。
Runtime 先比较实际变化,再依据完整 Locator 和当前已验证安装资源账确定参与的 Bundle,随后读取这些 Bundle 的插件绑定。
没有插件的已安装 Module 仍有真实 CONFIGURE 所有者;无变化不生成操作,也不会扫描无关 Bundle 的插件声明。
Module 或插件资源缺少合法安装归属时明确报错。没有 Module 身份和插件声明的 Runtime 本地服务按原本地配置合同保存,不伪造 Bundle 安装。
instanceRefProperty 仍受保护,不能通过改变 Locator 或另一条配置入口改写。
Runtime 编译后的授权
Bundle 作者通过领域对象选择声明授权;插件执行边界使用 Runtime 根据确切 Module 归属编译的资源定位。
下面是与后续请求对应的 SDK 授权结构,用于插件验证输入和输出;它不是作者清单,不能复制到 baijimu.bundle.json。
{
"pluginId": "tenant-provider",
"protocolVersion": "6.0.0",
"order": 0,
"failurePolicy": "FAIL_FAST",
"configuration": {"schemaVersion": "1.0.0", "values": {}},
"resources": [{
"resource": "publisher/sales/MODULE/customer",
"readProperties": ["region"],
"writeProperties": ["tenantId"],
"credentialProperties": ["inventory"]
}]
}生命周期请求
{
"contractVersion": "6.0.0",
"pluginId": "tenant-provider",
"executionSequence": 1,
"installation": {
"environmentKey": "consumer",
"applicationRuntimeId": "runtime-a",
"workspaceId": 42,
"bundleInstallId": "installation-a",
"bundle": {"environmentKey": "publisher", "bundleId": "sales"}
},
"operation": {
"operationId": "operation-a",
"operationType": "INSTALL",
"currentVersion": null,
"targetVersion": "1.0.0"
},
"stage": "BEFORE_RESOURCES",
"configuration": {"schemaVersion": "1.0.0", "values": {}},
"resources": {
"publisher/sales/MODULE/customer": {
"action": "INSTALL",
"currentVersion": null,
"targetVersion": "1.0.0",
"properties": {"region": {"@type": "Data", "value": "north"}},
"references": {"inventory": {"@type": "ServiceReference", "serviceId": "inventory-a"}}
}
}
}configuration.schemaVersion 属于插件自己的业务配置合同,不等于生命周期版本。
resources 的键为 ResourceLocator,只包含获授权的资源和属性。
properties 的每项输入和输出都必须是 {"@type":"Data","value":...},不接受裸值。
Runtime 按 Module 的属性定义校验 value,再写回一次 Data 包装,不递归猜测业务对象内的 @type。
SDK 的 decode_data() 用于读取业务值,from_data_values() 用于把业务值编码为输出;
decode() 与 from_properties() 保留完整的类型包装。
引用始终是逻辑 ServiceReference、Map 或 List,不附带调用地址或密钥。
响应
成功响应使用完整 CModel envelope:外层 contractVersion: "1.0.0"、errorCode: "0" 和 data。
data 原样关联请求的 contractVersion、pluginId、installation、operation、stage、executionSequence,
并返回 outcome 与 resources。
outcome 为 NOT_APPLIED、APPLIED、VERIFIED、FAILED 或 UNKNOWN。
resources 按 ResourceLocator 返回获准写入的业务 Data 属性,例如业务租户编号,以及插件自己签发、
按安装隔离的业务服务 Token。敏感业务属性必须声明 isSensitive: true,并由当前插件的
writeProperties 显式授权;它不属于用于引用解析授权的 credentialProperties。
不能回写引用属性、平台引用解析返回的 access 地址与 Token,或其他身份的共享管理凭据。
业务凭据的签发、轮换、撤销和保存边界见插件自有业务凭据。
Runtime 校验输出范围并决定安装进度。UNKNOWN 不能当成功处理。不得只返回裸 data。
{
"contractVersion": "1.0.0",
"errorCode": "0",
"data": {
"contractVersion": "6.0.0",
"pluginId": "tenant-provider",
"executionSequence": 1,
"installation": {
"environmentKey": "consumer",
"applicationRuntimeId": "runtime-a",
"workspaceId": 42,
"bundleInstallId": "installation-a",
"bundle": {
"environmentKey": "publisher",
"bundleId": "sales"
}
},
"operation": {
"operationId": "operation-a",
"operationType": "INSTALL",
"currentVersion": null,
"targetVersion": "1.0.0"
},
"stage": "BEFORE_RESOURCES",
"outcome": "APPLIED",
"resources": {
"publisher/sales/MODULE/customer": {
"tenantId": {"@type": "Data", "value": "tenant-a"}
}
}
}
}日常属性更新
修改已安装 Module 的属性会由所属 Bundle 执行 CONFIGURE,currentVersion 与 targetVersion 相同。
Runtime 在同一事务中保存目标配置并冻结现有 Bundle 操作和两阶段授权;失败的事务不会留下半份操作。
同一 Bundle 保留完整资源与插件范围,继续使用现有操作认领、派发和 Runtime 内部提交流程。
执行期间,其他用户配置写入会被拒绝;过期的配置快照不能覆盖新值。
网络中断后的重试保持 operationId + stage,插件返回同一业务结果及获准写入的 Data 属性。
业务调用前解析访问
插件使用独立平台凭据调用 POST /module-plugin-manager/api/bundle-plugin/service-reference/resolve。
在登记的平台 API 基地址后追加这个完整路径;不要再使用 /bundle-plugin/** 或 /plugin/** 别名。
该接口属于插件管理服务,公网网关按服务级 /api/** 规则映射,由插件管理服务验证插件凭据。
请求包含:
{
"contractVersion": "4.0.0",
"installation": {
"environmentKey": "consumer",
"applicationRuntimeId": "runtime-a",
"workspaceId": 42,
"bundleInstallId": "installation-a",
"bundle": {"environmentKey": "publisher", "bundleId": "sales"}
},
"resource": "publisher/sales/MODULE/customer",
"propertyKey": "inventory"
}不传 pluginId、目标服务 ID、URL 或 Token。平台从认证身份和活动安装的当前属性解析授权目标。
成功 data 返回相同的 installation、resource、propertyKey,以及当前逻辑 reference、
access[serviceId] = {url, token} 和 expiresAt。
完整的引用响应示例:
{
"contractVersion": "1.0.0",
"errorCode": "0",
"data": {
"contractVersion": "4.0.0",
"installation": {
"environmentKey": "consumer",
"applicationRuntimeId": "runtime-a",
"workspaceId": 42,
"bundleInstallId": "installation-a",
"bundle": {
"environmentKey": "publisher",
"bundleId": "sales"
}
},
"resource": "publisher/sales/MODULE/customer",
"propertyKey": "inventory",
"reference": {
"@type": "ServiceReference",
"serviceId": "inventory-a"
},
"access": {
"inventory-a": {
"url": "https://runtime.example/service/inventory-a",
"token": "example-current-access-token"
}
},
"expiresAt": null
}
}ServiceReferenceMap.valueMap 的业务键和 ServiceReferenceList.valueList 的顺序以当前响应 reference 为准;相同 serviceId 共用一份 access。
凭据仅用于本次业务操作,不持久化。任一目标未授权、安装失效或凭据撤销时,整次解析失败。
异步发布事件
Bundle 插件的后台 Worker 可以通过逻辑服务引用调用 Runtime 事件方法。Bundle 作者在 Module 中声明
引用属性,例如 eventPublisher,并将其绑定到拥有所需事件声明的 Module;发布自身事件时可以引用自身。
eventPublisher 是插件与 Bundle 作者约定的业务属性名,不是平台保留字段。在 Bundle 顶层声明插件绑定与该 Module 的资源授权。
在作者清单的插件授权中,把该属性加入 credentialProperties。使用目录返回的 Module 身份,例如:
{
"object": {"type": "MODULE", "moduleId": "a054ef60-f64c-47cf-8b63-4dbdd05e5ef1"},
"readProperties": [],
"writeProperties": [],
"credentialProperties": ["eventPublisher"]
}资源生效后,生命周期请求中的该属性为逻辑 ServiceReference。插件保存业务实例与
installation、资源 Locator、引用属性名的关联;不要保存事件 URL 或平台调用密钥。
每次发送及重试都执行以下步骤:
- 用当前安装定位、资源 Locator 和
propertyKey: "eventPublisher"请求上述访问解析接口。 - 验证响应的安装、资源、属性和有效期,按当前
reference.serviceId选择对应的access。 - 在服务基地址后添加目标 Module 已声明的事件方法名作为单个路径段,使用本次 token 作为 Bearer 凭据调用。
- 保持事件 ID 和业务幂等键不变,成功后确认 outbox;失败按业务重试策略处理,下次重新解析访问。
事件引用的授权与其他业务引用各自声明。销售活动等其他属性的授权不能代替事件发布授权。 解析失败、安装停止或卸载、授权撤销、响应身份不匹配或过期时不得投递;也不能使用此前保存的访问材料。 引用授权只授予当前目标允许的方法,事件名与载荷仍受目标 Module 的事件声明约束。
事件声明与订阅见模块事件与发布机制。 注册、Bundle 绑定及上线验收见Bundle 生命周期插件。
请求级 X-Runtime-Actor-Assertion 属于独立的Runtime 用户委托合同,不进入插件的安装关联或引用访问材料。