# Geutebruck Cross-Switching API - Architecture **Version**: 1.0.0 (MVP) **Last Updated**: 2025-12-08 **Status**: In Development --- ## Overview The Geutebruck Cross-Switching API provides a modern REST API for controlling video routing between cameras (video inputs) and monitors/viewers (video outputs) in Geutebruck surveillance systems. The system acts as a bridge between the native GeViScope/GeViSoft SDK and modern web/mobile applications. **Core Functionality**: - πŸ” User authentication with JWT tokens - πŸ“Ή Camera discovery and management - πŸ–₯️ Monitor/viewer discovery and status - πŸ”€ Cross-switching operations (route camera to monitor) - πŸ“Š Routing state tracking and audit logging --- ## System Architecture ### High-Level Architecture ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Client Apps β”‚ (Postman, curl, custom apps) β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ HTTP/REST β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ FastAPI Server β”‚ (Python 3.11) β”‚ Port: 8000 β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ β”‚ β–Ό β–Ό β–Ό β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ PostgreSQLβ”‚ β”‚ Redis β”‚ β”‚SDK Bridgeβ”‚ β”‚Auth/JWT β”‚ β”‚ Port:5432β”‚ β”‚Port:6379β”‚ β”‚Port:50051β”‚ β”‚ Service β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ gRPC β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ GeViScope β”‚ β”‚ SDK (.NET) β”‚ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ TCP/IP β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ GeViServer β”‚ β”‚ Port: 7700+ β”‚ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β” β–Ό β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Cameras β”‚ β”‚ GSCView β”‚ β”‚ (Inputs) β”‚ β”‚ Viewers β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` --- ## Component Details ### 1. FastAPI Server (Python) **Purpose**: REST API layer handling HTTP requests, authentication, and business logic **Technology Stack**: - Python 3.11+ - FastAPI (web framework) - SQLAlchemy (ORM) - Pydantic (validation) - PyJWT (authentication) **Key Responsibilities**: - Accept HTTP REST requests from clients - Authenticate users and generate JWT tokens - Validate request data - Communicate with SDK Bridge via gRPC - Store routing state in PostgreSQL - Cache camera/monitor lists in Redis - Audit log all operations - Return HTTP responses to clients **Port**: 8000 --- ### 2. SDK Bridge (C# .NET 8.0) **Purpose**: gRPC service that wraps the GeViScope SDK, translating between modern gRPC and legacy SDK **Technology Stack**: - C# .NET 8.0 - Grpc.AspNetCore - GeViScope SDK (.NET Framework 4.8 DLL) - Serilog (logging) **Key Responsibilities**: - Connect to GeViServer using GeViScope SDK - Enumerate cameras (GetFirstVideoInput / GetNextVideoInput) - Enumerate monitors (GetFirstVideoOutput / GetNextVideoOutput) - Execute cross-switching (CrossSwitch action) - Clear monitors (ClearVideoOutput action) - Translate SDK errors to gRPC status codes - Maintain connection health with retry logic **Why Separate Service?**: - βœ… Isolates SDK crashes from Python API - βœ… Enables independent scaling - βœ… Clear separation of concerns (SDK complexity vs API logic) - βœ… Type-safe gRPC communication - βœ… Can run on different machines if needed **Port**: 50051 (gRPC) --- ### 3. PostgreSQL Database **Purpose**: Persistent storage for users, routing state, and audit logs **Schema**: ```sql users: - id (UUID, primary key) - username (unique) - password_hash (bcrypt) - role (viewer, operator, administrator) - created_at, updated_at crossswitch_routes: - id (UUID, primary key) - camera_id (int) - monitor_id (int) - switched_at (timestamp) - switched_by_user_id (UUID, FK to users) audit_logs: - id (UUID, primary key) - user_id (UUID, FK to users) - action (string) - target (string) - timestamp (timestamp) - details (JSON) ``` **Port**: 5432 --- ### 4. Redis **Purpose**: Session storage, caching, and future pub/sub for events **Usage**: - **Session Storage**: JWT tokens and user sessions - **Caching**: Camera list (60s TTL), monitor list (60s TTL) - **Future**: Pub/sub for real-time routing updates **Port**: 6379 --- ### 5. GeViScope SDK & GeViServer **GeViServer**: - Backend service managing surveillance system - Handles actual video routing - Controls GSCView viewers - Manages camera inputs and outputs **GeViScope SDK**: - .NET Framework 4.8 DLL (GeViProcAPINET_4_0.dll) - Provides C# wrapper for GeViServer communication - Uses action-based message passing - State query pattern for enumeration **Ports**: 7700, 7701, 7703 --- ## Data Flow ### 1. Authentication Flow ``` Client β†’ POST /api/v1/auth/login { username: "admin", password: "secret" } ↓ FastAPI validates credentials ↓ Hash password with bcrypt ↓ Query PostgreSQL for user ↓ Generate JWT token (1hr expiry) ↓ Store session in Redis ↓ Client ← { access_token: "eyJ...", token_type: "bearer" } ``` ### 2. Camera Discovery Flow ``` Client β†’ GET /api/v1/cameras Header: Authorization: Bearer eyJ... ↓ FastAPI validates JWT ↓ Check Redis cache for camera list ↓ (cache miss) gRPC call to SDK Bridge: ListCameras() ↓ SDK Bridge β†’ GeViScope SDK β†’ CSQGetFirstVideoInput() β†’ CSQGetNextVideoInput() (loop) ↓ SDK Bridge ← Camera list ↓ FastAPI ← gRPC response ↓ Store in Redis (60s TTL) ↓ Client ← { cameras: [ { id: 1, name: "Camera 1", has_ptz: false }, { id: 2, name: "Front Gate", has_ptz: true } ]} ``` ### 3. Cross-Switching Flow ``` Client β†’ POST /api/v1/crossswitch { camera_id: 7, monitor_id: 3, mode: 0 } ↓ FastAPI validates JWT (requires operator role) ↓ Validate camera_id and monitor_id exist ↓ gRPC call to SDK Bridge: ExecuteCrossSwitch(7, 3, 0) ↓ SDK Bridge β†’ GeViScope SDK β†’ SendMessage("CrossSwitch(7, 3, 0)") ↓ GeViServer executes cross-switch ↓ SDK Bridge ← Success confirmation ↓ FastAPI stores route in PostgreSQL ↓ FastAPI logs to audit_logs table ↓ Client ← { success: true, message: "Camera 7 routed to monitor 3" } ``` --- ## Security Architecture ### Authentication & Authorization **Authentication**: JWT (JSON Web Tokens) - Access tokens: 1 hour lifetime - Refresh tokens: 7 days lifetime (future) - Tokens stored in Redis for quick invalidation - Bcrypt password hashing (cost factor: 12) **Authorization**: Role-Based Access Control (RBAC) | Role | Permissions | |------|------------| | **Viewer** | Read cameras, Read monitors, Read routing state | | **Operator** | Viewer + Execute cross-switch, Clear monitors | | **Administrator** | Operator + User management, Configuration | ### API Security - βœ… HTTPS enforced in production (TLS 1.2+) - βœ… CORS configured for allowed origins - βœ… Rate limiting (60 requests/minute per IP) - βœ… JWT secret key from environment (not hardcoded) - βœ… Database credentials in environment variables - βœ… No stack traces exposed to clients - βœ… Audit logging for all operations --- ## Scalability Considerations ### Current Architecture (MVP) - Single FastAPI instance - Single SDK Bridge instance - Single GeViServer connection ### Future Horizontal Scaling **FastAPI Layer**: - βœ… Stateless design enables multiple instances - βœ… Load balancer in front (nginx/HAProxy) - βœ… Shared PostgreSQL and Redis **SDK Bridge Layer**: - ⚠️ Limited by GeViServer connection capacity - Consider: Connection pooling pattern - Consider: Multiple SDK Bridge instances if needed **Database Layer**: - PostgreSQL read replicas for camera/monitor queries - Redis Cluster for high availability --- ## Error Handling ### SDK Bridge Error Translation | SDK Error | gRPC Status | HTTP Status | |-----------|-------------|-------------| | Connection Failed | UNAVAILABLE | 503 Service Unavailable | | Invalid Channel | INVALID_ARGUMENT | 400 Bad Request | | Permission Denied | PERMISSION_DENIED | 403 Forbidden | | Timeout | DEADLINE_EXCEEDED | 504 Gateway Timeout | | Unknown | INTERNAL | 500 Internal Server Error | ### Retry Logic - SDK Bridge connection: 3 attempts with exponential backoff - gRPC calls from FastAPI: 2 attempts with 1s delay - Transient errors logged but not exposed to client --- ## Monitoring & Observability ### Logging **FastAPI**: - Structured JSON logs (Structlog) - Log levels: DEBUG, INFO, WARNING, ERROR - Correlation IDs for request tracing **SDK Bridge**: - Serilog with file and console sinks - Separate logs for SDK communication ### Metrics (Future) **Prometheus Endpoint**: `/metrics` - Request count by endpoint - Request latency (p50, p95, p99) - Active cross-switch operations - gRPC call success/failure rates - Cache hit/miss rates ### Health Checks **Endpoint**: `GET /api/v1/health` Returns: ```json { "status": "healthy", "components": { "database": "up", "redis": "up", "sdk_bridge": "up" }, "timestamp": "2025-12-08T15:30:00Z" } ``` --- ## Deployment Architecture ### Development Environment ``` Localhost: - PostgreSQL (Docker or native) - Redis (Docker or native) - SDK Bridge (.NET) - FastAPI (uvicorn --reload) - GeViServer (C:\GEVISOFT\GeViServer.exe) ``` ### Production Environment (Windows Server) ``` Windows Server 2016+: - GeViServer (native Windows service) - SDK Bridge (Windows service via NSSM) - PostgreSQL (Docker or native) - Redis (Docker or native) - FastAPI (Docker or uvicorn behind nginx) - Nginx (reverse proxy with SSL termination) ``` ### Network Requirements - Port 8000: FastAPI (HTTPS in production) - Port 50051: SDK Bridge gRPC (internal only) - Port 5432: PostgreSQL (internal only) - Port 6379: Redis (internal only) - Port 7700-7703: GeViServer (internal only) --- ## Technology Choices Rationale ### Why Python FastAPI? - βœ… Modern async Python framework - βœ… Automatic OpenAPI documentation - βœ… Fast development cycle - βœ… Rich ecosystem (SQLAlchemy, Pydantic) - βœ… Easy to expand with new features ### Why C# SDK Bridge? - βœ… GeViScope SDK is .NET Framework 4.8 - βœ… gRPC provides type-safe communication - βœ… Isolates SDK complexity - βœ… Can run on separate machine if needed ### Why PostgreSQL? - βœ… Mature, reliable, ACID compliant - βœ… JSON support for flexible audit logs - βœ… Good performance for relational data ### Why Redis? - βœ… Fast in-memory caching - βœ… Session storage - βœ… Future: pub/sub for events ### Why gRPC (not REST for SDK Bridge)? - βœ… Type-safe protocol buffers - βœ… Efficient binary protocol - βœ… Streaming support (future) - βœ… Language-agnostic --- ## Future Enhancements (Phase 2) 1. **GeViSet Configuration Management** - Retrieve action mappings from GeViServer - Modify configurations via API - Export/import to CSV - Push configurations back to server 2. **Real-Time Event Stream** - WebSocket endpoint for routing changes - Redis pub/sub for event distribution - Monitor status change notifications 3. **PTZ Camera Control** - Pan/tilt/zoom commands - Preset positions - Tour sequences 4. **Multi-Tenancy** - Organization/tenant isolation - Per-tenant GeViServer connections 5. **Advanced Analytics** - Routing history reports - Usage patterns - Performance metrics --- ## Development Workflow 1. **Setup**: `.\scripts\setup_dev_environment.ps1` 2. **Start Services**: `.\scripts\start_services.ps1` 3. **Database Migrations**: `alembic upgrade head` 4. **Run Tests**: `pytest tests/ -v` 5. **Code Quality**: `ruff check src/api` + `black src/api` 6. **API Docs**: http://localhost:8000/docs --- ## References - **FastAPI Documentation**: https://fastapi.tiangolo.com - **gRPC .NET**: https://grpc.io/docs/languages/csharp/ - **GeViScope SDK**: See `docs/SDK_INTEGRATION_LESSONS.md` - **SQLAlchemy**: https://docs.sqlalchemy.org - **Pydantic**: https://docs.pydantic.dev --- **Document Version**: 1.0 **Architecture Status**: βœ… Defined, πŸ”„ In Development **Last Review**: 2025-12-08