gateway/modules/serviceCenter/__init__.py
ValueOn AG c8b7517209 refactor: modules/services/ abgeloest durch serviceCenter + serviceHub
serviceCenter = DI-Container (Resolver, Registry, Context) fuer Service-Instanziierung
serviceHub = Consumer-facing Aggregation (DB-Interfaces, Runtime-State, lazy Service-Resolution via serviceCenter)

- modules/serviceHub/ erstellt: ServiceHub, PublicService, getInterface()
- 22 Consumer-Dateien migriert (routes, features, tests): imports von modules.services auf serviceHub bzw. serviceCenter umgestellt
- resolver.py: legacy fallback auf altes services/ entfernt
- modules/services/ komplett geloescht (83 Dateien inkl. dead code mainAiChat.py)
- pre-extraction: progress callback durch chunk-pipeline propagiert, operationType DATA_EXTRACT->DATA_ANALYSE fuer guenstigeres Modell
2026-03-14 11:51:45 +01:00

134 lines
3.8 KiB
Python

# Copyright (c) 2025 Patrick Motsch
# All rights reserved.
"""
Service Center.
Central registry for core and importable services with per-feature resolution.
"""
import logging
from typing import Any, List, Optional
from modules.serviceCenter.context import ServiceCenterContext
from modules.serviceCenter.registry import (
CORE_SERVICES,
IMPORTABLE_SERVICES,
SERVICE_RBAC_OBJECTS,
)
from modules.serviceCenter.resolver import (
resolve,
get_resolution_cache,
clear_cache,
)
logger = logging.getLogger(__name__)
def getService(
key: str,
context: ServiceCenterContext,
) -> Any:
"""
Get a service instance by key for the given context.
Args:
key: Service key (e.g., "web", "extraction", "utils")
context: ServiceCenterContext with user, mandate_id, feature_instance_id, workflow
Returns:
Service instance
"""
cache = get_resolution_cache()
resolving = set()
return resolve(key, context, cache, resolving)
def preWarm(service_keys: Optional[List[str]] = None) -> None:
"""
Pre-load service modules at startup to avoid first-request latency.
Args:
service_keys: Optional list of keys to preload. If None, preloads all registered services.
"""
import importlib
keys = service_keys or list(CORE_SERVICES.keys()) + list(IMPORTABLE_SERVICES.keys())
for key in keys:
spec = CORE_SERVICES.get(key) or IMPORTABLE_SERVICES.get(key)
if not spec:
continue
try:
importlib.import_module(spec["module"])
logger.debug(f"Pre-warmed service module: {key}")
except (ImportError, ModuleNotFoundError) as e:
logger.debug(f"Could not pre-warm {key}: {e}")
def registerServiceObjects(catalogService) -> bool:
"""Register service RBAC objects in the catalog. Call at startup."""
try:
for obj in SERVICE_RBAC_OBJECTS:
catalogService.registerResourceObject(
featureCode="system",
objectKey=obj["objectKey"],
label=obj["label"],
meta=obj.get("meta"),
)
logger.info(f"Registered {len(SERVICE_RBAC_OBJECTS)} service RBAC objects")
return True
except Exception as e:
logger.error(f"Failed to register service RBAC objects: {e}")
return False
def can_access_service(
user,
rbac,
service_key: str,
mandate_id: Optional[str] = None,
feature_instance_id: Optional[str] = None,
allow_when_no_rbac: bool = True,
) -> bool:
"""
Check if user has permission to access the given service.
Args:
user: User object
rbac: RbacClass instance (e.g. from interfaceDbApp.rbac)
service_key: Service key (e.g., "web", "extraction")
mandate_id: Optional mandate context
feature_instance_id: Optional feature instance context
allow_when_no_rbac: If True, allow when rbac is None (migration/default)
Returns:
True if user has view permission on the service
"""
if not rbac:
return allow_when_no_rbac
if service_key not in IMPORTABLE_SERVICES:
return False
obj = IMPORTABLE_SERVICES[service_key]
object_key = obj.get("objectKey")
if not object_key:
return False
from modules.datamodels.datamodelRbac import AccessRuleContext
permissions = rbac.getUserPermissions(
user,
AccessRuleContext.RESOURCE,
object_key,
mandateId=mandate_id,
featureInstanceId=feature_instance_id,
)
return permissions.view if permissions else False
__all__ = [
"ServiceCenterContext",
"getService",
"preWarm",
"clear_cache",
"registerServiceObjects",
"can_access_service",
"SERVICE_RBAC_OBJECTS",
"CORE_SERVICES",
"IMPORTABLE_SERVICES",
]