Loading src/srm/adapters/federation_manager/fm_client.py +1 −1 Original line number Diff line number Diff line Loading @@ -113,7 +113,7 @@ class FederationManager(FederationManagerPort): res = await self._request("GET", _LIST_ZONES_ENDPOINT) zones = [] for obj in res: zones.append(Zone.model_validate_json(obj)) zones.append(Zone.model_validate(obj)) return zones async def list_full_service_instances(self) -> list[ServiceInstance]: Loading src/srm/api/dependencies.py +8 −2 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ from srm.adapters.database.repos.catalog import ( SqlServiceSpecificationRepository, ) from srm.adapters.database.repos.topology import SqlZoneRepository from srm.adapters.federation_manager.fm_client import FederationManager from srm.app_state import AppState from srm.application.services.capability_placement import CapabilityPlacementPlanner from srm.application.services.device_targeted_control_path import ( Loading Loading @@ -37,7 +38,12 @@ async def get_session(request: Request) -> AsyncGenerator[AsyncSession, None]: raise def get_fm_client(request: Request) -> FederationManager: return get_app_state(request=request).fm_client SessionDep = Annotated[AsyncSession, Depends(get_session)] FMClientDep = Annotated[FederationManager, Depends(get_fm_client)] def get_create_service_specification_use_case( Loading @@ -58,8 +64,8 @@ def get_delete_service_specification_use_case( return DeleteServiceSpecificationUseCase(SqlServiceSpecificationRepository(session)) def get_list_zones_use_case(session: SessionDep) -> ListZonesUseCase: return ListZonesUseCase(SqlZoneRepository(session)) def get_list_zones_use_case(session: SessionDep, fm_client: FMClientDep) -> ListZonesUseCase: return ListZonesUseCase(SqlZoneRepository(session), fm_client) def get_zone_provider_name() -> str: Loading src/srm/app_state.py +4 −0 Original line number Diff line number Diff line Loading @@ -3,6 +3,8 @@ from typing import Protocol from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession, async_sessionmaker from srm.adapters.databus.nats_connection_manager import NatsConnectionManager from srm.adapters.databus.nats_publisher import NatsPublisher from srm.adapters.federation_manager.fm_client import FederationManager from srm.adapters.transformation_functions.registry import ConfiguredControlPathRegistry from srm.api.databus.nats_subscriber import NatsSubscriber Loading @@ -13,3 +15,5 @@ class AppState(Protocol): databus_connection_manager: NatsConnectionManager databus_subscribers: list[NatsSubscriber] control_path_registry: ConfiguredControlPathRegistry publisher: NatsPublisher fm_client: FederationManager src/srm/application/use_cases/topology.py +28 −2 Original line number Diff line number Diff line from dataclasses import dataclass from srm.adapters.federation_manager.fm_client import FederationManager from srm.domain.models.topology import Zone, ZoneState from srm.domain.ports.database.topology import ZoneRepository Loading @@ -11,11 +12,36 @@ class ListZonesCommand: class ListZonesUseCase: def __init__(self, zones: ZoneRepository) -> None: def __init__(self, zones: ZoneRepository, fm_client: FederationManager) -> None: self._zones = zones self._fm_client = fm_client async def execute(self, command: ListZonesCommand) -> list[Zone]: return await self._zones.list_resource_zones( local_zones = await self._zones.list_resource_zones( state=command.state, region=command.region, ) federated_zones = await self._fm_client.list_zones() if len(federated_zones) > 0: filtered_fm_zones = filter( lambda zone: self.filter_zones(zone, command), federated_zones ) return local_zones + list(filtered_fm_zones) def filter_zones(self, zone: Zone, command: ListZonesCommand) -> bool: if command.region is None and command.state is None: return True if command.region is not None and command.state is not None: return ( zone.state == command.state and "location" in zone.metadata and str(zone.metadata["location"]["region"]) == command.region ) if command.region is not None: return ( "location" in zone.metadata and str(zone.metadata["location"]["region"]) == command.region ) else: return zone.state == command.state src/srm/domain/models/topology/enums.py +1 −1 Original line number Diff line number Diff line Loading @@ -11,7 +11,7 @@ class ZoneKind(StrEnum): class ZoneState(StrEnum): ACTIVE = "active" OFFLINE = "offline" INACTIVE = "inactive" UNKNOWN = "unknown" Loading Loading
src/srm/adapters/federation_manager/fm_client.py +1 −1 Original line number Diff line number Diff line Loading @@ -113,7 +113,7 @@ class FederationManager(FederationManagerPort): res = await self._request("GET", _LIST_ZONES_ENDPOINT) zones = [] for obj in res: zones.append(Zone.model_validate_json(obj)) zones.append(Zone.model_validate(obj)) return zones async def list_full_service_instances(self) -> list[ServiceInstance]: Loading
src/srm/api/dependencies.py +8 −2 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ from srm.adapters.database.repos.catalog import ( SqlServiceSpecificationRepository, ) from srm.adapters.database.repos.topology import SqlZoneRepository from srm.adapters.federation_manager.fm_client import FederationManager from srm.app_state import AppState from srm.application.services.capability_placement import CapabilityPlacementPlanner from srm.application.services.device_targeted_control_path import ( Loading Loading @@ -37,7 +38,12 @@ async def get_session(request: Request) -> AsyncGenerator[AsyncSession, None]: raise def get_fm_client(request: Request) -> FederationManager: return get_app_state(request=request).fm_client SessionDep = Annotated[AsyncSession, Depends(get_session)] FMClientDep = Annotated[FederationManager, Depends(get_fm_client)] def get_create_service_specification_use_case( Loading @@ -58,8 +64,8 @@ def get_delete_service_specification_use_case( return DeleteServiceSpecificationUseCase(SqlServiceSpecificationRepository(session)) def get_list_zones_use_case(session: SessionDep) -> ListZonesUseCase: return ListZonesUseCase(SqlZoneRepository(session)) def get_list_zones_use_case(session: SessionDep, fm_client: FMClientDep) -> ListZonesUseCase: return ListZonesUseCase(SqlZoneRepository(session), fm_client) def get_zone_provider_name() -> str: Loading
src/srm/app_state.py +4 −0 Original line number Diff line number Diff line Loading @@ -3,6 +3,8 @@ from typing import Protocol from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession, async_sessionmaker from srm.adapters.databus.nats_connection_manager import NatsConnectionManager from srm.adapters.databus.nats_publisher import NatsPublisher from srm.adapters.federation_manager.fm_client import FederationManager from srm.adapters.transformation_functions.registry import ConfiguredControlPathRegistry from srm.api.databus.nats_subscriber import NatsSubscriber Loading @@ -13,3 +15,5 @@ class AppState(Protocol): databus_connection_manager: NatsConnectionManager databus_subscribers: list[NatsSubscriber] control_path_registry: ConfiguredControlPathRegistry publisher: NatsPublisher fm_client: FederationManager
src/srm/application/use_cases/topology.py +28 −2 Original line number Diff line number Diff line from dataclasses import dataclass from srm.adapters.federation_manager.fm_client import FederationManager from srm.domain.models.topology import Zone, ZoneState from srm.domain.ports.database.topology import ZoneRepository Loading @@ -11,11 +12,36 @@ class ListZonesCommand: class ListZonesUseCase: def __init__(self, zones: ZoneRepository) -> None: def __init__(self, zones: ZoneRepository, fm_client: FederationManager) -> None: self._zones = zones self._fm_client = fm_client async def execute(self, command: ListZonesCommand) -> list[Zone]: return await self._zones.list_resource_zones( local_zones = await self._zones.list_resource_zones( state=command.state, region=command.region, ) federated_zones = await self._fm_client.list_zones() if len(federated_zones) > 0: filtered_fm_zones = filter( lambda zone: self.filter_zones(zone, command), federated_zones ) return local_zones + list(filtered_fm_zones) def filter_zones(self, zone: Zone, command: ListZonesCommand) -> bool: if command.region is None and command.state is None: return True if command.region is not None and command.state is not None: return ( zone.state == command.state and "location" in zone.metadata and str(zone.metadata["location"]["region"]) == command.region ) if command.region is not None: return ( "location" in zone.metadata and str(zone.metadata["location"]["region"]) == command.region ) else: return zone.state == command.state
src/srm/domain/models/topology/enums.py +1 −1 Original line number Diff line number Diff line Loading @@ -11,7 +11,7 @@ class ZoneKind(StrEnum): class ZoneState(StrEnum): ACTIVE = "active" OFFLINE = "offline" INACTIVE = "inactive" UNKNOWN = "unknown" Loading