Multi-Cloud Forensic Debugger API — Azure Service Bus, AWS SQS/SNS, GCP Pub/Sub — built with .NET 10 and Clean Architecture.
This README provides quick start instructions and API reference. For complete documentation with architecture diagrams, design patterns, and detailed flows, see:
- Comprehensive Guide — Complete guide with Mermaid diagrams
- Architecture Details — Architectural documentation with Mermaid diagrams
| Document | Purpose | Audience |
|---|---|---|
| Comprehensive Guide | Complete guide with diagrams | Everyone (novices to experts) |
| ARCHITECTURE.md | Deep architectural details | Architects, senior developers |
| FLOW.md | As-built provider routing — which controllers share a path and which don't | Anyone touching multicloud routing |
| IMPLEMENTATION_PATTERNS.md | Code patterns & conventions | Backend developers |
| DEPLOYMENT_OPERATIONS.md | Production deployment guide | DevOps, SREs |
From the project root, use the automated setup script that installs all prerequisites:
# From servicehub root directory
cd /path/to/servicehub
./run.shThis automatically:
- ✅ Installs .NET 10 SDK (if needed)
- ✅ Installs Node.js & npm (for the web UI)
- ✅ Restores all packages
- ✅ Starts both API and Web UI
If you only want to run the API server:
- .NET 10 SDK — Auto-installed by root
run.sh, or download manually - Azure Service Bus namespace (for testing)
- VS Code or Visual Studio 2022
# Navigate to API directory
cd services/api
# Restore packages
dotnet restore
# Run the API
dotnet run --project src/ServiceHub.Api/ServiceHub.Api.csproj
# Or use watch mode (hot reload for development)
dotnet watch --project src/ServiceHub.Api/ServiceHub.Api.csproj- API: http://localhost:5153
- API Docs (Scalar): http://localhost:5153/scalar/v1
- Health Check: http://localhost:5153/health
- Ready Check: http://localhost:5153/health/ready
- Live Check: http://localhost:5153/health/live
curl -X POST http://localhost:5153/api/v1/namespaces \
-H "Content-Type: application/json" \
-d '{
"name": "my-servicebus",
"connectionString": "Endpoint=sb://YOUR-NAMESPACE.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=YOUR-KEY",
"authType": 0,
"displayName": "My Service Bus",
"description": "Production Service Bus"
}'Response:
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "my-servicebus",
"displayName": "My Service Bus",
"description": "Production Service Bus",
"authType": "ConnectionString",
"isActive": true,
"createdAt": "2026-01-17T10:00:00Z",
"modifiedAt": null,
"lastConnectionTestAt": null,
"lastConnectionTestSucceeded": null
}curl -X GET http://localhost:5153/api/v1/namespaces/{namespaceId}/testResponse:
{
"isConnected": true,
"message": "Connection successful",
"testedAt": "2026-01-17T10:05:00Z"
}curl -X GET "http://localhost:5153/api/v1/queues?namespaceId={namespaceId}"Response:
[
{
"name": "my-queue",
"activeMessageCount": 42,
"deadLetterMessageCount": 0,
"sizeInBytes": 8192,
"status": "Active",
"createdAt": "2026-01-10T08:00:00Z",
"maxSizeInMegabytes": 1024,
"requiresDuplicateDetection": false,
"requiresSession": false
}
]curl -X POST http://localhost:5153/api/v1/messages/queue/my-queue \
-H "Content-Type: application/json" \
-d '{
"namespaceId": "{namespaceId}",
"entityName": "my-queue",
"body": "Hello from ServiceHub!",
"contentType": "text/plain",
"applicationProperties": {
"source": "api-test",
"priority": "high",
"timestamp": "2026-01-17T10:00:00Z"
}
}'Response: 202 Accepted
curl -X GET "http://localhost:5153/api/v1/messages/queue/my-queue?namespaceId={namespaceId}&maxMessages=10"Response:
[
{
"messageId": "abc123",
"sequenceNumber": 1,
"body": "Hello from ServiceHub!",
"contentType": "text/plain",
"enqueuedTime": "2026-01-17T10:00:00Z",
"deliveryCount": 0,
"state": "Active",
"applicationProperties": {
"source": "api-test",
"priority": "high"
}
}
]curl -X GET "http://localhost:5153/api/v1/topics?namespaceId={namespaceId}"curl -X GET "http://localhost:5153/api/v1/subscriptions?namespaceId={namespaceId}&topicName=my-topic"curl -X GET "http://localhost:5153/api/v1/messages/queue/my-queue/deadletter?namespaceId={namespaceId}&maxMessages=10"curl -X GET http://localhost:5153/api/v1/namespacescurl -X DELETE http://localhost:5153/api/v1/namespaces/{namespaceId}ServiceHub.Api/ # HTTP Layer
├── Controllers/ # API endpoints
│ └── V1/ # Version 1 controllers
│ ├── NamespacesController.cs
│ ├── QueuesController.cs
│ ├── TopicsController.cs
│ ├── SubscriptionsController.cs
│ ├── MessagesController.cs
│ ├── AnomaliesController.cs
│ └── HealthController.cs
├── Middleware/ # Request pipeline
│ ├── ErrorHandlingMiddleware.cs
│ ├── CorrelationIdMiddleware.cs
│ ├── RequestLoggingMiddleware.cs
│ └── RateLimitingMiddleware.cs
├── Configuration/ # Service configuration
│ ├── CorsConfiguration.cs
│ ├── SwaggerConfiguration.cs
│ └── HealthCheckConfiguration.cs
└── Extensions/ # Service registration
└── ServiceCollectionExtensions.cs
ServiceHub.Core/ # Domain Logic
├── Entities/ # Domain entities
│ ├── Namespace.cs
│ ├── Message.cs
│ └── Anomaly.cs
├── DTOs/ # Data transfer objects
│ ├── Requests/
│ └── Responses/
├── Interfaces/ # Abstractions
└── Enums/ # Domain enums
ServiceHub.Infrastructure/ # Azure Service Bus, SQLite, AES-GCM encryption
ServiceHub.Infrastructure.Aws/ # AWS SQS/SNS support (Cloud Bridge)
ServiceHub.Infrastructure.Gcp/ # GCP Pub/Sub support (Cloud Bridge)
ServiceHub.Shared/ # Cross-cutting Concerns
├── Results/ # Result pattern
├── Constants/ # Error codes, routes
└── Helpers/ # Utilities
Copy .env.example to .env and configure:
cp .env.example .envKey settings:
ASPNETCORE_ENVIRONMENT: Development, Staging, Production, or Simulator (gates Simulator-only endpoints and DI registrations)ENCRYPTION_KEY: For connection string encryption (32+ characters)CORS_ORIGINS: Allowed frontend origins
Main configuration file with:
- Logging: Log levels by namespace
- ServiceBus: Connection settings, retry policies
- Security: Encryption settings
- AI: AI service configuration
- RateLimit: API rate limiting
- Swagger: API documentation settings
-
Connection String Encryption
- AES-GCM encryption for stored connection strings
- Key derivation: HKDF (64-char hex keys) / PBKDF2-100k (other keys)
-
Log Injection Prevention
- All user-derived values sanitised with
LogRedactor.SanitiseForLog()before logging - Applies to Azure, AWS, and GCP infrastructure layers
- Strips newline/control characters (CodeQL
cs/log-forgingcompliant)
- All user-derived values sanitised with
-
CORS Policy
- Configurable allowed origins
- Prevents unauthorized cross-origin requests
-
Rate Limiting
- Keys on the authenticated owner ID (falls back to remote IP for unauthenticated requests), so tenants sharing a reverse-proxy IP don't share a limit bucket
- Configurable limits per endpoint
-
Request Correlation
- Tracks requests across distributed systems
- Automatic correlation ID generation
dotnet test tests/ServiceHub.UnitTests/ServiceHub.UnitTests.csprojdotnet test tests/ServiceHub.IntegrationTests/ServiceHub.IntegrationTests.csprojdotnet testThe API provides three health check endpoints:
-
General Health:
/health- Overall application health
- Returns 200 OK if healthy
-
Readiness:
/health/ready- Checks if app is ready to accept requests
- Verifies dependencies (database, external services)
-
Liveness:
/health/live- Checks if app is running
- Used for restart decisions
# Build image
docker build -t servicehub-api .
# Run container
docker run -p 5000:5000 servicehub-apiPOST /api/v1/namespaces- Create namespace connectionGET /api/v1/namespaces- List all namespacesGET /api/v1/namespaces/{id}- Get namespace by IDGET /api/v1/namespaces/{id}/test- Test connectionDELETE /api/v1/namespaces/{id}- Delete namespace
GET /api/v1/queues?namespaceId={id}- List queuesGET /api/v1/queues/{queueName}?namespaceId={id}- Get queue details
GET /api/v1/topics?namespaceId={id}- List topicsGET /api/v1/topics/{topicName}?namespaceId={id}- Get topic details
GET /api/v1/subscriptions?namespaceId={id}&topicName={topic}- List subscriptionsGET /api/v1/subscriptions/{subscriptionName}?namespaceId={id}&topicName={topic}- Get subscription details
POST /api/v1/messages/queue/{queueName}- Send to queuePOST /api/v1/messages/topic/{topicName}- Send to topicGET /api/v1/messages/queue/{queueName}?namespaceId={id}- Peek queue messagesGET /api/v1/messages/queue/{queueName}/deadletter?namespaceId={id}- Peek DLQGET /api/v1/messages/topic/{topicName}/subscription/{subscriptionName}?namespaceId={id}- Peek subscriptionGET /api/v1/messages/topic/{topicName}/subscription/{subscriptionName}/deadletter?namespaceId={id}- Peek subscription DLQ
POST /api/v1/anomalies/detect?namespaceId={id}- Detect anomaliesGET /api/v1/anomalies/{id}- Get anomaly by ID
Not yet implemented:
IAIServiceClient(the backend service these endpoints depend on) is currently a stub — it always returns "service unavailable" (503). It's unrelated to the client-side heuristic pattern detection used by AI Findings/DLQ Intelligence in the web UI, which runs entirely in-browser and calls no backend AI endpoint.
GET /health- General healthGET /health/ready- Readiness checkGET /health/live- Liveness check
- Dependency Flow: API → Infrastructure → Core ← Shared
- Domain Isolation: Core has no external dependencies
- Result Pattern: Consistent error handling throughout
- DTOs: Clear separation between domain and API models
- Interfaces: Abstractions for all external dependencies
dotnet --version # Should be 10.0 or higherdotnet builddotnet cleandotnet restoredotnet watch run --project src/ServiceHub.Api/ServiceHub.Api.csprojServiceHub API follows Clean Architecture principles with clear layer separation:
┌─────────────────────────────────────────────────────────┐
│ Presentation Layer │
│ (ServiceHub.Api - ASP.NET Core) │
│ • REST Controllers • Middleware • Filters │
│ • No business logic - only HTTP concerns │
└────────────────┬────────────────────────────────────────┘
│ Depends on ↓
┌────────────────▼────────────────────────────────────────┐
│ Domain Layer │
│ (ServiceHub.Core) │
│ • Entities • DTOs • Interfaces • Enums │
│ • No dependencies - pure domain models │
└────────────────┬────────────────────────────────────────┘
│ Implemented by ↓
┌────────────────▼────────────────────────────────────────┐
│ Infrastructure Layer │
│ (ServiceHub.Infrastructure) │
│ • Azure Service Bus client • SQLite • AI services │
│ • Implements Core interfaces │
└─────────────────────────────────────────────────────────┘
- Dependency Inversion — Core defines interfaces, Infrastructure implements them
- Single Responsibility — Each layer has one clear purpose
- Separation of Concerns — Business logic separate from infrastructure
- Testability — Easy to mock dependencies
See ARCHITECTURE.md for detailed architectural diagrams and patterns.
MIT License - see LICENSE file for details
Contributions are welcome! Please follow:
- Fork the repository
- Create a feature branch
- Commit your changes
- Push to the branch
- Create a Pull Request
For issues, questions, or feature requests:
- Open an issue on GitHub
- Check existing documentation
- Review Swagger UI for API details
Built with ❤️ using .NET 10, Clean Architecture, and Azure Service Bus