Commit e667920c authored by George Papathanail's avatar George Papathanail
Browse files

feat: add CAMARA request/response schemas

parent ac5e755f
Loading
Loading
Loading
Loading
+74 −0
Original line number Diff line number Diff line
from datetime import datetime
from enum import StrEnum
from typing import Any, Literal, Optional
from uuid import UUID

from pydantic import BaseModel, Field


class TrafficInfluenceState(StrEnum):
    ORDERED = "ordered"
    CREATED = "created"
    ACTIVE = "active"
    ERROR = "error"
    DELETION_IN_PROGRESS = "deletion in progress"
    DELETED = "deleted"


class SubscriptionProtocol(StrEnum):
    HTTP = "HTTP"
    MQTT3 = "MQTT3"
    MQTT5 = "MQTT5"
    AMQP = "AMQP"
    NATS = "NATS"
    KAFKA = "KAFKA"


SubscriptionEventType = Literal["org.camaraproject.traffic-influence.v1.traffic-influence-change"]


class Config(BaseModel):
    subscriptionDetail: dict[str, Any]
    subscriptionExpireTime: Optional[datetime] = None
    subscriptionMaxEvents: Optional[int] = Field(default=None, ge=1)
    initialEvent: Optional[bool] = None


class SubscriptionRequest(BaseModel):
    protocol: SubscriptionProtocol
    sink: str = Field(pattern=r"^https:\/\/.+$")
    # sinkCredential is a discriminated union (PLAIN/ACCESSTOKEN/REFRESHTOKEN) in the
    # CAMARA spec; kept generic here since OEG only persists a sink_credential_ref
    # (never the raw credential) and doesn't branch on credential type.
    sinkCredential: Optional[dict[str, Any]] = None
    types: list[SubscriptionEventType] = Field(min_length=1, max_length=1)
    config: Config


class SourceTrafficFilters(BaseModel):
    sourcePort: Optional[int] = Field(default=None, ge=0, le=65535)


class DestinationTrafficFilters(BaseModel):
    destinationPort: Optional[int] = Field(default=None, ge=0, le=65535)
    destinationProtocol: Optional[str] = None


class BaseTrafficInfluence(BaseModel):
    apiConsumerId: str
    appId: UUID
    appInstanceId: Optional[UUID] = None
    edgeCloudRegion: Optional[str] = None
    edgeCloudZoneId: Optional[UUID] = None
    sourceTrafficFilters: Optional[SourceTrafficFilters] = None
    destinationTrafficFilters: Optional[DestinationTrafficFilters] = None
    subscriptionRequest: Optional[SubscriptionRequest] = None


class PostTrafficInfluence(BaseTrafficInfluence):
    pass


class TrafficInfluence(BaseTrafficInfluence):
    trafficInfluenceID: UUID
    state: TrafficInfluenceState