Skip to content
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .github/workflows/backend-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,14 @@ jobs:
docker compose -f docker-compose.ci.yaml up -d --wait --wait-timeout 120
docker compose -f docker-compose.ci.yaml ps

- name: Create Kafka topics
env:
KAFKA_BOOTSTRAP_SERVERS: localhost:9092
KAFKA_TOPIC_PREFIX: "test."
run: |
cd backend
uv run python -m scripts.create_topics

- name: Run integration tests
timeout-minutes: 10
env:
Expand Down Expand Up @@ -174,6 +182,14 @@ jobs:
timeout 90 bash -c 'until sudo k3s kubectl cluster-info; do sleep 5; done'
kubectl create namespace integr8scode --dry-run=client -o yaml | kubectl apply -f -

- name: Create Kafka topics
env:
KAFKA_BOOTSTRAP_SERVERS: localhost:9092
KAFKA_TOPIC_PREFIX: "test."
run: |
cd backend
uv run python -m scripts.create_topics

- name: Run E2E tests
timeout-minutes: 10
env:
Expand Down
6 changes: 5 additions & 1 deletion backend/.env.test
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ REDIS_DECODE_RESPONSES=true

# Kafka - use localhost for tests
KAFKA_BOOTSTRAP_SERVERS=localhost:9092
KAFKA_TOPIC_PREFIX=test.
SCHEMA_REGISTRY_URL=http://localhost:8081

# Security
Expand All @@ -31,9 +32,12 @@ CORS_ALLOWED_ORIGINS=["http://localhost:3000","https://localhost:3000"]
# Features
RATE_LIMIT_ENABLED=true
ENABLE_TRACING=false
OTEL_SDK_DISABLED=true

# OpenTelemetry - explicitly disabled for tests (no endpoint = NoOp meter)
OTEL_EXPORTER_OTLP_ENDPOINT=
OTEL_METRICS_EXPORTER=none
OTEL_TRACES_EXPORTER=none
OTEL_LOGS_EXPORTER=none

# Development
DEVELOPMENT_MODE=false
Expand Down
137 changes: 129 additions & 8 deletions backend/app/core/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,53 +5,174 @@
AdminServicesProvider,
AuthProvider,
BusinessServicesProvider,
ConnectionProvider,
CoordinatorProvider,
CoreServicesProvider,
DatabaseProvider,
DLQProcessorProvider,
EventProvider,
EventReplayProvider,
K8sWorkerProvider,
KafkaServicesProvider,
KubernetesProvider,
LoggingProvider,
MessagingProvider,
MetricsProvider,
PodMonitorProvider,
RedisProvider,
ResultProcessorProvider,
RepositoryProvider,
SagaOrchestratorProvider,
SettingsProvider,
SSEProvider,
UserServicesProvider,
)
from app.settings import Settings


def create_app_container() -> AsyncContainer:
def create_app_container(settings: Settings) -> AsyncContainer:
"""
Create the application DI container.

Args:
settings: Application settings (injected via from_context).
"""
return make_async_container(
SettingsProvider(),
LoggingProvider(),
DatabaseProvider(),
RedisProvider(),
CoreServicesProvider(),
MetricsProvider(),
RepositoryProvider(),
MessagingProvider(),
EventProvider(),
ConnectionProvider(),
KafkaServicesProvider(),
SSEProvider(),
AuthProvider(),
UserServicesProvider(),
AdminServicesProvider(),
BusinessServicesProvider(),
FastapiProvider(),
context={Settings: settings},
)


def create_result_processor_container() -> AsyncContainer:
def create_result_processor_container(settings: Settings) -> AsyncContainer:
"""
Create a minimal DI container for the ResultProcessor worker.
Includes only settings, database, event/kafka, and required repositories.

Args:
settings: Application settings (injected via from_context).
"""
return make_async_container(
SettingsProvider(),
LoggingProvider(),
DatabaseProvider(),
RedisProvider(),
CoreServicesProvider(),
MetricsProvider(),
RepositoryProvider(),
EventProvider(),
MessagingProvider(),
context={Settings: settings},
)


def create_coordinator_container(settings: Settings) -> AsyncContainer:
"""Create DI container for the ExecutionCoordinator worker."""
return make_async_container(
SettingsProvider(),
LoggingProvider(),
DatabaseProvider(),
RedisProvider(),
CoreServicesProvider(),
MetricsProvider(),
RepositoryProvider(),
MessagingProvider(),
EventProvider(),
CoordinatorProvider(),
context={Settings: settings},
)


def create_k8s_worker_container(settings: Settings) -> AsyncContainer:
"""Create DI container for the KubernetesWorker."""
return make_async_container(
SettingsProvider(),
LoggingProvider(),
DatabaseProvider(),
RedisProvider(),
CoreServicesProvider(),
MetricsProvider(),
RepositoryProvider(),
MessagingProvider(),
EventProvider(),
KubernetesProvider(),
K8sWorkerProvider(),
context={Settings: settings},
)


def create_pod_monitor_container(settings: Settings) -> AsyncContainer:
"""Create DI container for the PodMonitor worker."""
return make_async_container(
SettingsProvider(),
LoggingProvider(),
DatabaseProvider(),
CoreServicesProvider(),
ConnectionProvider(),
MetricsProvider(),
RepositoryProvider(),
MessagingProvider(),
EventProvider(),
KafkaServicesProvider(),
KubernetesProvider(),
PodMonitorProvider(),
context={Settings: settings},
)


def create_saga_orchestrator_container(settings: Settings) -> AsyncContainer:
"""Create DI container for the SagaOrchestrator worker."""
return make_async_container(
SettingsProvider(),
LoggingProvider(),
DatabaseProvider(),
RedisProvider(),
CoreServicesProvider(),
MetricsProvider(),
RepositoryProvider(),
MessagingProvider(),
EventProvider(),
SagaOrchestratorProvider(),
context={Settings: settings},
)


def create_event_replay_container(settings: Settings) -> AsyncContainer:
"""Create DI container for the EventReplay worker."""
return make_async_container(
SettingsProvider(),
LoggingProvider(),
DatabaseProvider(),
CoreServicesProvider(),
MetricsProvider(),
RepositoryProvider(),
MessagingProvider(),
ResultProcessorProvider(),
EventProvider(),
EventReplayProvider(),
context={Settings: settings},
)


def create_dlq_processor_container(settings: Settings) -> AsyncContainer:
"""Create DI container for the DLQ processor worker."""
return make_async_container(
SettingsProvider(),
LoggingProvider(),
DatabaseProvider(),
CoreServicesProvider(),
MetricsProvider(),
RepositoryProvider(),
EventProvider(),
DLQProcessorProvider(),
context={Settings: settings},
)
Loading
Loading