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>
274 lines
7.1 KiB
Markdown
274 lines
7.1 KiB
Markdown
# 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)
|
|
```bash
|
|
# 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)
|
|
```powershell
|
|
# 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
|
|
```bash
|
|
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
|
|
```bash
|
|
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
|
|
```bash
|
|
curl -X POST "http://localhost:5000/api/gateway/reload"
|
|
```
|
|
|
|
### Option 3: Database Direct Insert
|
|
|
|
#### Insert Service Instance
|
|
```sql
|
|
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
|
|
```sql
|
|
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`:
|
|
|
|
```bash
|
|
# 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:
|
|
|
|
```bash
|
|
# 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:
|
|
|
|
```bash
|
|
# 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
|
|
```bash
|
|
# Global routes
|
|
curl http://localhost:5000/api/gateway/routes/global
|
|
|
|
# Tenant routes
|
|
curl http://localhost:5000/api/gateway/tenants/{tenantCode}/routes
|
|
```
|
|
|
|
### View Instances
|
|
```bash
|
|
curl http://localhost:5000/api/gateway/clusters/activity-service/instances
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Route Not Working
|
|
1. Check if route is configured: `GET /api/gateway/routes/global`
|
|
2. Verify instance health: `GET /api/gateway/clusters/{clusterId}/instances`
|
|
3. 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](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/routing)
|