SPECIFICATION
第 5 章 协商机制
5.1 协商原则
DTP 实现 必须 强制执行以下协商原则:
- 协商先行:任何 Fragment 数据传输前,必须 已存在一个状态为
active的 Agreement。 - 无裸传输:实现 不得 允许不依赖 Agreement 的数据传输。
- 双向协商:主端 可 发起数据归集协商;从端 可 发起数据注入协商。
- 动态调整:双方 可 在 Agreement 处于
active状态时调整其参数。 - 明确终止:双方 可 明确终止 Agreement。终止后 必须 立即停止该约定下的数据传输。
5.2 协商帧类型
协商 必须 通过两种帧类型完成:Request_Frame 与 Response_Frame。
5.2.1 Request_Frame
Request_Frame 必须 包含以下字段:
interface RequestFrame {
frameType: "request";
requestId: string;
requestorRole: "master" | "slave";
requestType: "collection" | "injection" | "adjustment" | "termination";
targetAgreementId?: AgreementID;
proposedParams: AgreementParams;
}
| 字段 | 规范性要求 |
|---|---|
frameType | 必须 为字面量 "request" |
requestId | 必须 为请求的唯一标识符。应 使用 UUID v4 |
requestorRole | 必须 为 "master" 或 "slave",标识请求发起方 |
requestType | 必须 为下表四种类型之一 |
targetAgreementId | 当 requestType 为 "adjustment" 或 "termination" 时 必须 提供 |
proposedParams | 必须 提供完整的 AgreementParams(参见第 5.4 节) |
5.2.2 RequestType
| 值 | 语义 | 限制 |
|---|---|---|
"collection" | 数据归集请求 | 必须 由 requestorRole = "master" 发起 |
"injection" | 数据注入申请 | 必须 由 requestorRole = "slave" 发起 |
"adjustment" | 调整已有约定 | 必须 提供 targetAgreementId,目标约定 必须 处于 active 状态 |
"termination" | 终止已有约定 | 必须 提供 targetAgreementId |
实现 必须 拒绝不符合上述限制的请求并返回相应错误(参见第 9 章)。
5.2.3 Response_Frame
Response_Frame 必须 包含以下字段:
interface ResponseFrame {
frameType: "response";
requestId: string;
result: NegotiationResult;
agreedParams?: AgreementParams;
agreementId?: AgreementID;
rejectionReason?: string;
}
| 字段 | 规范性要求 |
|---|---|
frameType | 必须 为字面量 "response" |
requestId | 必须 为对应 Request_Frame 的 requestId |
result | 必须 为 NegotiationResult 之一 |
agreedParams | 当 result 为 accepted 或 counter_proposal 时 必须 提供 |
agreementId | 当 result 为 accepted 时 必须 提供,必须 是新生成的 UUID v4 |
rejectionReason | 当 result 为 rejected 时 必须 提供 |
5.2.4 NegotiationResult
NegotiationResult 必须 是以下三个值之一:
| 值 | 语义 |
|---|---|
"accepted" | 接受请求 |
"rejected" | 拒绝请求 |
"counter_proposal" | 提出替代方案 |
实现 不得 返回未列出的结果值。
5.3 协商流程
5.3.1 数据归集协商(Master 发起)
数据归集协商 必须 遵循以下流程:
- Master 发送 Request_Frame,
requestType = "collection",requestorRole = "master"。 - Slave 必须 回复 Response_Frame,包含以下三种结果之一:
"accepted":同意按proposedParams传输。必须 在 Response_Frame 中包含新生成的agreementId。"rejected":拒绝传输。必须 在rejectionReason中说明合规性约束(例如 DLP 策略)。不得 因非合规性原因拒绝。"counter_proposal":提出替代参数。必须 在agreedParams中提供修改后的参数。
- 如 Slave 回复
counter_proposal,Master 可 发送新的 Request_Frame 接受、拒绝或继续协商。 - Master 必须 持久化记录 Slave 对每次数据归集请求的响应结果。
5.3.2 数据注入协商(Slave 发起)
数据注入协商 必须 遵循以下流程:
- Slave 发送 Request_Frame,
requestType = "injection",requestorRole = "slave"。 - Master 必须 回复 Response_Frame,包含以下三种结果之一:
"accepted":同意提供数据。必须 在agreedParams中说明经过滤的数据范围(最小化数据集)。必须 在 Response_Frame 中包含新生成的agreementId。"rejected":拒绝提供数据。应 在rejectionReason中说明原因。"counter_proposal":提供不同范围或格式的数据。必须 在agreedParams中说明替代方案。
- Master 在数据注入决策中 必须 拥有完全决定权,不得 被强制接受请求。
5.3.3 协商超时
实现 必须 为 Request_Frame 设置超时阈值。如在阈值内未收到对端 Response_Frame:
- 请求方 应 重发 Request_Frame,重试次数 不得 超过实现配置的上限。
- 重试上限达到后,请求方 必须 终止协商并向上层应用通知
AGREEMENT_NEGOTIATION_FAILED错误(3003)。
5.4 约定参数(AgreementParams)
AgreementParams 必须 包含以下字段:
interface AgreementParams {
dataType: string;
dataRange: string;
transferMode: TransferMode;
frequency: number | null;
validityPeriod: number;
priority: Priority;
}
| 字段 | 类型 | 规范性要求 |
|---|---|---|
dataType | string | 必须 非空。标识数据类型 |
dataRange | string | 必须 非空。描述数据范围 |
transferMode | TransferMode | 必须 为下表三个值之一 |
frequency | number | null | 单位 Hz。当 transferMode = "one_time" 时 必须 为 null;其他模式时 必须 为正数 |
validityPeriod | number | 单位毫秒。必须 为正整数 |
priority | Priority | 必须 为下表四个值之一 |
5.4.1 TransferMode
| 值 | 语义 |
|---|---|
"one_time" | 一次性传输。Agreement 在数据传输完成后 应 自动终止 |
"periodic" | 周期性传输。必须 设置 frequency |
"streaming" | 流式传输。必须 设置 frequency |
5.4.2 Priority
| 值 | 语义 |
|---|---|
"low" | 低优先级 |
"normal" | 正常优先级(默认) |
"high" | 高优先级 |
"critical" | 紧急优先级 |
实现 应 在多个约定竞争资源时按 priority 调度。
5.5 约定生命周期
5.5.1 状态定义
AgreementStatus 必须 是以下四个值之一:
| 状态 | 语义 |
|---|---|
"negotiating" | 协商进行中 |
"active" | 约定生效,数据传输中 |
"suspended" | 连接中断,约定暂停 |
"terminated" | 约定终止 |
5.5.2 状态转换
约定状态 必须 遵循以下转换规则:
| 当前状态 | 触发事件 | 目标状态 |
|---|---|---|
| (无) | Request_Frame 发出 | negotiating |
negotiating | Response_Frame 返回 accepted | active |
negotiating | Response_Frame 返回 rejected | (终止) |
active | 底层连接断开 | suspended |
active | 收到 termination 类型 Request_Frame | terminated |
active | validityPeriod 超时 | terminated |
suspended | 连接恢复且 CAP 重新验证通过 | active |
suspended | 持久化超时 | terminated |
terminated | (终态) | (无) |
5.5.3 一次性约定的自动终止
当 transferMode = "one_time" 且数据传输完成时:
- 发送方 必须 在最后一个 Fragment 后通过
requestType = "termination"的 Request_Frame 终止该约定。 - 接收方 必须 在收到所有 Fragment 并确认后将约定状态设为
terminated。
5.6 多约定并发
DTP 实现 必须 支持单个会话中同时维护多个 active 状态的约定。
实现 必须 满足:
- 每个 Fragment 通过其 Agreement_ID 关联到具体约定。
- 不同约定的 Fragment 可 在传输流中交错。
- 多约定的实际传输方式(串行或并行)取决于 底层 Transport_Adapter 的能力。
- 实现 不得 限制单个会话中活跃约定的最大数量低于 16。应 支持任意数量。
5.7 旁观者协商限制
旁观者(Observer)角色 必须 满足:
- 不得 发送 Request_Frame。如尝试发送,DTP_Engine 必须 拒绝该操作并返回
OBSERVER_WRITE_DENIED错误(8002)。 - 不得 接收任何 Response_Frame 的决策权。
- 可 接收数据帧的只读副本。
- 必须 在加入旁观时由 Controller 显式授权。
