- Implemented a new tool `stella-callgraph-node` that extracts call graphs from JavaScript/TypeScript projects using Babel AST. - Added command-line interface with options for JSON output and help. - Included functionality to analyze project structure, detect functions, and build call graphs. - Created a package.json file for dependency management. feat: introduce stella-callgraph-python for Python call graph extraction - Developed `stella-callgraph-python` to extract call graphs from Python projects using AST analysis. - Implemented command-line interface with options for JSON output and verbose logging. - Added framework detection to identify popular web frameworks and their entry points. - Created an AST analyzer to traverse Python code and extract function definitions and calls. - Included requirements.txt for project dependencies. chore: add framework detection for Python projects - Implemented framework detection logic to identify frameworks like Flask, FastAPI, Django, and others based on project files and import patterns. - Enhanced the AST analyzer to recognize entry points based on decorators and function definitions.
StellaOps Router Example
This example demonstrates the StellaOps Router, Gateway, and Microservice SDK working together.
Overview
The example includes:
- Examples.Gateway - HTTP gateway that routes requests to microservices
- Examples.Billing.Microservice - Sample billing service with typed and streaming endpoints
- Examples.Inventory.Microservice - Sample inventory service demonstrating multi-service routing
- Examples.Integration.Tests - End-to-end integration tests
Prerequisites
- .NET 10 SDK
- Docker and Docker Compose (for containerized deployment)
Project Structure
examples/router/
├── Examples.Router.sln
├── docker-compose.yaml
├── README.md
├── src/
│ ├── Examples.Gateway/
│ │ ├── Program.cs
│ │ ├── router.yaml
│ │ └── appsettings.json
│ ├── Examples.Billing.Microservice/
│ │ ├── Program.cs
│ │ ├── microservice.yaml
│ │ └── Endpoints/
│ │ ├── CreateInvoiceEndpoint.cs
│ │ ├── GetInvoiceEndpoint.cs
│ │ └── UploadAttachmentEndpoint.cs
│ └── Examples.Inventory.Microservice/
│ ├── Program.cs
│ └── Endpoints/
│ ├── ListItemsEndpoint.cs
│ └── GetItemEndpoint.cs
└── tests/
└── Examples.Integration.Tests/
Running Locally
Build the Solution
cd examples/router
dotnet build Examples.Router.sln
Run with Docker Compose
docker-compose up --build
This starts:
- Gateway on port 8080 (HTTP) and 5100 (TCP transport)
- Billing microservice
- Inventory microservice
- RabbitMQ (optional, for message-based transport)
Run Without Docker
Start each service in separate terminals:
# Terminal 1: Gateway
cd src/Examples.Gateway
dotnet run
# Terminal 2: Billing Microservice
cd src/Examples.Billing.Microservice
dotnet run
# Terminal 3: Inventory Microservice
cd src/Examples.Inventory.Microservice
dotnet run
Example API Calls
Billing Service
Create an invoice:
curl -X POST http://localhost:8080/invoices \
-H "Content-Type: application/json" \
-d '{"customerId": "CUST-001", "amount": 99.99, "description": "Service fee"}'
Get an invoice:
curl http://localhost:8080/invoices/INV-12345
Upload an attachment (streaming):
curl -X POST http://localhost:8080/invoices/INV-12345/attachments \
-H "Content-Type: application/octet-stream" \
--data-binary @document.pdf
Inventory Service
List items:
curl "http://localhost:8080/items?page=1&pageSize=20"
List items by category:
curl "http://localhost:8080/items?category=widgets"
Get a specific item:
curl http://localhost:8080/items/SKU-001
Adding New Endpoints
1. Create the Endpoint Class
using StellaOps.Microservice;
[StellaEndpoint("POST", "/orders", TimeoutSeconds = 30)]
public sealed class CreateOrderEndpoint : IStellaEndpoint<CreateOrderRequest, CreateOrderResponse>
{
public Task<CreateOrderResponse> HandleAsync(
CreateOrderRequest request,
CancellationToken cancellationToken)
{
// Implementation
return Task.FromResult(new CreateOrderResponse { OrderId = "ORD-123" });
}
}
2. Register in Program.cs
builder.Services.AddScoped<CreateOrderEndpoint>();
3. Update router.yaml (if needed)
Add routing rules for the new endpoint path.
Streaming Endpoints
For endpoints that handle large payloads (file uploads, etc.), implement IRawStellaEndpoint:
[StellaEndpoint("POST", "/files/{id}", SupportsStreaming = true)]
public sealed class UploadFileEndpoint : IRawStellaEndpoint
{
public async Task<RawResponse> HandleAsync(
RawRequestContext context,
CancellationToken cancellationToken)
{
var id = context.PathParameters["id"];
// Stream body directly without buffering
await using var stream = context.Body;
// Process stream...
return RawResponse.Ok("{}");
}
}
Cancellation Behavior
All endpoints receive a CancellationToken that is triggered when:
- The client disconnects
- The request timeout is exceeded
- The gateway shuts down
Always respect the cancellation token in long-running operations:
public async Task<Response> HandleAsync(Request request, CancellationToken ct)
{
// Check cancellation periodically
ct.ThrowIfCancellationRequested();
// Or pass to async operations
await SomeLongOperation(ct);
}
Payload Limits
Default limits are configured in router.yaml:
payloadLimits:
maxRequestBodySizeBytes: 10485760 # 10 MB
maxChunkSizeBytes: 65536 # 64 KB
For streaming endpoints, the body is not buffered so these limits apply per-chunk.
Running Tests
cd tests/Examples.Integration.Tests
dotnet test
The integration tests verify:
- End-to-end request routing
- Multi-service registration
- Streaming uploads
- Request cancellation
- Payload limit enforcement
Configuration
Gateway (router.yaml)
# Microservice routing rules
services:
billing:
routes:
- path: /invoices
methods: [GET, POST]
- path: /invoices/{id}
methods: [GET, PUT, DELETE]
- path: /invoices/{id}/attachments
methods: [POST]
inventory:
routes:
- path: /items
methods: [GET]
- path: /items/{sku}
methods: [GET]
Microservice (microservice.yaml)
service:
name: billing
version: 1.0.0
region: demo
endpoints:
- path: /invoices
method: POST
timeoutSeconds: 30
- path: /invoices/{id}
method: GET
timeoutSeconds: 10
routers:
- host: localhost
port: 5100
transportType: InMemory
Troubleshooting
Microservice not registering
Check that:
- Gateway is running and healthy
- Router host/port in microservice.yaml matches gateway
- Network connectivity between services
Request timeouts
Increase the timeout in the endpoint attribute:
[StellaEndpoint("POST", "/long-operation", TimeoutSeconds = 120)]
Streaming not working
Ensure the endpoint:
- Is marked with
SupportsStreaming = true - Implements
IRawStellaEndpoint - Does not buffer the entire body before processing
License
AGPL-3.0-or-later