Files

159 lines
6.4 KiB
Python

"""Composition root for the independent KnowledgeFS product services."""
from __future__ import annotations
from threading import Lock
from typing import NamedTuple
from sqlalchemy.orm import Session, sessionmaker
from configs import dify_config
from repositories.sqlalchemy_knowledge_fs_capability_issuance_auditor import (
SQLAlchemyKnowledgeFSCapabilityIssuanceAuditor,
)
from services.knowledge_fs.app_admission_service import KnowledgeFSAppAdmissionService
from services.knowledge_fs.app_binding_management import (
KnowledgeFSAppBindingManagementService,
SQLKnowledgeFSAppCatalog,
)
from services.knowledge_fs.app_execution_capability import KnowledgeFSAppExecutionCapabilityService
from services.knowledge_fs.batch_capability import KnowledgeFSBatchCapabilityBroker
from services.knowledge_fs.capability_broker import KnowledgeFSCapabilityBroker
from services.knowledge_fs.control_plane_service import (
KnowledgeFSControlPlaneService,
SQLKnowledgeFSWorkspaceMemberPort,
)
from services.knowledge_fs.control_space_commands import KnowledgeFSControlSpaceCommandService
from services.knowledge_fs.credential_service import KnowledgeFSCredentialService
from services.knowledge_fs.cutover import KnowledgeFSWorkspaceCutoverService
from services.knowledge_fs.cutover_runtime_gate import SQLKnowledgeFSWorkspaceRuntimeGate
from services.knowledge_fs.data_facade import KnowledgeFSDataFacade
from services.knowledge_fs.greenfield_initializer import KnowledgeFSWorkspaceGreenfieldInitializer
from services.knowledge_fs.product_application_service import KnowledgeFSProductApplicationService
from services.knowledge_fs.product_authorization import DifyKnowledgeFSProductRBACPort
from services.knowledge_fs.product_remote import KnowledgeFSOperationUnavailableError
from services.knowledge_fs.product_remote_http import HTTPKnowledgeFSProductRemoteClient
from services.knowledge_fs.product_service import KnowledgeFSProductService
from services.knowledge_fs.remote_registry import get_knowledge_fs_lifecycle_remote
from services.knowledge_fs.revocation_commands import KnowledgeFSRevocationCommandProducer
from services.knowledge_fs.space_tag_service import KnowledgeFSSpaceTagService
from services.knowledge_fs_capability import create_configured_knowledge_fs_capability_issuer
class KnowledgeFSRuntime(NamedTuple):
application: KnowledgeFSProductApplicationService
app_admission: KnowledgeFSAppAdmissionService
app_bindings: KnowledgeFSAppBindingManagementService
app_capabilities: KnowledgeFSAppExecutionCapabilityService
broker: KnowledgeFSCapabilityBroker
control_plane: KnowledgeFSControlPlaneService
credentials: KnowledgeFSCredentialService
facade: KnowledgeFSDataFacade
space_tags: KnowledgeFSSpaceTagService
_runtime_cache_lock = Lock()
_runtime_cache: tuple[sessionmaker[Session], KnowledgeFSRuntime] | None = None
def get_knowledge_fs_runtime(session_maker: sessionmaker[Session]) -> KnowledgeFSRuntime:
"""Reuse the process runtime so request handling never reparses the signing key."""
global _runtime_cache
cached = _runtime_cache
if cached is not None and cached[0] is session_maker:
return cached[1]
with _runtime_cache_lock:
cached = _runtime_cache
if cached is not None and cached[0] is session_maker:
return cached[1]
runtime = create_knowledge_fs_runtime(session_maker)
_runtime_cache = (session_maker, runtime)
return runtime
def create_knowledge_fs_runtime(session_maker: sessionmaker[Session]) -> KnowledgeFSRuntime:
base_url = dify_config.KNOWLEDGE_FS_BASE_URL
if base_url is None:
raise KnowledgeFSOperationUnavailableError("KnowledgeFS integration is not configured")
rbac = DifyKnowledgeFSProductRBACPort()
remote = HTTPKnowledgeFSProductRemoteClient(
base_url=base_url,
timeout_seconds=dify_config.KNOWLEDGE_FS_TIMEOUT_SECONDS,
max_response_bytes=dify_config.KNOWLEDGE_FS_PRODUCT_MAX_RESPONSE_BYTES,
)
issuer = create_configured_knowledge_fs_capability_issuer(
audit=SQLAlchemyKnowledgeFSCapabilityIssuanceAuditor(session_maker)
)
greenfield_cutover = KnowledgeFSWorkspaceCutoverService(
session_maker,
remote_factory=get_knowledge_fs_lifecycle_remote,
)
greenfield_initializer = KnowledgeFSWorkspaceGreenfieldInitializer(
session_maker,
cutover=greenfield_cutover,
)
cutover_gate = SQLKnowledgeFSWorkspaceRuntimeGate(
session_maker,
initializer=greenfield_initializer,
)
batch_capabilities = KnowledgeFSBatchCapabilityBroker(
session_maker,
cutover_gate=cutover_gate,
issuer=issuer,
)
product = KnowledgeFSProductService(
session_maker,
batch_capabilities=batch_capabilities,
cutover_gate=cutover_gate,
remote=remote,
rbac=rbac,
)
revocations = KnowledgeFSRevocationCommandProducer()
control_plane = KnowledgeFSControlPlaneService(
session_maker,
product=product,
members=SQLKnowledgeFSWorkspaceMemberPort(),
revocations=revocations,
)
broker = KnowledgeFSCapabilityBroker(
session_maker,
cutover_gate=cutover_gate,
product=product,
issuer=issuer,
)
facade = KnowledgeFSDataFacade(broker=broker, remote=remote)
credentials = KnowledgeFSCredentialService(session_maker, product=product, revocations=revocations)
application = KnowledgeFSProductApplicationService(
product=product,
control_plane=control_plane,
commands=KnowledgeFSControlSpaceCommandService(session_maker),
facade=facade,
rbac=rbac,
)
app_admission = KnowledgeFSAppAdmissionService(session_maker, revocations=revocations)
return KnowledgeFSRuntime(
application=application,
app_admission=app_admission,
app_bindings=KnowledgeFSAppBindingManagementService(
session_maker,
product=product,
apps=SQLKnowledgeFSAppCatalog(),
revocations=revocations,
),
app_capabilities=KnowledgeFSAppExecutionCapabilityService(
admission=app_admission,
broker=broker,
remote=remote,
),
broker=broker,
control_plane=control_plane,
credentials=credentials,
facade=facade,
space_tags=KnowledgeFSSpaceTagService(session_maker, product=product),
)
__all__ = ["KnowledgeFSRuntime", "create_knowledge_fs_runtime", "get_knowledge_fs_runtime"]