Commit 378941c5 authored by George Papathanail's avatar George Papathanail
Browse files

Merge branch 'refactor/traffic' into 'develop'

feat(traffic-influence): add CAMARA -> SRM activate/deactivate mapper

See merge request !24
parents 4c85fb1e b016faf4
Loading
Loading
Loading
Loading
Loading
+218 −0

File added.

Preview size limit exceeded, changes collapsed.

+36 −0
Changes for src/open_exposure_gateway/adapters/database/mappers.py: 36 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@ from open_exposure_gateway.adapters.database.sql import (
    CallbackRegistrationRow,
    OperationRow,
    QodSessionRow,
    TrafficInfluenceRow,
)
from open_exposure_gateway.domain.models import (
    AppDeployment,
@@ -19,6 +20,7 @@ from open_exposure_gateway.domain.models import (
    CallbackRegistration,
    Operation,
    QodSession,
    TrafficInfluence,
)


@@ -174,6 +176,40 @@ class QodSessionMapper:
        )


class TrafficInfluenceMapper:
    @staticmethod
    def to_domain(row: TrafficInfluenceRow) -> TrafficInfluence:
        return TrafficInfluence(
            traffic_influence_id=row.traffic_influence_id,
            operation_id=row.operation_id,
            app_registration_id=row.app_registration_id,
            edge_cloud_zone_id=row.edge_cloud_zone_id,
            edge_cloud_region=row.edge_cloud_region,
            source_port=row.source_port,
            destination_port=row.destination_port,
            destination_protocol=row.destination_protocol,
            state=row.state,
            external_ref=row.external_ref,
            created_at=row.created_at,
            updated_at=row.updated_at,
        )

    @staticmethod
    def to_row(domain: TrafficInfluence) -> TrafficInfluenceRow:
        return TrafficInfluenceRow(
            traffic_influence_id=domain.traffic_influence_id,
            operation_id=domain.operation_id,
            app_registration_id=domain.app_registration_id,
            edge_cloud_zone_id=domain.edge_cloud_zone_id,
            edge_cloud_region=domain.edge_cloud_region,
            source_port=domain.source_port,
            destination_port=domain.destination_port,
            destination_protocol=domain.destination_protocol,
            state=domain.state,
            external_ref=domain.external_ref,
        )


class CallbackRegistrationMapper:
    @staticmethod
    def to_domain(row: CallbackRegistrationRow) -> CallbackRegistration:
+10 −0
Changes for src/open_exposure_gateway/adapters/database/repos/app_instances.py: 10 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -52,6 +52,16 @@ class SqlAppInstanceRepository(AppInstanceRepository):
        row = await self._session.scalar(stmt.limit(1))
        return row is not None

    async def list_ready_ids_in_zone(
        self, app_registration_id: UUID, edge_cloud_zone_id: UUID
    ) -> list[UUID]:
        stmt = select(AppInstanceRow.app_instance_id).where(
            AppInstanceRow.app_registration_id == app_registration_id,
            AppInstanceRow.edge_cloud_zone_id == edge_cloud_zone_id,
            AppInstanceRow.state == AppInstanceState.READY,
        )
        return list(await self._session.scalars(stmt))

    async def save(self, app_instance: AppInstance) -> AppInstance:
        merged = await self._session.merge(AppInstanceMapper.to_row(app_instance))
        await self._session.flush()
+46 −0
Changes for src/open_exposure_gateway/adapters/database/repos/traffic_influences.py: 46 added lines, 0 removed lines.
Original line number Diff line number Diff line
from uuid import UUID

from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from open_exposure_gateway.adapters.database.mappers import TrafficInfluenceMapper
from open_exposure_gateway.adapters.database.sql import TrafficInfluenceRow
from open_exposure_gateway.domain.models import TrafficInfluence
from open_exposure_gateway.domain.models.traffic_influences.enums import TrafficInfluenceState
from open_exposure_gateway.ports.database.traffic_influences import TrafficInfluenceRepository


class SqlTrafficInfluenceRepository(TrafficInfluenceRepository):
    def __init__(self, session: AsyncSession) -> None:
        self._session = session

    async def get_by_id(self, traffic_influence_id: UUID) -> TrafficInfluence | None:
        stmt = select(TrafficInfluenceRow).where(
            TrafficInfluenceRow.traffic_influence_id == traffic_influence_id
        )
        row = await self._session.scalar(stmt)
        return TrafficInfluenceMapper.to_domain(row) if row is not None else None

    async def get_by_operation_id(self, operation_id: UUID) -> TrafficInfluence | None:
        stmt = select(TrafficInfluenceRow).where(TrafficInfluenceRow.operation_id == operation_id)
        row = await self._session.scalar(stmt)
        return TrafficInfluenceMapper.to_domain(row) if row is not None else None

    async def list_by_app_registration_id(
        self, app_registration_id: UUID | None
    ) -> list[TrafficInfluence]:
        stmt = select(TrafficInfluenceRow).where(
            TrafficInfluenceRow.state != TrafficInfluenceState.DELETED
        )
        if app_registration_id is not None:
            stmt = stmt.where(TrafficInfluenceRow.app_registration_id == app_registration_id)
        rows = await self._session.scalars(stmt)
        return [TrafficInfluenceMapper.to_domain(row) for row in rows]

    async def save(self, traffic_influence: TrafficInfluence) -> TrafficInfluence:
        merged = await self._session.merge(TrafficInfluenceMapper.to_row(traffic_influence))
        await self._session.flush()
        saved = await self.get_by_id(merged.traffic_influence_id)
        if saved is None:
            raise RuntimeError("Saved traffic influence could not be reloaded")
        return saved
+26 −0
Changes for src/open_exposure_gateway/adapters/database/sql.py: 26 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ from open_exposure_gateway.domain.models.registration.enums import (
    AppRegistrationStatus,
    PackageType,
)
from open_exposure_gateway.domain.models.traffic_influences.enums import TrafficInfluenceState


def get_metadata() -> MetaData:
@@ -243,3 +244,28 @@ class QodSessionRow(AuditedMixin, Base):
    external_ref: Mapped[str | None] = mapped_column(String(255))
    device_ports: Mapped[dict[str, object] | None] = mapped_column(JSONB)
    application_server_ports: Mapped[dict[str, object] | None] = mapped_column(JSONB)


class TrafficInfluenceRow(AuditedMixin, Base):
    __tablename__ = "traffic_influences"
    __table_args__ = (
        Index("idx_traffic_influences_operation", "operation_id"),
        Index("idx_traffic_influences_app_registration", "app_registration_id"),
    )

    traffic_influence_id: Mapped[UUID] = mapped_column(PG_UUID(as_uuid=True), primary_key=True)
    operation_id: Mapped[UUID] = mapped_column(
        ForeignKey("operations.operation_id"), nullable=False
    )
    app_registration_id: Mapped[UUID] = mapped_column(
        ForeignKey("app_registrations.app_registration_id"), nullable=False
    )
    edge_cloud_zone_id: Mapped[UUID | None] = mapped_column(PG_UUID(as_uuid=True))
    edge_cloud_region: Mapped[str | None] = mapped_column(String(256))
    source_port: Mapped[int | None] = mapped_column(Integer)
    destination_port: Mapped[int | None] = mapped_column(Integer)
    destination_protocol: Mapped[str | None] = mapped_column(String(32))
    state: Mapped[TrafficInfluenceState] = mapped_column(
        _enum_type(TrafficInfluenceState), nullable=False
    )
    external_ref: Mapped[str | None] = mapped_column(String(255))
Loading