百积木文档
开发指南Bundle 生命周期插件开发

Bundle 生命周期与引用协议

使用 Bundle 安装身份、资源授权和按需访问解析,实现跨资源的外部业务生命周期。

Bundle 生命周期协议 6.0.0 以整个安装实例为操作边界,访问解析协议为 4.0.0。 所有自定义插件统一使用这一机制,Module 作为 Bundle 资源接受显式属性授权。

安装身份与执行语义

installation 包含安装环境 environmentKeyapplicationRuntimeIdworkspaceIdbundleInstallId 和 Bundle 来源 bundle.environmentKey + bundle.bundleId。 安装环境与 Bundle 来源可以不同,所有定位均由 Runtime 提供。

operationType + stage 表达操作与资源执行时机:

字段允许值
operation.operationTypeINSTALLUPGRADECONFIGUREDETACH
stageBEFORE_RESOURCESAFTER_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"datadata 原样关联请求的 contractVersionpluginIdinstallationoperationstageexecutionSequence, 并返回 outcomeresources

outcomeNOT_APPLIEDAPPLIEDVERIFIEDFAILEDUNKNOWNresources 按 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 执行 CONFIGUREcurrentVersiontargetVersion 相同。 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 返回相同的 installationresourcepropertyKey,以及当前逻辑 referenceaccess[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 或平台调用密钥。

每次发送及重试都执行以下步骤:

  1. 用当前安装定位、资源 Locator 和 propertyKey: "eventPublisher" 请求上述访问解析接口。
  2. 验证响应的安装、资源、属性和有效期,按当前 reference.serviceId 选择对应的 access
  3. 在服务基地址后添加目标 Module 已声明的事件方法名作为单个路径段,使用本次 token 作为 Bearer 凭据调用。
  4. 保持事件 ID 和业务幂等键不变,成功后确认 outbox;失败按业务重试策略处理,下次重新解析访问。

事件引用的授权与其他业务引用各自声明。销售活动等其他属性的授权不能代替事件发布授权。 解析失败、安装停止或卸载、授权撤销、响应身份不匹配或过期时不得投递;也不能使用此前保存的访问材料。 引用授权只授予当前目标允许的方法,事件名与载荷仍受目标 Module 的事件声明约束。

事件声明与订阅见模块事件与发布机制。 注册、Bundle 绑定及上线验收见Bundle 生命周期插件

请求级 X-Runtime-Actor-Assertion 属于独立的Runtime 用户委托合同,不进入插件的安装关联或引用访问材料。

本页内容