Changes: - Remove deprecated Fengling.Activity and YarpGateway.Admin projects - Add points processing services with distributed lock support - Update Vben frontend with gateway management pages - Add gateway config controller and database listener - Update routing to use header-mixed-nav layout - Add comprehensive test suites for Member services - Add YarpGateway integration tests - Update package versions in Directory.Packages.props Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
7.1 KiB
7.1 KiB
Activity Service Gateway Integration Guide
Overview
This document describes how to integrate the Activity Engine microservice with the YARP reverse proxy gateway.
Architecture
Client Request
│
▼
┌─────────────────────────────────┐
│ YARP Gateway │
│ │
│ Route: /api/activity/** │
│ Cluster: activity-service │
└─────────────────────────────────┘
│
▼
┌─────────────────────────────────┐
│ Activity Service │
│ http://localhost:5001 │
│ │
│ GET /api/activity/campaigns │
│ POST /api/activity/campaigns │
│ GET /api/activity/campaigns/.. │
└─────────────────────────────────┘
Configuration Steps
Option 1: Using Command Line Script
Bash (Linux/macOS)
# Make script executable
chmod +x scripts/gateway/register-activity-service.sh
# Register with global route (all tenants)
./scripts/gateway/register-activity-service.sh \
--gateway-url "http://localhost:5000" \
--service-name "activity" \
--cluster-id "activity-service" \
--address "http://localhost:5001"
# Register with tenant-specific route
./scripts/gateway/register-activity-service.sh \
--gateway-url "http://localhost:5000" \
--tenant-code "tenant001" \
--service-name "activity" \
--address "http://localhost:5001"
PowerShell (Windows)
# Register with global route
pwsh scripts/gateway/Register-ActivityService.ps1 `
-GatewayUrl "http://localhost:5000" `
-ServiceName "activity" `
-ClusterId "activity-service" `
-InstanceAddress "http://localhost:5001" `
-IsGlobal
# Register with tenant-specific route
pwsh scripts/gateway/Register-ActivityService.ps1 `
-GatewayUrl "http://localhost:5000" `
-TenantCode "tenant001" `
-ServiceName "activity" `
-InstanceAddress "http://localhost:5001"
Option 2: Using Gateway Management API
1. Add Service Instance
curl -X POST "http://localhost:5000/api/gateway/clusters/activity-service/instances" \
-H "Content-Type: application/json" \
-d '{
"destinationId": "activity-1",
"address": "http://localhost:5001",
"weight": 1
}'
2. Add Global Route
curl -X POST "http://localhost:5000/api/gateway/routes/global" \
-H "Content-Type: application/json" \
-d '{
"serviceName": "activity",
"clusterId": "activity-service",
"pathPattern": "/api/activity/{**path}"
}'
3. Reload Configuration
curl -X POST "http://localhost:5000/api/gateway/reload"
Option 3: Database Direct Insert
Insert Service Instance
INSERT INTO "ServiceInstances" (
"Id",
"ClusterId",
"DestinationId",
"Address",
"Health",
"Weight",
"Status",
"CreatedTime"
)
VALUES (
EXTRACT(EPOCH FROM NOW())::bigint * 1000,
'activity-service',
'activity-1',
'http://localhost:5001',
1,
1,
1,
NOW()
);
Insert Global Route
INSERT INTO "TenantRoutes" (
"Id",
"TenantCode",
"ServiceName",
"ClusterId",
"PathPattern",
"Priority",
"Status",
"IsGlobal",
"CreatedTime"
)
VALUES (
EXTRACT(EPOCH FROM NOW())::bigint * 1000 + 1,
'',
'activity',
'activity-service',
'/api/activity/{**path}',
0,
1,
true,
NOW()
);
API Endpoints
After configuration, the following endpoints will be available through the gateway:
| Method | Path | Description |
|---|---|---|
| POST | /api/activity/api/campaigns |
Create a new campaign |
| GET | /api/activity/api/campaigns |
List all campaigns |
| GET | /api/activity/api/campaigns/{id} |
Get campaign by ID |
| POST | /api/activity/api/campaigns/{id}/publish |
Publish a campaign |
Health Check
The Activity service exposes a health check endpoint at /health:
# Direct access
curl http://localhost:5001/health
# Through gateway
curl http://localhost:5000/api/activity/health
Multiple Instances
For high availability, add multiple service instances:
# Add second instance
curl -X POST "http://localhost:5000/api/gateway/clusters/activity-service/instances" \
-H "Content-Type: application/json" \
-d '{
"destinationId": "activity-2",
"address": "http://localhost:5002",
"weight": 1
}'
# Reload configuration
curl -X POST "http://localhost:5000/api/gateway/reload"
Load Balancing
The gateway uses Distributed Weighted Round Robin load balancing by default. Adjust weights for traffic distribution:
# Increase weight for a high-performance instance
curl -X PUT "http://localhost:5000/api/gateway/instances/12345" \
-H "Content-Type: application/json" \
-d '{"weight": 2}'
Monitoring
View Routes
# Global routes
curl http://localhost:5000/api/gateway/routes/global
# Tenant routes
curl http://localhost:5000/api/gateway/tenants/{tenantCode}/routes
View Instances
curl http://localhost:5000/api/gateway/clusters/activity-service/instances
Troubleshooting
Route Not Working
- Check if route is configured:
GET /api/gateway/routes/global - Verify instance health:
GET /api/gateway/clusters/{clusterId}/instances - Reload configuration:
POST /api/gateway/reload
404 Not Found
- Ensure the path pattern matches the request URL
- Check if the route is active (Status = 1)
502 Bad Gateway
- Verify the service instance is running
- Check the service address is accessible from the gateway
- Verify health check endpoint:
GET /health
Configuration Reference
GwServiceInstance Fields
| Field | Type | Description |
|---|---|---|
| ClusterId | string | Unique cluster identifier |
| DestinationId | string | Unique destination identifier |
| Address | string | Service address (http://host:port) |
| Weight | int | Load balancing weight (default: 1) |
| Health | int | Health status (1 = healthy) |
| Status | int | Active status (1 = active) |
GwTenantRoute Fields
| Field | Type | Description |
|---|---|---|
| TenantCode | string | Tenant identifier (empty for global) |
| ServiceName | string | Logical service name |
| ClusterId | string | Target cluster identifier |
| PathPattern | string | URL path pattern with placeholders |
| Priority | int | Route priority (lower = higher priority) |
| IsGlobal | bool | Whether route applies to all tenants |
Path Pattern Syntax
YARP uses ASP.NET Core routing syntax for path patterns:
| Pattern | Description |
|---|---|
/api/activity |
Exact match |
/api/activity/{**path} |
Catch-all segment |
/api/activity/{id} |
Parameter segment |
/api/activity/{id}/rewards |
Multiple parameters |
For more details, see ASP.NET Core Routing