403 lines
25 KiB
Markdown
403 lines
25 KiB
Markdown
# StellaOps Router Architecture
|
|
|
|
This document describes the internal architecture of the StellaOps Router framework.
|
|
|
|
## Core Components
|
|
|
|
### 1. Router Gateway
|
|
|
|
The Gateway is the HTTP ingress point that accepts client requests and routes them to appropriate microservices.
|
|
|
|
```
|
|
┌─────────────────────────────────────────────┐
|
|
│ Router Gateway │
|
|
│ │
|
|
HTTP Request ──────►│ ┌────────────────────────────────────────┐ │
|
|
│ │ Middleware Pipeline │ │
|
|
│ │ ├─ Authentication │ │
|
|
│ │ ├─ Authorization │ │
|
|
│ │ └─ Rate Limiting │ │
|
|
│ └────────────────────────────────────────┘ │
|
|
│ │ │
|
|
│ ▼ │
|
|
│ ┌────────────────────────────────────────┐ │
|
|
│ │ Route Resolution │ │
|
|
│ │ - Path matching │ │
|
|
│ │ - Service discovery │ │
|
|
│ │ - Load balancing │ │
|
|
│ └────────────────────────────────────────┘ │
|
|
│ │ │
|
|
│ ▼ │
|
|
│ ┌────────────────────────────────────────┐ │
|
|
│ │ Request Dispatch │ │
|
|
│ │ - Serialize to binary │ │
|
|
│ │ - Send via transport │ │
|
|
│ │ - Await response │ │
|
|
│ └────────────────────────────────────────┘ │
|
|
│ │ │
|
|
│ ▼ │
|
|
│ ┌────────────────────────────────────────┐ │
|
|
│ │ Response Processing │ │
|
|
│ │ - Deserialize from binary │ │
|
|
│ │ - Transform headers │ │
|
|
│ │ - Stream body │ │
|
|
│ └────────────────────────────────────────┘ │
|
|
│ │
|
|
└──────────────────────────────────────────────┘
|
|
│
|
|
▼ Binary Protocol
|
|
┌─────────────────────────────────────────────┐
|
|
│ Microservices │
|
|
└─────────────────────────────────────────────┘
|
|
```
|
|
|
|
**Key Classes:**
|
|
- `RouterGatewayMiddleware` - ASP.NET Core middleware for request handling
|
|
- `ServiceRegistry` - Tracks registered microservices and their endpoints
|
|
- `RouteResolver` - Matches incoming paths to service endpoints
|
|
- `RequestDispatcher` - Sends requests via appropriate transport
|
|
|
|
### 2. Microservice SDK
|
|
|
|
The SDK provides the programming model for building microservices with typed endpoints.
|
|
|
|
```
|
|
┌──────────────────────────────────────────────────────────────────┐
|
|
│ Microservice Process │
|
|
│ │
|
|
│ ┌────────────────────────────────────────────────────────────┐ │
|
|
│ │ Endpoint Handlers (User Code) │ │
|
|
│ │ │ │
|
|
│ │ [StellaEndpoint("POST", "/orders")] │ │
|
|
│ │ class CreateOrderEndpoint : IStellaEndpoint<Req, Res> │ │
|
|
│ │ │ │
|
|
│ │ [StellaEndpoint("GET", "/stream", SupportsStreaming=true)]│ │
|
|
│ │ class StreamEndpoint : IRawStellaEndpoint │ │
|
|
│ └────────────────────────────────────────────────────────────┘ │
|
|
│ │ │
|
|
│ ▼ │
|
|
│ ┌────────────────────────────────────────────────────────────┐ │
|
|
│ │ EndpointDescriptorProvider (Source Generated) │ │
|
|
│ │ - Collects all [StellaEndpoint] in assembly │ │
|
|
│ │ - Provides routing metadata at startup │ │
|
|
│ └────────────────────────────────────────────────────────────┘ │
|
|
│ │ │
|
|
│ ▼ │
|
|
│ ┌────────────────────────────────────────────────────────────┐ │
|
|
│ │ MicroserviceHost │ │
|
|
│ │ - Connects to gateway │ │
|
|
│ │ - Registers endpoints │ │
|
|
│ │ - Dispatches incoming requests to handlers │ │
|
|
│ │ - Manages heartbeat and reconnection │ │
|
|
│ └────────────────────────────────────────────────────────────┘ │
|
|
│ │ │
|
|
│ ▼ │
|
|
│ ┌────────────────────────────────────────────────────────────┐ │
|
|
│ │ Transport Client │ │
|
|
│ │ (InMemory, TCP, TLS, RabbitMQ, etc.) │ │
|
|
│ └────────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
└───────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
**Key Classes:**
|
|
- `StellaEndpointAttribute` - Marks endpoint classes with routing metadata
|
|
- `IStellaEndpoint<TRequest, TResponse>` - Typed endpoint interface
|
|
- `IRawStellaEndpoint` - Raw/streaming endpoint interface
|
|
- `MicroserviceHost` - Manages service lifecycle and gateway connection
|
|
|
|
### 3. Transport Layer
|
|
|
|
The transport layer provides pluggable communication protocols.
|
|
|
|
```
|
|
┌────────────────────────────────────────────────────────────────────┐
|
|
│ Transport Abstraction │
|
|
│ │
|
|
│ ┌────────────────────────────────────────────────────────────┐ │
|
|
│ │ ITransportServer / ITransportClient │ │
|
|
│ │ - ConnectAsync / AcceptAsync │ │
|
|
│ │ - SendAsync / ReceiveAsync │ │
|
|
│ │ - Disconnect / Dispose │ │
|
|
│ └────────────────────────────────────────────────────────────┘ │
|
|
│ │ │
|
|
│ ┌──────────────────┼──────────────────┐ │
|
|
│ ▼ ▼ ▼ │
|
|
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
|
│ │ InMemory │ │ TCP/TLS │ │ RabbitMQ │ │
|
|
│ │ Transport │ │ Transport │ │ Transport │ │
|
|
│ │ │ │ │ │ │ │
|
|
│ │ - Zero-copy │ │ - Binary │ │ - Async │ │
|
|
│ │ - Dev/test │ │ - Framing │ │ - Pub/Sub │ │
|
|
│ │ │ │ - Backpress │ │ - Durable │ │
|
|
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
|
│ │
|
|
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
|
│ │ UDP │ │ Valkey │ │ PostgreSQL │ │
|
|
│ │ Transport │ │ Transport │ │ Transport │ │
|
|
│ │ │ │ │ │ │ │
|
|
│ │ - Broadcast │ │ - Streams │ │ - LISTEN/ │ │
|
|
│ │ - Fire&Forg │ │ - Consumer │ │ NOTIFY │ │
|
|
│ │ │ │ Groups │ │ - Txn queue │ │
|
|
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
|
│ │
|
|
└─────────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
**Transport Selection Guidelines:**
|
|
|
|
| Scenario | Recommended Transport |
|
|
|----------|----------------------|
|
|
| Development/Testing | InMemory |
|
|
| Same-datacenter services | TCP |
|
|
| Cross-datacenter secure | TLS with mTLS |
|
|
| High-volume async | RabbitMQ |
|
|
| Broadcast notifications | UDP |
|
|
| Distributed with replay | Valkey Streams |
|
|
| Transactional messaging | PostgreSQL |
|
|
|
|
### 4. Binary Protocol
|
|
|
|
All transports use a common binary frame format:
|
|
|
|
```
|
|
┌────────────────────────────────────────────────────────────────┐
|
|
│ Frame Header (24 bytes) │
|
|
├────────────┬────────────┬────────────┬────────────┬────────────┤
|
|
│ Magic (4) │ Version(2) │ Type (2) │ Flags (4) │ Length (8) │
|
|
├────────────┴────────────┴────────────┴────────────┴────────────┤
|
|
│ Correlation ID (4) │
|
|
├─────────────────────────────────────────────────────────────────┤
|
|
│ Frame Payload │
|
|
│ │
|
|
│ For Request: │
|
|
│ ┌─────────────────────────────────────────────────────────┐ │
|
|
│ │ Method (1) │ Path Length (2) │ Path (variable) │ │
|
|
│ ├─────────────────────────────────────────────────────────┤ │
|
|
│ │ Header Count (2) │ Headers (key-length-key-val pairs) │ │
|
|
│ ├─────────────────────────────────────────────────────────┤ │
|
|
│ │ Body (remaining bytes) │ │
|
|
│ └─────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
│ For Response: │
|
|
│ ┌─────────────────────────────────────────────────────────┐ │
|
|
│ │ Status Code (2) │ Header Count (2) │ Headers (...) │ │
|
|
│ ├─────────────────────────────────────────────────────────┤ │
|
|
│ │ Body (remaining bytes) │ │
|
|
│ └─────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
└─────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
**Frame Types:**
|
|
- `0x01` - Request
|
|
- `0x02` - Response
|
|
- `0x03` - Heartbeat
|
|
- `0x04` - Registration
|
|
- `0x05` - Acknowledgment
|
|
- `0x10` - Stream Chunk
|
|
- `0x11` - Stream End
|
|
|
|
### 5. Source Generator
|
|
|
|
The `StellaOps.Microservice.SourceGen` package generates code at compile time:
|
|
|
|
```csharp
|
|
// Input: User-defined endpoint
|
|
[StellaEndpoint("POST", "/orders")]
|
|
public sealed class CreateOrderEndpoint : IStellaEndpoint<CreateOrderRequest, CreateOrderResponse>
|
|
{
|
|
// ...
|
|
}
|
|
|
|
// Generated: Endpoint descriptor
|
|
[GeneratedCode("StellaOps.Microservice.SourceGen", "1.0.0")]
|
|
internal static class StellaEndpointDescriptors
|
|
{
|
|
public static IEnumerable<EndpointDescriptor> GetDescriptors()
|
|
{
|
|
yield return new EndpointDescriptor
|
|
{
|
|
Method = HttpMethod.Post,
|
|
Path = "/orders",
|
|
TimeoutSeconds = 30,
|
|
SupportsStreaming = false,
|
|
HandlerType = typeof(CreateOrderEndpoint),
|
|
RequestType = typeof(CreateOrderRequest),
|
|
ResponseType = typeof(CreateOrderResponse)
|
|
};
|
|
}
|
|
}
|
|
|
|
// Generated: JSON Schema provider (if [ValidateSchema] present)
|
|
[GeneratedCode("StellaOps.Microservice.SourceGen", "1.0.0")]
|
|
internal static class CreateOrderRequestSchemaProvider
|
|
{
|
|
public static JsonSchema GetSchema() => JsonSchema.FromText("""
|
|
{
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"type": "object",
|
|
"properties": {
|
|
"customerId": { "type": "string" },
|
|
"amount": { "type": "number" }
|
|
},
|
|
"required": ["customerId", "amount"]
|
|
}
|
|
""");
|
|
}
|
|
```
|
|
|
|
## Request Flow
|
|
|
|
### 1. Service Registration
|
|
|
|
```
|
|
Microservice Gateway
|
|
│ │
|
|
│─────── Connect ─────────────►│
|
|
│ │
|
|
│─────── Register ────────────►│
|
|
│ (service name, version, │ ┌───────────────┐
|
|
│ endpoint descriptors) │ │ ServiceReg │
|
|
│ │ │ Registry │
|
|
│◄────── Ack ─────────────────│ └───────────────┘
|
|
│ │
|
|
│◄─────► Heartbeat ───────────►│ (every 30s)
|
|
│ │
|
|
```
|
|
|
|
### 2. Request Dispatch
|
|
|
|
```
|
|
Client Gateway Microservice
|
|
│ │ │
|
|
│── HTTP Req ──►│ │
|
|
│ │ │
|
|
│ │── Route Resolve ─► │
|
|
│ │ (path matching) │
|
|
│ │ │
|
|
│ │── Binary Frame ───────────►│
|
|
│ │ (via transport) │
|
|
│ │ │
|
|
│ │ │── Handle
|
|
│ │ │ Request
|
|
│ │ │
|
|
│ │◄── Binary Response ────────│
|
|
│ │ │
|
|
│◄─ HTTP Resp ──│ │
|
|
│ │ │
|
|
```
|
|
|
|
### 3. Streaming
|
|
|
|
```
|
|
Client Gateway Microservice
|
|
│ │ │
|
|
│── HTTP POST ─►│ │
|
|
│ (chunked) │ │
|
|
│ │── Stream Start ───────────►│
|
|
│ │ │
|
|
│ ┌─ chunk 1 ─►│── Stream Chunk ───────────►│
|
|
│ │ │ │
|
|
│ │ chunk 2 ─►│── Stream Chunk ───────────►│
|
|
│ │ │ │
|
|
│ └ chunk N ─►│── Stream End ─────────────►│
|
|
│ │ │
|
|
│ │◄── Response ───────────────│
|
|
│◄─ HTTP 200 ──│ │
|
|
│ │ │
|
|
```
|
|
|
|
## Configuration Loading
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|
│ Configuration Sources │
|
|
├─────────────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │
|
|
│ │ YAML Files │ │ Environment │ │ IConfiguration │ │
|
|
│ │ │ │ Variables │ │ (ASP.NET) │ │
|
|
│ │ - router.yaml│ │ │ │ │ │
|
|
│ │ - microserv. │ │ STELLA_* │ │ appsettings.json │ │
|
|
│ │ .yaml │ │ │ │ │ │
|
|
│ └──────────────┘ └──────────────┘ └──────────────────────┘ │
|
|
│ │ │ │ │
|
|
│ └────────────────┬────────────────────┘ │
|
|
│ ▼ │
|
|
│ ┌──────────────────┐ │
|
|
│ │ RouterConfig │ │
|
|
│ │ Provider │ │
|
|
│ │ │ │
|
|
│ │ - Hot reload │ │
|
|
│ │ - Validation │ │
|
|
│ │ - Defaults │ │
|
|
│ └──────────────────┘ │
|
|
│ │
|
|
└──────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
## Error Handling
|
|
|
|
### Transport Errors
|
|
- Connection failures trigger automatic reconnection with exponential backoff
|
|
- Failed requests are retried based on idempotency metadata
|
|
- Circuit breaker prevents cascading failures
|
|
|
|
### Request Errors
|
|
- Timeout errors return 504 Gateway Timeout
|
|
- Validation errors return 400 Bad Request with details
|
|
- Handler exceptions return 500 with sanitized message
|
|
|
|
### Resilience Patterns
|
|
|
|
```csharp
|
|
// Retry policy (configured in microservice.yaml)
|
|
retryPolicy:
|
|
maxAttempts: 3
|
|
initialDelay: 100ms
|
|
maxDelay: 5s
|
|
retryableStatuses: [502, 503, 504]
|
|
|
|
// Circuit breaker (configured in router.yaml)
|
|
circuitBreaker:
|
|
failureThreshold: 5
|
|
samplingDuration: 10s
|
|
breakDuration: 30s
|
|
```
|
|
|
|
## Security
|
|
|
|
### Transport Security
|
|
- TLS 1.3 for encrypted communication
|
|
- mTLS for mutual authentication
|
|
- Certificate validation with configurable CA trust
|
|
|
|
### Gateway Security
|
|
- Integration with Authority module for OAuth/OIDC
|
|
- Claims-based authorization at route level
|
|
- Rate limiting per client/tenant
|
|
|
|
### Message Security
|
|
- Optional message signing for integrity
|
|
- Tenant isolation in multi-tenant deployments
|
|
- Audit logging of all requests
|
|
|
|
## Performance Characteristics
|
|
|
|
| Metric | InMemory | TCP | TLS | RabbitMQ |
|
|
|--------|----------|-----|-----|----------|
|
|
| Latency (p50) | < 0.1ms | < 1ms | < 2ms | < 5ms |
|
|
| Latency (p99) | < 0.5ms | < 5ms | < 10ms | < 20ms |
|
|
| Throughput | 500K rps | 100K rps | 80K rps | 50K rps |
|
|
| Memory/conn | N/A | 2KB | 8KB | 16KB |
|
|
|
|
*Benchmarks run on AMD EPYC with 10GB network, small payloads (<1KB)*
|
|
|
|
## See Also
|
|
|
|
- [Getting Started Guide](./GETTING_STARTED.md)
|
|
- [Transport Configuration](./transports/)
|
|
- [Examples](./examples/README.md)
|
|
- [API Reference](../api/router/)
|