Commit 76dfe55e authored by Sergio Gimenez's avatar Sergio Gimenez
Browse files

feat(fm): terminate a federation on DeleteFederationDetails

parent bda4d121
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
from uuid import UUID

from sqlalchemy import Select, insert, select
from sqlalchemy import Select, insert, select, update
from sqlalchemy.ext.asyncio import AsyncSession

from federation_manager.adapters.database.tables import federation_contexts as contexts
@@ -61,6 +61,12 @@ class PostgresFederationContextRepo:
        )
        await self._session.commit()

    async def set_status(self, context_id: UUID, status: str) -> None:
        await self._session.execute(
            update(contexts).where(contexts.c.id == context_id).values(status=status)
        )
        await self._session.commit()

    async def _one(self, stmt: Select[tuple[object, ...]]) -> FederationContext | None:
        row = (await self._session.execute(stmt)).one_or_none()
        if row is None:
+17 −1
Original line number Diff line number Diff line
@@ -48,7 +48,7 @@ async def get_federation_health(
) -> FederationHealthResponse:
    partner = await auth.authenticate(token)
    context = await contexts.find_inbound(partner.id, federationContextId)
    if context is None:
    if context is None or context.is_terminated():
        raise FederationContextUnknown(partner.id)
    return FederationHealthResponse(
        federation_health_status=FederationHealthInfo(
@@ -72,3 +72,19 @@ async def create_federation(
    context, accepted = await service.create(partner, body)
    response.headers["Location"] = f"{EWBI_BASE_PATH}/{context.federation_context_id}/partner"
    return accepted


@router.delete(
    "/{federationContextId}/partner",
    operation_id="DeleteFederationDetails",
    status_code=200,
    responses=EWBI_ERROR_RESPONSES,
)
async def delete_federation_details(
    federationContextId: FederationContextIdPath,  # noqa: N803 - GSMA path template name
    auth: Annotated[PartnerAuthenticator, Depends(get_partner_authenticator)],
    service: Annotated[InboundFederationService, Depends(get_inbound_federation_service)],
    token: Annotated[str, Depends(get_bearer_token)],
) -> None:
    partner = await auth.authenticate(token)
    await service.terminate(partner, federationContextId)
+8 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@ from federation_manager.contracts.ewbi import (
)
from federation_manager.domain.errors import (
    FederationAlreadyExists,
    FederationContextUnknown,
    FederationError,
    FederationEstablishmentFailed,
    PartnerNotActive,
@@ -28,6 +29,7 @@ from federation_manager.domain.ports import (
OUTBOUND = "outbound"
INBOUND = "inbound"
AVAILABLE = "available"
TERMINATED = "terminated"


def _utcnow() -> datetime:
@@ -152,3 +154,9 @@ class InboundFederationService:
            platform_caps=list(self._local.platform_caps),
            partner_op_federation_id=self._local.federation_id,
        )

    async def terminate(self, partner: PartnerOP, federation_context_id: str) -> None:
        context = await self._contexts.find_inbound(partner.id, federation_context_id)
        if context is None or context.is_terminated():
            raise FederationContextUnknown(partner.id)
        await self._contexts.set_status(context.id, TERMINATED)
+3 −0
Original line number Diff line number Diff line
@@ -90,6 +90,9 @@ class FederationContext:
    def is_active(self) -> bool:
        return self.status == "available"

    def is_terminated(self) -> bool:
        return self.status == "terminated"


@dataclass
class FederationTransaction:
+2 −0
Original line number Diff line number Diff line
@@ -50,6 +50,8 @@ class FederationContextRepositoryPort(Protocol):

    async def add(self, context: FederationContext) -> None: ...

    async def set_status(self, context_id: UUID, status: str) -> None: ...


class RoutingRuleRepositoryPort(Protocol):
    async def list_active(self, identifier_type: str) -> list[RoutingRule]: ...
Loading