- 新增多个业务域的__init__.py模块文件,规范包导出结构 - 调整多个DTO文件的导入路径,统一模块组织方式 - 移除测试文件中多余的空行与导入语句 - 优化部分业务模块的包层级划分
641 lines
33 KiB
Python
641 lines
33 KiB
Python
"""控制面管道。
|
||
|
||
装配 5 个控制面阶段(auth → permission → rate-limit → dispatch → audit),
|
||
按顺序执行阶段并按失败策略处理异常。auth / permission / rate-limit / dispatch
|
||
阶段 failure=TERMINATE,确保认证 / 权限 / 限流 / 分派任一环节失败即中止
|
||
请求;audit 阶段 failure=DEGRADE,审计失败仅降级不阻塞主流程。
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from typing import TYPE_CHECKING
|
||
|
||
# H-1: 控制面写操作用例服务(handler 委托)
|
||
from yuxi.channels.application.account.usecase.channel_account_write_service import (
|
||
ChannelAccountWriteService,
|
||
)
|
||
from yuxi.channels.application.control_plane.audit_context_builder import (
|
||
AuditContextBuilder,
|
||
)
|
||
from yuxi.channels.application.control_plane.handlers.account_handler import (
|
||
AccountHandler,
|
||
)
|
||
from yuxi.channels.application.control_plane.handlers.agent_handler import (
|
||
AgentHandler,
|
||
)
|
||
from yuxi.channels.application.control_plane.handlers.analytics_handler import (
|
||
AnalyticsHandler,
|
||
)
|
||
from yuxi.channels.application.control_plane.handlers.audit_handler import (
|
||
AuditHandler,
|
||
)
|
||
from yuxi.channels.application.control_plane.handlers.capability_handler import (
|
||
CapabilityHandler,
|
||
)
|
||
from yuxi.channels.application.control_plane.handlers.config_handler import (
|
||
ConfigHandler,
|
||
)
|
||
from yuxi.channels.application.control_plane.handlers.content_review_handler import (
|
||
ContentReviewHandler,
|
||
)
|
||
from yuxi.channels.application.control_plane.handlers.dashboard_handler import (
|
||
DashboardHandler,
|
||
)
|
||
from yuxi.channels.application.control_plane.handlers.directory_handler import (
|
||
DirectoryHandler,
|
||
)
|
||
from yuxi.channels.application.control_plane.handlers.doctor_handler import (
|
||
DoctorHandler,
|
||
)
|
||
from yuxi.channels.application.control_plane.handlers.health_handler import (
|
||
HealthHandler,
|
||
)
|
||
from yuxi.channels.application.control_plane.handlers.identity_handler import (
|
||
IdentityHandler,
|
||
)
|
||
from yuxi.channels.application.control_plane.handlers.login_handler import (
|
||
LoginHandler,
|
||
)
|
||
from yuxi.channels.application.control_plane.handlers.message_handler import (
|
||
MessageHandler,
|
||
)
|
||
from yuxi.channels.application.control_plane.handlers.outbox_handler import (
|
||
OutboxHandler,
|
||
)
|
||
from yuxi.channels.application.control_plane.handlers.pairing_handler import (
|
||
PairingHandler,
|
||
)
|
||
from yuxi.channels.application.control_plane.handlers.plugin_handler import (
|
||
PluginHandler,
|
||
)
|
||
from yuxi.channels.application.control_plane.handlers.route_binding_handler import (
|
||
RouteBindingHandler,
|
||
)
|
||
from yuxi.channels.application.control_plane.handlers.session_handler import (
|
||
SessionHandler,
|
||
)
|
||
from yuxi.channels.application.control_plane.handlers.webhook_handler import (
|
||
WebhookHandler,
|
||
)
|
||
from yuxi.channels.application.control_plane.handlers.whitelist_handler import (
|
||
WhitelistHandler,
|
||
)
|
||
from yuxi.channels.application.control_plane.handlers.wizard_handler import (
|
||
WizardHandler,
|
||
)
|
||
from yuxi.channels.application.control_plane.stages.audit_stage import AuditStage
|
||
from yuxi.channels.application.control_plane.stages.auth_stage import AuthStage
|
||
from yuxi.channels.application.control_plane.stages.dispatch_stage import (
|
||
DispatchStage,
|
||
)
|
||
from yuxi.channels.application.control_plane.stages.permission_stage import (
|
||
PermissionStage,
|
||
)
|
||
from yuxi.channels.application.control_plane.stages.rate_limit_stage import (
|
||
RateLimitStage,
|
||
)
|
||
from yuxi.channels.application.control_plane.usecase.session_write_service import (
|
||
SessionWriteService,
|
||
)
|
||
from yuxi.channels.application.messaging.pipeline.base import Pipeline
|
||
from yuxi.channels.application.observability.circuit_breaker.channel_circuit_breaker import (
|
||
ChannelCircuitBreaker,
|
||
)
|
||
from yuxi.channels.application.observability.health.channel_probe import ChannelProbe
|
||
from yuxi.channels.application.outbox.usecase.message_outbox_service import (
|
||
MessageOutboxService,
|
||
)
|
||
from yuxi.channels.application.pairing.usecase.pairing_write_service import (
|
||
PairingWriteService,
|
||
)
|
||
from yuxi.channels.application.plugin.lifecycle.plugin_loader import PluginLoader
|
||
from yuxi.channels.application.plugin.lifecycle.sensitive_field_registry import (
|
||
SensitiveFieldRegistry,
|
||
)
|
||
from yuxi.channels.contract.dtos.messaging.channel import ChannelType
|
||
from yuxi.channels.contract.dtos.outbox.outbox import OutboxConfig, OutboxConfigHolder
|
||
from yuxi.channels.contract.plugin.adapters.attachment_upload_adapter import (
|
||
AttachmentUploadAdapter,
|
||
)
|
||
from yuxi.channels.contract.plugin.adapters.content_moderation_adapter import (
|
||
ContentModerationAdapter,
|
||
)
|
||
from yuxi.channels.contract.plugin.adapters.directory_adapter import DirectoryAdapter
|
||
from yuxi.channels.contract.plugin.adapters.webhook_test_adapter import WebhookTestAdapter
|
||
from yuxi.channels.contract.plugin.adapters.whitelist_adapter import WhitelistAdapter
|
||
from yuxi.channels.contract.ports.driven.account.service_account_port import ServiceAccountPort
|
||
from yuxi.channels.contract.ports.driven.audit.content_review_repository_port import (
|
||
ContentReviewRepositoryPort,
|
||
)
|
||
from yuxi.channels.contract.ports.driven.config.config_port import ConfigPort
|
||
from yuxi.channels.contract.ports.driven.messaging.conversation_port import ConversationPort
|
||
from yuxi.channels.contract.ports.driven.messaging.event_publisher_port import EventPublisherPort
|
||
from yuxi.channels.contract.ports.driven.messaging.message_ops_port import MessageOpsPort
|
||
from yuxi.channels.contract.ports.driven.outbox.outbox_repository_port import OutboxRepositoryPort
|
||
from yuxi.channels.contract.ports.driven.plugin.channel_plugin_repository_port import (
|
||
ChannelPluginRepositoryPort,
|
||
)
|
||
from yuxi.channels.contract.ports.driven.plugin.plugin_lifecycle_manager_port import (
|
||
PluginLifecycleManagerPort,
|
||
)
|
||
from yuxi.channels.contract.ports.driven.routing.route_binding_repository_port import (
|
||
RouteBindingRepositoryPort,
|
||
)
|
||
from yuxi.channels.contract.ports.driven.shared.cache_port import CachePort
|
||
from yuxi.channels.contract.ports.driven.shared.logger_port import LoggerPort
|
||
from yuxi.channels.contract.ports.driven.shared.masking_port import MaskingPort
|
||
from yuxi.channels.contract.ports.driven.shared.persistence_port import PersistencePort
|
||
from yuxi.channels.contract.ports.driven.shared.queue_port import QueuePort
|
||
from yuxi.channels.contract.ports.driven.shared.realtime_metrics_port import (
|
||
RealtimeMetricsPort,
|
||
)
|
||
from yuxi.channels.contract.ports.driven.shared.tracer_port import TracerPort
|
||
from yuxi.channels.contract.ports.driven.shared.transaction_port import TransactionPort
|
||
from yuxi.channels.contract.ports.driving.messaging.admin_message_port import AdminMessagePort
|
||
from yuxi.channels.core.account.account_creation_service import (
|
||
AccountCreationService,
|
||
)
|
||
from yuxi.channels.core.account.account_lifecycle_service import (
|
||
AccountLifecycleService,
|
||
)
|
||
|
||
# Task 11: 注入 CredentialService 到 AccountHandler(P1 enable/disable 链路)
|
||
from yuxi.channels.core.account.credential_service import CredentialService
|
||
from yuxi.channels.core.account.doctor_service import DoctorService
|
||
from yuxi.channels.core.account.qr_login_service import QrLoginService
|
||
from yuxi.channels.core.account.wizard_service import WizardService
|
||
from yuxi.channels.core.config.config_manager import ConfigManager
|
||
from yuxi.channels.core.plugin.degradation_manager import DegradationManager
|
||
from yuxi.channels.core.plugin.plugin_registry import PluginRegistry
|
||
from yuxi.channels.core.routing.route_match_registry import RouteMatchRegistry
|
||
from yuxi.channels.core.routing.route_resolver import RouteResolver
|
||
from yuxi.channels.core.session.session_merger import SessionMerger
|
||
from yuxi.channels.core.whitelist.whitelist_registry import WhitelistRegistry
|
||
|
||
if TYPE_CHECKING:
|
||
# C-13: IdentityMergeService 仅为工厂方法签名类型注解,运行时不构造
|
||
# (由 DI 层注入实例)。放 TYPE_CHECKING 守卫避免 control_plane_pipeline
|
||
# → identity_handler → usecase.identity_merge_service → usecase/__init__
|
||
# → channel_control_service → control_plane_pipeline 的循环导入。
|
||
from yuxi.channels.application.control_plane.usecase.identity_merge_service import (
|
||
IdentityMergeService,
|
||
)
|
||
|
||
|
||
class ControlPlanePipeline(Pipeline):
|
||
"""控制面管道。
|
||
|
||
装配 5 个控制面阶段,按顺序执行。阶段顺序:
|
||
auth → permission → rate-limit → dispatch → audit
|
||
|
||
auth / permission / rate-limit / dispatch 阶段 failure=TERMINATE,确保
|
||
任一环节失败即中止请求;audit 阶段 failure=DEGRADE,审计失败仅降级
|
||
不阻塞主流程。
|
||
"""
|
||
|
||
def __init__(
|
||
self,
|
||
auth_stage: AuthStage,
|
||
permission_stage: PermissionStage,
|
||
rate_limit_stage: RateLimitStage,
|
||
dispatch_stage: DispatchStage,
|
||
audit_stage: AuditStage,
|
||
logger: LoggerPort | None = None,
|
||
tracer_port: TracerPort | None = None,
|
||
) -> None:
|
||
"""初始化控制面管道。
|
||
|
||
参数:
|
||
auth_stage: auth 阶段实例。
|
||
permission_stage: permission 阶段实例。
|
||
rate_limit_stage: rate-limit 阶段实例。
|
||
dispatch_stage: dispatch 阶段实例。
|
||
audit_stage: audit 阶段实例。
|
||
logger: 可选日志端口。
|
||
"""
|
||
stages = [
|
||
auth_stage,
|
||
permission_stage,
|
||
rate_limit_stage,
|
||
dispatch_stage,
|
||
audit_stage,
|
||
]
|
||
super().__init__(name="control-plane", stages=stages, logger=logger, tracer_port=tracer_port)
|
||
|
||
@classmethod
|
||
def create(
|
||
cls,
|
||
*,
|
||
persistence_port: PersistencePort,
|
||
config_manager: ConfigManager,
|
||
config_port: ConfigPort,
|
||
session_merger: SessionMerger,
|
||
degradation_manager: DegradationManager,
|
||
whitelist_registry: WhitelistRegistry,
|
||
cache_port: CachePort,
|
||
event_publisher: EventPublisherPort,
|
||
plugin_registry: PluginRegistry,
|
||
wizard_service: WizardService | None = None,
|
||
directory_adapter_registry: dict[ChannelType, DirectoryAdapter] | None = None,
|
||
doctor_service: DoctorService | None = None,
|
||
whitelist_adapter_registry: dict[ChannelType, WhitelistAdapter] | None = None,
|
||
logger: LoggerPort | None = None,
|
||
lifecycle_service: AccountLifecycleService | None = None,
|
||
login_service: QrLoginService | None = None,
|
||
conversation_port: ConversationPort | None = None,
|
||
lifecycle_manager: PluginLifecycleManagerPort | None = None,
|
||
circuit_breaker: ChannelCircuitBreaker | None = None,
|
||
message_ops_port: MessageOpsPort | None = None,
|
||
outbox_repository: OutboxRepositoryPort | None = None,
|
||
outbox_config: OutboxConfig | None = None,
|
||
outbox_config_holder: OutboxConfigHolder | None = None,
|
||
queue_port: QueuePort | None = None,
|
||
content_moderation_adapters: dict[ChannelType, ContentModerationAdapter] | None = None,
|
||
default_moderation_adapter: ContentModerationAdapter | None = None,
|
||
review_repository: ContentReviewRepositoryPort | None = None,
|
||
masking_port: MaskingPort,
|
||
transaction_port: TransactionPort | None = None,
|
||
plugin_loader: PluginLoader | None = None,
|
||
webhook_test_adapters: dict[ChannelType, WebhookTestAdapter] | None = None,
|
||
attachment_upload_adapters: dict[ChannelType, AttachmentUploadAdapter] | None = None,
|
||
channel_probe: ChannelProbe | None = None,
|
||
realtime_metrics: RealtimeMetricsPort | None = None,
|
||
service_account_port: ServiceAccountPort | None = None,
|
||
# Task 11: 凭证编排服务,注入到 AccountHandler(P0 暂不调用)
|
||
credential_service: CredentialService | None = None,
|
||
account_creation_service: AccountCreationService | None = None,
|
||
# F-01:敏感字段注册表,注入到 ConfigHandler(config/export 过滤)
|
||
# 与 AuditContextBuilder(params_summary 脱敏)
|
||
sensitive_registry: SensitiveFieldRegistry | None = None,
|
||
# Task 13: 路由绑定管理依赖,注入到 RouteBindingHandler
|
||
# (route_binding/* 系列操作)。route_binding_repository 复用
|
||
# persistence 适配器(实现 RouteBindingRepositoryPort)。
|
||
route_binding_repository: RouteBindingRepositoryPort | None = None,
|
||
# P1-D1: 插件安装记录仓储端口,注入到 PluginHandler 供 install/uninstall
|
||
# 持久化安装元数据。复用 persistence 适配器(实现 ChannelPluginRepositoryPort)。
|
||
plugin_repository: ChannelPluginRepositoryPort | None = None,
|
||
route_resolver: RouteResolver | None = None,
|
||
route_match_registry: RouteMatchRegistry | None = None,
|
||
# Task 11: 管理员消息续投端口,注入到 MessageHandler 供
|
||
# admin-message/retry-failed 操作调用 retryFailedTargets。
|
||
admin_message_port: AdminMessagePort | None = None,
|
||
# C-13: 身份合并回滚用例服务,注入到 IdentityHandler 供
|
||
# identity/rollback-merge 操作调用 rollbackMerge。为 ``None`` 时调用
|
||
# identity/* 操作抛 ``NotImplementedError``(501)。默认为 ``None``。
|
||
identity_merge_service: IdentityMergeService | None = None,
|
||
# H-4: 追踪端口,为每个 stage 包裹独立 span(§11.2)。
|
||
tracer_port: TracerPort | None = None,
|
||
) -> ControlPlanePipeline:
|
||
"""工厂方法:接收所有依赖,构造 5 个阶段并返回 ControlPlanePipeline 实例。
|
||
|
||
参数:
|
||
persistence_port: 持久化被驱动端口。
|
||
config_manager: 配置热更新领域服务。
|
||
config_port: 配置被驱动端口(``ConfigPort``),注入到
|
||
``CapabilityHandler`` 用于 CAP-03 运行时可用性推导。
|
||
session_merger: 会话合并领域服务。
|
||
degradation_manager: 优雅降级领域服务。
|
||
whitelist_registry: 白名单注册表,用于 whitelist/list 读取与
|
||
默认实现的内存缓存(FR-18)。
|
||
cache_port: 缓存被驱动端口。
|
||
event_publisher: 事件发布端口,用于发布领域事件。
|
||
plugin_registry: 插件注册表,用于检查渠道插件是否处于 FAILED
|
||
状态(FR-36 配对审批降级检查)。
|
||
wizard_service: 安装向导领域服务(FR-16),用于 wizard/* 操作。
|
||
为 ``None`` 时调用 wizard/* 操作返回 501。默认为 ``None``。
|
||
directory_adapter_registry: 目录适配器注册表,键为渠道类型
|
||
(FR-14)。未注册目录适配器的渠道调用 directory/* 操作时
|
||
返回 501。默认为 ``None``,等价于空注册表。
|
||
doctor_service: 配置诊断领域服务(FR-17),用于 doctor/* 操作。
|
||
为 ``None`` 时调用 doctor/* 操作返回 501。默认为 ``None``。
|
||
whitelist_adapter_registry: 白名单适配器注册表,键为渠道类型
|
||
(FR-18)。注册了适配器的渠道将白名单操作委托到插件;未注册
|
||
的渠道使用默认实现(读写 ``allow_from`` 配置)。默认为
|
||
``None``,等价于空注册表。
|
||
logger: 可选日志端口。
|
||
lifecycle_service: 账户生命周期领域服务(AL-01~AL-04),用于
|
||
``account/*`` 操作的回调编排。为 ``None`` 时 account/create
|
||
与 account/update 抛 ValidationError,其余 account/* 操作
|
||
跳过回调逻辑。默认为 ``None``。
|
||
login_service: 扫码登录领域服务(QR-01~QR-04),用于
|
||
``login/*`` 操作的扫码登录流程编排。为 ``None`` 时调用
|
||
``login/*`` 操作抛 ``NotImplementedError``(501)。默认为 ``None``。
|
||
conversation_port: 会话被驱动端口,用于 ``message/*`` 操作的
|
||
消息查询(运维排查用例)。为 ``None`` 时调用 ``message/*``
|
||
操作抛 ``NotImplementedError``(501)。默认为 ``None``。
|
||
lifecycle_manager: 插件生命周期管理器被驱动端口
|
||
(``PluginLifecycleManagerPort``),用于 ``plugin/*`` 操作的
|
||
生命周期编排(FR-32)。为 ``None`` 时调用 ``plugin/*`` 操作
|
||
抛 ``NotImplementedError``(501)。默认为 ``None``。
|
||
circuit_breaker: 渠道熔断器(``ChannelCircuitBreaker``),用于
|
||
``account/runtime_status`` 操作聚合熔断器状态快照(AC-32)。
|
||
为 ``None`` 时 ``circuit_breaker`` 字段返回 ``null``,degraded
|
||
仅依据账户状态判定。默认为 ``None``。
|
||
message_ops_port: 消息操作被驱动端口(``MessageOpsPort``),用于
|
||
``message/recall`` 操作的 IM 平台撤回调用。为 ``None`` 时调用
|
||
``message/recall`` 操作抛 ``NotImplementedError``(501)。默认
|
||
为 ``None``。
|
||
outbox_repository: 发件箱仓储被驱动端口(``OutboxRepositoryPort``),
|
||
用于 ``outbox/*`` 操作的查询、统计与逻辑删除(OBX-01~OBX-08)。
|
||
为 ``None`` 时调用 ``outbox/*`` 操作抛 ``NotImplementedError``
|
||
(501)。默认为 ``None``。
|
||
outbox_config: 发件箱配置(``OutboxConfig``),用于 ``outbox/retry_policy``
|
||
操作返回装配期配置快照。为 ``None`` 时调用该操作抛
|
||
``NotImplementedError``(501)。默认为 ``None``。
|
||
outbox_config_holder: 发件箱配置可变持有器
|
||
(``OutboxConfigHolder``),支持 ``outbox/update_retry_policy``
|
||
热更新配置。非空时优先使用 holder,``outbox_config`` 仅作
|
||
回退构造 holder 的初始值。默认为 ``None``。
|
||
queue_port: 队列被驱动端口(``QueuePort``),用于 ``outbox/retry`` 操作
|
||
入队 ARQ 重试任务。为 ``None`` 时调用 ``outbox/retry`` 操作
|
||
抛 ``NotImplementedError``(501)。默认为 ``None``。
|
||
content_moderation_adapters: 内容审核插件适配器列表
|
||
(``ContentModerationAdapter``),按 ``channel_type`` 索引。
|
||
装配期校验同 ``channel_type`` 唯一性
|
||
(``RuleViolationError(rule="content_moderation_adapter_duplicate")``)。
|
||
为 ``None`` 时等价于空列表,``content_review/preview`` 使用兜底
|
||
适配器。默认为 ``None``。
|
||
default_moderation_adapter: 默认内容审核适配器
|
||
(``DefaultContentModerationAdapter``),未注册插件渠道时兜底。
|
||
为 ``None`` 且无插件匹配时 ``content_review/preview`` 抛
|
||
``ValidationError``(不静默兜底)。默认为 ``None``。
|
||
review_repository: 内容审核历史仓储端口
|
||
(``ContentReviewRepositoryPort``),用于 ``content_review/preview``
|
||
写入审核记录。为 ``None`` 时调用 ``content_review/preview`` 抛
|
||
``ValidationError``(不静默兜底)。默认为 ``None``。
|
||
masking_port: 脱敏被驱动端口(``MaskingPort``),必填。供
|
||
``AuditContextBuilder`` 对 ``params_summary`` 全量遮蔽脱敏,
|
||
及 ``DispatchStage`` 对账户 ``config`` / ``operations_history``
|
||
脱敏(FR-34)。
|
||
transaction_port: 事务端口(Pattern D 逐条独立事务),供
|
||
``DispatchStage._executeBatch`` 批量编排使用。默认为 ``None``。
|
||
plugin_loader: 插件加载器(``PluginLoader``),用于 PLG-INSTALL /
|
||
PLG-UNINSTALL 文件操作。默认为 ``None``。
|
||
webhook_test_adapters: Webhook 测试适配器注册表
|
||
(``WebhookTestAdapter``),按 ``channel_type`` 索引。默认为 ``None``。
|
||
attachment_upload_adapters: 附件上传适配器注册表
|
||
(``AttachmentUploadAdapter``),按 ``channel_type`` 索引。默认为
|
||
``None``。
|
||
channel_probe: 渠道主动探测器(``ChannelProbe``),用于
|
||
``account/runtime_status``(聚合探测状态)。为 ``None`` 时
|
||
上述操作跳过主动探测。默认为 ``None``。
|
||
realtime_metrics: 实时指标端口(可选),注入到 DashboardHandler
|
||
供 ``dashboard/realtime`` 查询消息速率与活跃会话计数
|
||
(DSB-REALTIME)。为 ``None`` 时实时指标返回零值。默认为
|
||
``None``。
|
||
service_account_port: 服务账号领域服务被驱动端口(可选),注入到
|
||
AccountHandler 供 ``account/create`` 在事务内幂等创建服务账号
|
||
并回填 ``service_user_uid``。为 ``None`` 时账户创建不绑定服务
|
||
账号(向后兼容)。默认为 ``None``。
|
||
credential_service: 凭证编排服务(Task 11 注入,可选),注入到
|
||
AccountHandler 供 P1 enable/disable 链路凭证撤销使用。P0 阶段
|
||
暂不调用,仅完成依赖注入装配。默认为 ``None``。
|
||
sensitive_registry: 敏感字段注册表(F-01,可选),注入到
|
||
``ConfigHandler``(``config/export`` 过滤敏感字段)与
|
||
``AuditContextBuilder``(``params_summary`` 顶层敏感 key 脱敏)。
|
||
为 ``None`` 时回退至 ``hot_reloadable`` 过滤与 ``maskFull``
|
||
关键词兜底(向后兼容)。默认为 ``None``。
|
||
route_binding_repository: 路由绑定仓储端口
|
||
(``RouteBindingRepositoryPort``,Task 13 注入,可选),注入到
|
||
``RouteBindingHandler`` 供 ``route_binding/*`` 系列操作读写绑定
|
||
规则。复用 persistence 适配器(实现该端口)。为 ``None`` 时调用
|
||
``route_binding/*`` 操作抛 ``NotImplementedError``(501)。默认
|
||
为 ``None``。
|
||
plugin_repository: 插件安装记录仓储端口
|
||
(``ChannelPluginRepositoryPort``,P1-D1 注入,可选),注入到
|
||
``PluginHandler`` 供 install/uninstall 持久化安装元数据与
|
||
lifecycle 操作同步 ``last_known_state``。复用 persistence 适配器
|
||
(实现该端口)。为 ``None`` 时跳过 DB 持久化(仅内存注册表)。
|
||
route_resolver: 路由解析领域服务(``RouteResolver``,可选),注入到
|
||
``RouteBindingHandler`` 供 ``route_binding/resolve`` 路由解析测试。
|
||
为 ``None`` 时该操作抛 ``NotImplementedError``(501)。默认为
|
||
``None``。
|
||
route_match_registry: 路由匹配注册表(``RouteMatchRegistry``,可选),
|
||
注入到 ``RouteBindingHandler`` 供 create 增量刷新 / update / delete
|
||
全量刷新匹配注册表。为 ``None`` 时刷新逻辑抛
|
||
``NotImplementedError``(501)。默认为 ``None``。
|
||
admin_message_port: 管理员消息驱动端口(``AdminMessagePort``,可选),
|
||
注入到 ``MessageHandler`` 供 ``admin-message/retry-failed`` 操作
|
||
调用 ``retryFailedTargets`` 续投 fan-out 失败目标(Task 11)。
|
||
为 ``None`` 时该操作抛 ``NotImplementedError``(501)。默认为
|
||
``None``。
|
||
identity_merge_service: 身份合并回滚用例服务
|
||
(``IdentityMergeService``,C-13 可选),注入到 ``IdentityHandler``
|
||
供 ``identity/rollback-merge`` 操作调用 ``rollbackMerge`` 回滚坏
|
||
合并。为 ``None`` 时调用 ``identity/*`` 操作抛
|
||
``NotImplementedError``(501)。默认为 ``None``。
|
||
|
||
返回:
|
||
装配完成的 ControlPlanePipeline 实例。
|
||
"""
|
||
auth_stage = AuthStage()
|
||
permission_stage = PermissionStage()
|
||
rate_limit_stage = RateLimitStage(cache_port=cache_port)
|
||
audit_builder = AuditContextBuilder(
|
||
audit_log_repo=persistence_port,
|
||
logger=logger,
|
||
masking_port=masking_port,
|
||
sensitive_registry=sensitive_registry,
|
||
)
|
||
# H-1: 控制面写操作用例服务(handler 委托)。显式构造使依赖装配
|
||
# 集中在 DI 层,便于追踪与替换。各 handler __init__ 仍支持未注入时
|
||
# 自动构造(向后兼容测试与旧调用方)。
|
||
pairing_write_service = PairingWriteService(
|
||
persistence_port=persistence_port,
|
||
event_publisher=event_publisher,
|
||
plugin_registry=plugin_registry,
|
||
logger=logger,
|
||
)
|
||
channel_account_write_service = ChannelAccountWriteService(
|
||
persistence_port=persistence_port,
|
||
lifecycle_service=lifecycle_service,
|
||
event_publisher=event_publisher,
|
||
plugin_registry=plugin_registry,
|
||
credential_service=credential_service,
|
||
)
|
||
session_write_service = SessionWriteService(persistence_port)
|
||
message_outbox_service = (
|
||
MessageOutboxService(persistence_port, conversation_port) if conversation_port is not None else None
|
||
)
|
||
# 所有批量 handler(config/account/message/session/content_review/
|
||
# pairing/whitelist/outbox/plugin)均按 transaction_port 内部自建
|
||
# BatchExecutor,无共享实例。
|
||
handlers = [
|
||
ConfigHandler(
|
||
config_manager=config_manager,
|
||
transaction_port=transaction_port,
|
||
logger=logger,
|
||
sensitive_registry=sensitive_registry,
|
||
),
|
||
CapabilityHandler(
|
||
plugin_registry=plugin_registry,
|
||
config_port=config_port,
|
||
logger=logger,
|
||
),
|
||
WizardHandler(wizard_service=wizard_service, logger=logger),
|
||
AuditHandler(
|
||
persistence_port=persistence_port,
|
||
config_manager=config_manager,
|
||
logger=logger,
|
||
),
|
||
AnalyticsHandler(
|
||
persistence_port=persistence_port,
|
||
review_repository=review_repository,
|
||
cache_port=cache_port,
|
||
logger=logger,
|
||
),
|
||
ContentReviewHandler(
|
||
content_moderation_adapters=content_moderation_adapters,
|
||
default_moderation_adapter=default_moderation_adapter,
|
||
review_repository=review_repository,
|
||
transaction_port=transaction_port,
|
||
logger=logger,
|
||
persistence_port=persistence_port,
|
||
),
|
||
AccountHandler(
|
||
persistence_port=persistence_port,
|
||
event_publisher=event_publisher,
|
||
plugin_registry=plugin_registry,
|
||
lifecycle_service=lifecycle_service,
|
||
audit_context_builder=audit_builder,
|
||
masking_port=masking_port,
|
||
circuit_breaker=circuit_breaker,
|
||
login_service=login_service,
|
||
channel_probe=channel_probe,
|
||
transaction_port=transaction_port,
|
||
service_account_port=service_account_port,
|
||
logger=logger,
|
||
# Task 11: 凭证编排服务,供 P1 enable/disable 链路凭证撤销(P0 暂不调用)
|
||
credential_service=credential_service,
|
||
account_creation_service=account_creation_service,
|
||
# H-1: 账户写操作用例服务
|
||
channel_account_write_service=channel_account_write_service,
|
||
),
|
||
# agent_management_port 原工厂未传入(保持原有行为,agent/* 返回 501)
|
||
AgentHandler(logger=logger),
|
||
HealthHandler(
|
||
persistence_port=persistence_port,
|
||
degradation_manager=degradation_manager,
|
||
plugin_registry=plugin_registry,
|
||
circuit_breaker=circuit_breaker,
|
||
queue_port=queue_port,
|
||
logger=logger,
|
||
),
|
||
MessageHandler(
|
||
persistence_port=persistence_port,
|
||
conversation_port=conversation_port,
|
||
masking_port=masking_port,
|
||
message_ops_port=message_ops_port,
|
||
queue_port=queue_port,
|
||
transaction_port=transaction_port,
|
||
attachment_upload_adapters=attachment_upload_adapters,
|
||
logger=logger,
|
||
admin_message_port=admin_message_port,
|
||
# H-1: 消息发件箱写操作用例服务
|
||
message_outbox_service=message_outbox_service,
|
||
),
|
||
SessionHandler(
|
||
session_merger=session_merger,
|
||
persistence_port=persistence_port,
|
||
conversation_port=conversation_port,
|
||
config_manager=config_manager,
|
||
masking_port=masking_port,
|
||
transaction_port=transaction_port,
|
||
event_publisher=event_publisher,
|
||
logger=logger,
|
||
# H-1: 会话写操作用例服务
|
||
session_write_service=session_write_service,
|
||
),
|
||
LoginHandler(
|
||
login_service=login_service,
|
||
logger=logger,
|
||
persistence_port=persistence_port,
|
||
audit_context_builder=audit_builder,
|
||
event_publisher=event_publisher,
|
||
),
|
||
DirectoryHandler(
|
||
directory_adapter_registry=directory_adapter_registry,
|
||
cache_port=cache_port,
|
||
logger=logger,
|
||
config_manager=config_manager,
|
||
persistence_port=persistence_port,
|
||
),
|
||
DashboardHandler(
|
||
persistence_port=persistence_port,
|
||
conversation_port=conversation_port,
|
||
outbox_repository=outbox_repository,
|
||
review_repository=review_repository,
|
||
queue_port=queue_port,
|
||
realtime_metrics=realtime_metrics,
|
||
plugin_registry=plugin_registry,
|
||
logger=logger,
|
||
),
|
||
PairingHandler(
|
||
persistence_port=persistence_port,
|
||
plugin_registry=plugin_registry,
|
||
event_publisher=event_publisher,
|
||
transaction_port=transaction_port,
|
||
logger=logger,
|
||
# H-1: 配对写操作用例服务
|
||
pairing_write_service=pairing_write_service,
|
||
),
|
||
WhitelistHandler(
|
||
whitelist_registry=whitelist_registry,
|
||
config_manager=config_manager,
|
||
whitelist_adapter_registry=whitelist_adapter_registry,
|
||
transaction_port=transaction_port,
|
||
logger=logger,
|
||
),
|
||
DoctorHandler(
|
||
doctor_service=doctor_service,
|
||
persistence_port=persistence_port,
|
||
logger=logger,
|
||
),
|
||
WebhookHandler(
|
||
persistence_port=persistence_port,
|
||
webhook_test_adapters=webhook_test_adapters,
|
||
logger=logger,
|
||
),
|
||
PluginHandler(
|
||
lifecycle_manager=lifecycle_manager,
|
||
plugin_loader=plugin_loader,
|
||
plugin_registry=plugin_registry,
|
||
config_manager=config_manager,
|
||
transaction_port=transaction_port,
|
||
plugin_repository=plugin_repository,
|
||
logger=logger,
|
||
),
|
||
OutboxHandler(
|
||
outbox_repository=outbox_repository,
|
||
outbox_config=outbox_config,
|
||
outbox_config_holder=outbox_config_holder,
|
||
queue_port=queue_port,
|
||
transaction_port=transaction_port,
|
||
config_manager=config_manager,
|
||
logger=logger,
|
||
),
|
||
RouteBindingHandler(
|
||
repo_port=route_binding_repository,
|
||
route_resolver=route_resolver,
|
||
registry=route_match_registry,
|
||
event_publisher=event_publisher,
|
||
logger=logger,
|
||
persistence_port=persistence_port,
|
||
),
|
||
IdentityHandler(
|
||
identity_merge_service=identity_merge_service,
|
||
logger=logger,
|
||
),
|
||
]
|
||
dispatch_stage = DispatchStage(handlers=handlers)
|
||
audit_stage = AuditStage(audit_builder=audit_builder)
|
||
return cls(
|
||
auth_stage=auth_stage,
|
||
permission_stage=permission_stage,
|
||
rate_limit_stage=rate_limit_stage,
|
||
dispatch_stage=dispatch_stage,
|
||
audit_stage=audit_stage,
|
||
logger=logger,
|
||
tracer_port=tracer_port,
|
||
)
|