0
# Command Handlers
1
2
The Command Handlers system provides REST-like interfaces for dynamic management of gateway rules and API definitions through Sentinel's command system. These handlers enable remote configuration and monitoring of gateway flow control settings.
3
4
## Capabilities
5
6
### GetGatewayRuleCommandHandler
7
8
Command handler for retrieving all currently loaded gateway flow rules.
9
10
```java { .api }
11
/**
12
* Command handler to fetch all gateway rules
13
* Accessible via HTTP: /gateway/getRules
14
*/
15
@CommandMapping(name = "gateway/getRules", desc = "Fetch all gateway rules")
16
class GetGatewayRuleCommandHandler implements CommandHandler<String> {
17
/**
18
* Handle the get rules request
19
* @param request Command request (typically empty for GET operations)
20
* @return Command response containing JSON representation of rules
21
*/
22
CommandResponse<String> handle(CommandRequest request);
23
}
24
```
25
26
**Usage Examples:**
27
28
```bash
29
# HTTP GET request to fetch gateway rules
30
curl http://localhost:8719/gateway/getRules
31
32
# Example response:
33
[
34
{
35
"resource": "user-api",
36
"resourceMode": 1,
37
"grade": 1,
38
"count": 100.0,
39
"intervalSec": 1,
40
"controlBehavior": 0,
41
"burst": 0,
42
"maxQueueingTimeoutMs": 500,
43
"paramItem": null
44
},
45
{
46
"resource": "payment-api",
47
"resourceMode": 1,
48
"grade": 1,
49
"count": 50.0,
50
"intervalSec": 1,
51
"controlBehavior": 0,
52
"burst": 0,
53
"maxQueueingTimeoutMs": 500,
54
"paramItem": {
55
"parseStrategy": 0,
56
"fieldName": null,
57
"pattern": null,
58
"matchStrategy": 0
59
}
60
}
61
]
62
```
63
64
### UpdateGatewayRuleCommandHandler
65
66
Command handler for updating gateway flow rules with support for persistent storage.
67
68
```java { .api }
69
/**
70
* Command handler to update gateway rules
71
* Accessible via HTTP: /gateway/updateRules
72
*/
73
@CommandMapping(name = "gateway/updateRules", desc = "Update gateway rules")
74
class UpdateGatewayRuleCommandHandler implements CommandHandler<String> {
75
/**
76
* Handle the update rules request
77
* @param request Command request containing JSON rule data
78
* @return Command response indicating success or failure
79
*/
80
CommandResponse<String> handle(CommandRequest request);
81
82
/**
83
* Get the writable data source for rule persistence
84
* @return Writable data source or null if not configured
85
*/
86
static WritableDataSource<Set<GatewayFlowRule>> getWritableDataSource();
87
88
/**
89
* Set the writable data source for rule persistence
90
* @param gatewayFlowWds Writable data source for gateway flow rules
91
*/
92
static void setWritableDataSource(WritableDataSource<Set<GatewayFlowRule>> gatewayFlowWds);
93
}
94
```
95
96
**Usage Examples:**
97
98
```bash
99
# HTTP POST request to update gateway rules
100
curl -X POST http://localhost:8719/gateway/updateRules \
101
-H "Content-Type: application/json" \
102
-d '[
103
{
104
"resource": "user-api",
105
"resourceMode": 1,
106
"grade": 1,
107
"count": 200.0,
108
"intervalSec": 1
109
},
110
{
111
"resource": "order-api",
112
"resourceMode": 1,
113
"grade": 1,
114
"count": 100.0,
115
"intervalSec": 1,
116
"paramItem": {
117
"parseStrategy": 0
118
}
119
}
120
]'
121
122
# Example success response:
123
{"result": "success", "msg": "Gateway rules updated successfully"}
124
125
# Example error response:
126
{"result": "failed", "msg": "Invalid rule format: missing resource name"}
127
```
128
129
```java
130
// Configure persistent storage for rules
131
public class RulePersistenceConfig {
132
public void configureRulePersistence() {
133
// File-based persistence
134
WritableDataSource<Set<GatewayFlowRule>> fileDataSource =
135
new FileWritableDataSource<>("gateway-rules.json",
136
rules -> JSON.toJSONString(rules, SerializerFeature.PrettyFormat));
137
138
UpdateGatewayRuleCommandHandler.setWritableDataSource(fileDataSource);
139
140
// Now rule updates will be automatically persisted to file
141
}
142
}
143
```
144
145
### GetGatewayApiDefinitionGroupCommandHandler
146
147
Command handler for retrieving all currently loaded gateway API definitions.
148
149
```java { .api }
150
/**
151
* Command handler to fetch gateway API definitions
152
* Accessible via HTTP: /gateway/getApiDefinitions
153
*/
154
@CommandMapping(name = "gateway/getApiDefinitions", desc = "Fetch all customized gateway API groups")
155
class GetGatewayApiDefinitionGroupCommandHandler implements CommandHandler<String> {
156
/**
157
* Handle the get API definitions request
158
* @param request Command request (typically empty for GET operations)
159
* @return Command response containing JSON representation of API definitions
160
*/
161
CommandResponse<String> handle(CommandRequest request);
162
}
163
```
164
165
**Usage Examples:**
166
167
```bash
168
# HTTP GET request to fetch API definitions
169
curl http://localhost:8719/gateway/getApiDefinitions
170
171
# Example response:
172
[
173
{
174
"apiName": "user-api",
175
"predicateItems": [
176
{
177
"pattern": "/api/users/**",
178
"matchStrategy": 1
179
}
180
]
181
},
182
{
183
"apiName": "order-api",
184
"predicateItems": [
185
{
186
"pattern": "/api/orders/**",
187
"matchStrategy": 1
188
},
189
{
190
"pattern": "/api/order-history/**",
191
"matchStrategy": 1
192
}
193
]
194
}
195
]
196
```
197
198
### UpdateGatewayApiDefinitionGroupCommandHandler
199
200
Command handler for updating gateway API definitions with support for persistent storage.
201
202
```java { .api }
203
/**
204
* Command handler to update gateway API definitions
205
* Accessible via HTTP: /gateway/updateApiDefinitions
206
*/
207
@CommandMapping(name = "gateway/updateApiDefinitions", desc = "")
208
class UpdateGatewayApiDefinitionGroupCommandHandler implements CommandHandler<String> {
209
/**
210
* Handle the update API definitions request
211
* @param request Command request containing JSON API definition data
212
* @return Command response indicating success or failure
213
*/
214
CommandResponse<String> handle(CommandRequest request);
215
216
/**
217
* Get the writable data source for API definition persistence
218
* @return Writable data source or null if not configured
219
*/
220
static WritableDataSource<Set<ApiDefinition>> getWritableDataSource();
221
222
/**
223
* Set the writable data source for API definition persistence
224
* @param apiDefinitionWds Writable data source for API definitions
225
*/
226
static void setWritableDataSource(WritableDataSource<Set<ApiDefinition>> apiDefinitionWds);
227
}
228
```
229
230
**Usage Examples:**
231
232
```bash
233
# HTTP POST request to update API definitions
234
curl -X POST http://localhost:8719/gateway/updateApiDefinitions \
235
-H "Content-Type: application/json" \
236
-d '[
237
{
238
"apiName": "user-service",
239
"predicateItems": [
240
{
241
"pattern": "/api/users/**",
242
"matchStrategy": 1
243
},
244
{
245
"pattern": "/api/user-profile/**",
246
"matchStrategy": 1
247
}
248
]
249
},
250
{
251
"apiName": "payment-service",
252
"predicateItems": [
253
{
254
"pattern": "/api/payments/**",
255
"matchStrategy": 1
256
}
257
]
258
}
259
]'
260
261
# Example success response:
262
{"result": "success", "msg": "API definitions updated successfully"}
263
```
264
265
```java
266
// Configure persistent storage for API definitions
267
public class ApiDefinitionPersistenceConfig {
268
public void configureApiDefinitionPersistence() {
269
// Database-based persistence
270
WritableDataSource<Set<ApiDefinition>> dbDataSource =
271
new DatabaseWritableDataSource<>(dataSource, "gateway_api_definitions");
272
273
UpdateGatewayApiDefinitionGroupCommandHandler.setWritableDataSource(dbDataSource);
274
275
// Redis-based persistence
276
WritableDataSource<Set<ApiDefinition>> redisDataSource =
277
new RedisWritableDataSource<>(jedisPool, "gateway:api:definitions");
278
279
UpdateGatewayApiDefinitionGroupCommandHandler.setWritableDataSource(redisDataSource);
280
}
281
}
282
```
283
284
## Command System Integration
285
286
The command handlers integrate with Sentinel's command system for HTTP-based management:
287
288
### Command Endpoint Configuration
289
290
```java
291
// Command handlers are automatically registered through @CommandMapping annotation
292
// Default port is 8719, configurable via system property
293
294
// Configure command center port
295
System.setProperty("csp.sentinel.api.port", "8720");
296
297
// Configure command center host
298
System.setProperty("csp.sentinel.api.host", "0.0.0.0");
299
```
300
301
### HTTP API Reference
302
303
| Endpoint | Method | Description | Request Body | Response |
304
|----------|--------|-------------|--------------|----------|
305
| `/gateway/getRules` | GET | Fetch all gateway rules | None | JSON array of gateway rules |
306
| `/gateway/updateRules` | POST | Update gateway rules | JSON array of gateway rules | Success/error message |
307
| `/gateway/getApiDefinitions` | GET | Fetch API definitions | None | JSON array of API definitions |
308
| `/gateway/updateApiDefinitions` | POST | Update API definitions | JSON array of API definitions | Success/error message |
309
310
### Request/Response Format
311
312
**Gateway Rule JSON Format:**
313
```json
314
{
315
"resource": "api-name",
316
"resourceMode": 1,
317
"grade": 1,
318
"count": 100.0,
319
"intervalSec": 1,
320
"controlBehavior": 0,
321
"burst": 0,
322
"maxQueueingTimeoutMs": 500,
323
"paramItem": {
324
"parseStrategy": 0,
325
"fieldName": "X-User-ID",
326
"pattern": "premium_.*",
327
"matchStrategy": 2
328
}
329
}
330
```
331
332
**API Definition JSON Format:**
333
```json
334
{
335
"apiName": "user-api",
336
"predicateItems": [
337
{
338
"pattern": "/api/users/**",
339
"matchStrategy": 1
340
}
341
]
342
}
343
```
344
345
## Persistent Storage Integration
346
347
Command handlers support integration with various persistent storage systems:
348
349
### File-based Persistence
350
351
```java
352
// File persistence for rules
353
WritableDataSource<Set<GatewayFlowRule>> fileRuleSource =
354
new FileWritableDataSource<>("rules.json", this::serializeRules);
355
356
// File persistence for API definitions
357
WritableDataSource<Set<ApiDefinition>> fileApiSource =
358
new FileWritableDataSource<>("api-definitions.json", this::serializeApiDefinitions);
359
```
360
361
### Database Persistence
362
363
```java
364
// Database persistence implementation
365
public class DatabaseWritableDataSource<T> implements WritableDataSource<T> {
366
private final DataSource dataSource;
367
private final String tableName;
368
369
@Override
370
public void write(T value) throws Exception {
371
try (Connection conn = dataSource.getConnection()) {
372
// Implement database write logic
373
String json = JSON.toJSONString(value);
374
PreparedStatement stmt = conn.prepareStatement(
375
"INSERT OR REPLACE INTO " + tableName + " (config_key, config_value) VALUES (?, ?)");
376
stmt.setString(1, "gateway_config");
377
stmt.setString(2, json);
378
stmt.executeUpdate();
379
}
380
}
381
}
382
```
383
384
### Redis Persistence
385
386
```java
387
// Redis persistence implementation
388
public class RedisWritableDataSource<T> implements WritableDataSource<T> {
389
private final JedisPool jedisPool;
390
private final String key;
391
392
@Override
393
public void write(T value) throws Exception {
394
try (Jedis jedis = jedisPool.getResource()) {
395
String json = JSON.toJSONString(value);
396
jedis.set(key, json);
397
}
398
}
399
}
400
```
401
402
## Error Handling
403
404
Command handlers provide comprehensive error handling:
405
406
### Common Error Responses
407
408
```json
409
// Invalid JSON format
410
{
411
"result": "failed",
412
"msg": "Invalid JSON format in request body"
413
}
414
415
// Missing required fields
416
{
417
"result": "failed",
418
"msg": "Missing required field: resource"
419
}
420
421
// Invalid rule configuration
422
{
423
"result": "failed",
424
"msg": "Invalid rule: count must be positive"
425
}
426
427
// Persistence failure
428
{
429
"result": "failed",
430
"msg": "Failed to persist configuration: database connection timeout"
431
}
432
```
433
434
### Error Handling Implementation
435
436
```java
437
public class CommandErrorHandling {
438
public CommandResponse<String> safeHandleUpdate(String requestBody) {
439
try {
440
// Parse and validate request
441
Set<GatewayFlowRule> rules = parseRules(requestBody);
442
validateRules(rules);
443
444
// Update rules
445
boolean success = GatewayRuleManager.loadRules(rules);
446
if (!success) {
447
return CommandResponse.ofFailure("Failed to load rules");
448
}
449
450
// Persist if configured
451
persistRules(rules);
452
453
return CommandResponse.ofSuccess("Rules updated successfully");
454
455
} catch (JsonParseException e) {
456
return CommandResponse.ofFailure("Invalid JSON format: " + e.getMessage());
457
} catch (ValidationException e) {
458
return CommandResponse.ofFailure("Validation error: " + e.getMessage());
459
} catch (Exception e) {
460
return CommandResponse.ofFailure("Internal error: " + e.getMessage());
461
}
462
}
463
}
464
```
465
466
## Security Considerations
467
468
When using command handlers in production:
469
470
### Authentication and Authorization
471
472
```java
473
// Custom command handler with authentication
474
public class SecureGatewayRuleCommandHandler implements CommandHandler<String> {
475
@Override
476
public CommandResponse<String> handle(CommandRequest request) {
477
// Validate authentication token
478
String token = request.getMetadata().get("Authorization");
479
if (!isValidToken(token)) {
480
return CommandResponse.ofFailure("Unauthorized");
481
}
482
483
// Check permissions
484
if (!hasUpdatePermission(token)) {
485
return CommandResponse.ofFailure("Insufficient permissions");
486
}
487
488
// Process request
489
return handleUpdate(request);
490
}
491
}
492
```
493
494
### Network Security
495
496
```java
497
// Configure command center for internal network only
498
System.setProperty("csp.sentinel.api.host", "127.0.0.1"); // Localhost only
499
System.setProperty("csp.sentinel.api.port", "8719");
500
501
// Or disable command center entirely for production
502
System.setProperty("csp.sentinel.api.port", ""); // Disable command center
503
```
504
505
## Best Practices
506
507
1. **Configure persistent storage** to maintain rules across restarts
508
2. **Implement proper error handling** for all command operations
509
3. **Validate input data** thoroughly before applying rule changes
510
4. **Use authentication** in production environments
511
5. **Monitor command handler usage** for security and operational insights
512
6. **Test rule updates** in non-production environments first
513
7. **Implement rollback mechanisms** for failed rule updates
514
8. **Use appropriate network security** to protect command endpoints
515
9. **Log all rule changes** for audit trails
516
10. **Consider rate limiting** on command endpoints to prevent abuse