CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-com-alibaba-csp--sentinel-api-gateway-adapter-common

Common abstraction module for API gateway flow control in Sentinel providing GatewayFlowRule and ApiDefinition for gateway-specific traffic management.

Pending
Overview
Eval results
Files

command-handlers.mddocs/

Command Handlers

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.

Capabilities

GetGatewayRuleCommandHandler

Command handler for retrieving all currently loaded gateway flow rules.

/**
 * Command handler to fetch all gateway rules
 * Accessible via HTTP: /gateway/getRules
 */
@CommandMapping(name = "gateway/getRules", desc = "Fetch all gateway rules")
class GetGatewayRuleCommandHandler implements CommandHandler<String> {
    /**
     * Handle the get rules request
     * @param request Command request (typically empty for GET operations)
     * @return Command response containing JSON representation of rules
     */
    CommandResponse<String> handle(CommandRequest request);
}

Usage Examples:

# HTTP GET request to fetch gateway rules
curl http://localhost:8719/gateway/getRules

# Example response:
[
  {
    "resource": "user-api",
    "resourceMode": 1,
    "grade": 1,
    "count": 100.0,
    "intervalSec": 1,
    "controlBehavior": 0,
    "burst": 0,
    "maxQueueingTimeoutMs": 500,
    "paramItem": null
  },
  {
    "resource": "payment-api", 
    "resourceMode": 1,
    "grade": 1,
    "count": 50.0,
    "intervalSec": 1,
    "controlBehavior": 0,
    "burst": 0,
    "maxQueueingTimeoutMs": 500,
    "paramItem": {
      "parseStrategy": 0,
      "fieldName": null,
      "pattern": null,
      "matchStrategy": 0
    }
  }
]

UpdateGatewayRuleCommandHandler

Command handler for updating gateway flow rules with support for persistent storage.

/**
 * Command handler to update gateway rules
 * Accessible via HTTP: /gateway/updateRules
 */
@CommandMapping(name = "gateway/updateRules", desc = "Update gateway rules")
class UpdateGatewayRuleCommandHandler implements CommandHandler<String> {
    /**
     * Handle the update rules request
     * @param request Command request containing JSON rule data
     * @return Command response indicating success or failure
     */
    CommandResponse<String> handle(CommandRequest request);
    
    /**
     * Get the writable data source for rule persistence
     * @return Writable data source or null if not configured
     */
    static WritableDataSource<Set<GatewayFlowRule>> getWritableDataSource();
    
    /**
     * Set the writable data source for rule persistence
     * @param gatewayFlowWds Writable data source for gateway flow rules
     */
    static void setWritableDataSource(WritableDataSource<Set<GatewayFlowRule>> gatewayFlowWds);
}

Usage Examples:

# HTTP POST request to update gateway rules
curl -X POST http://localhost:8719/gateway/updateRules \
  -H "Content-Type: application/json" \
  -d '[
    {
      "resource": "user-api",
      "resourceMode": 1,
      "grade": 1, 
      "count": 200.0,
      "intervalSec": 1
    },
    {
      "resource": "order-api",
      "resourceMode": 1,
      "grade": 1,
      "count": 100.0,
      "intervalSec": 1,
      "paramItem": {
        "parseStrategy": 0
      }
    }
  ]'

# Example success response:
{"result": "success", "msg": "Gateway rules updated successfully"}

# Example error response:
{"result": "failed", "msg": "Invalid rule format: missing resource name"}
// Configure persistent storage for rules
public class RulePersistenceConfig {
    public void configureRulePersistence() {
        // File-based persistence
        WritableDataSource<Set<GatewayFlowRule>> fileDataSource = 
            new FileWritableDataSource<>("gateway-rules.json", 
                rules -> JSON.toJSONString(rules, SerializerFeature.PrettyFormat));
        
        UpdateGatewayRuleCommandHandler.setWritableDataSource(fileDataSource);
        
        // Now rule updates will be automatically persisted to file
    }
}

GetGatewayApiDefinitionGroupCommandHandler

Command handler for retrieving all currently loaded gateway API definitions.

/**
 * Command handler to fetch gateway API definitions
 * Accessible via HTTP: /gateway/getApiDefinitions
 */
@CommandMapping(name = "gateway/getApiDefinitions", desc = "Fetch all customized gateway API groups")
class GetGatewayApiDefinitionGroupCommandHandler implements CommandHandler<String> {
    /**
     * Handle the get API definitions request
     * @param request Command request (typically empty for GET operations)
     * @return Command response containing JSON representation of API definitions
     */
    CommandResponse<String> handle(CommandRequest request);
}

Usage Examples:

# HTTP GET request to fetch API definitions
curl http://localhost:8719/gateway/getApiDefinitions

# Example response:
[
  {
    "apiName": "user-api",
    "predicateItems": [
      {
        "pattern": "/api/users/**",
        "matchStrategy": 1
      }
    ]
  },
  {
    "apiName": "order-api", 
    "predicateItems": [
      {
        "pattern": "/api/orders/**",
        "matchStrategy": 1
      },
      {
        "pattern": "/api/order-history/**",
        "matchStrategy": 1
      }
    ]
  }
]

UpdateGatewayApiDefinitionGroupCommandHandler

Command handler for updating gateway API definitions with support for persistent storage.

/**
 * Command handler to update gateway API definitions
 * Accessible via HTTP: /gateway/updateApiDefinitions
 */
@CommandMapping(name = "gateway/updateApiDefinitions", desc = "")
class UpdateGatewayApiDefinitionGroupCommandHandler implements CommandHandler<String> {
    /**
     * Handle the update API definitions request
     * @param request Command request containing JSON API definition data
     * @return Command response indicating success or failure
     */
    CommandResponse<String> handle(CommandRequest request);
    
    /**
     * Get the writable data source for API definition persistence
     * @return Writable data source or null if not configured
     */
    static WritableDataSource<Set<ApiDefinition>> getWritableDataSource();
    
    /**
     * Set the writable data source for API definition persistence  
     * @param apiDefinitionWds Writable data source for API definitions
     */
    static void setWritableDataSource(WritableDataSource<Set<ApiDefinition>> apiDefinitionWds);
}

Usage Examples:

# HTTP POST request to update API definitions
curl -X POST http://localhost:8719/gateway/updateApiDefinitions \
  -H "Content-Type: application/json" \
  -d '[
    {
      "apiName": "user-service",
      "predicateItems": [
        {
          "pattern": "/api/users/**",
          "matchStrategy": 1
        },
        {
          "pattern": "/api/user-profile/**", 
          "matchStrategy": 1
        }
      ]
    },
    {
      "apiName": "payment-service",
      "predicateItems": [
        {
          "pattern": "/api/payments/**",
          "matchStrategy": 1
        }
      ]
    }
  ]'

# Example success response:
{"result": "success", "msg": "API definitions updated successfully"}
// Configure persistent storage for API definitions
public class ApiDefinitionPersistenceConfig {
    public void configureApiDefinitionPersistence() {
        // Database-based persistence
        WritableDataSource<Set<ApiDefinition>> dbDataSource = 
            new DatabaseWritableDataSource<>(dataSource, "gateway_api_definitions");
        
        UpdateGatewayApiDefinitionGroupCommandHandler.setWritableDataSource(dbDataSource);
        
        // Redis-based persistence
        WritableDataSource<Set<ApiDefinition>> redisDataSource = 
            new RedisWritableDataSource<>(jedisPool, "gateway:api:definitions");
        
        UpdateGatewayApiDefinitionGroupCommandHandler.setWritableDataSource(redisDataSource);
    }
}

Command System Integration

The command handlers integrate with Sentinel's command system for HTTP-based management:

Command Endpoint Configuration

// Command handlers are automatically registered through @CommandMapping annotation
// Default port is 8719, configurable via system property

// Configure command center port
System.setProperty("csp.sentinel.api.port", "8720");

// Configure command center host  
System.setProperty("csp.sentinel.api.host", "0.0.0.0");

HTTP API Reference

EndpointMethodDescriptionRequest BodyResponse
/gateway/getRulesGETFetch all gateway rulesNoneJSON array of gateway rules
/gateway/updateRulesPOSTUpdate gateway rulesJSON array of gateway rulesSuccess/error message
/gateway/getApiDefinitionsGETFetch API definitionsNoneJSON array of API definitions
/gateway/updateApiDefinitionsPOSTUpdate API definitionsJSON array of API definitionsSuccess/error message

Request/Response Format

Gateway Rule JSON Format:

{
  "resource": "api-name",
  "resourceMode": 1,
  "grade": 1,
  "count": 100.0,
  "intervalSec": 1,
  "controlBehavior": 0,
  "burst": 0,
  "maxQueueingTimeoutMs": 500,
  "paramItem": {
    "parseStrategy": 0,
    "fieldName": "X-User-ID",
    "pattern": "premium_.*",
    "matchStrategy": 2
  }
}

API Definition JSON Format:

{
  "apiName": "user-api",
  "predicateItems": [
    {
      "pattern": "/api/users/**",
      "matchStrategy": 1
    }
  ]
}

Persistent Storage Integration

Command handlers support integration with various persistent storage systems:

File-based Persistence

// File persistence for rules
WritableDataSource<Set<GatewayFlowRule>> fileRuleSource = 
    new FileWritableDataSource<>("rules.json", this::serializeRules);

// File persistence for API definitions  
WritableDataSource<Set<ApiDefinition>> fileApiSource = 
    new FileWritableDataSource<>("api-definitions.json", this::serializeApiDefinitions);

Database Persistence

// Database persistence implementation
public class DatabaseWritableDataSource<T> implements WritableDataSource<T> {
    private final DataSource dataSource;
    private final String tableName;
    
    @Override
    public void write(T value) throws Exception {
        try (Connection conn = dataSource.getConnection()) {
            // Implement database write logic
            String json = JSON.toJSONString(value);
            PreparedStatement stmt = conn.prepareStatement(
                "INSERT OR REPLACE INTO " + tableName + " (config_key, config_value) VALUES (?, ?)");
            stmt.setString(1, "gateway_config");
            stmt.setString(2, json);
            stmt.executeUpdate();
        }
    }
}

Redis Persistence

// Redis persistence implementation
public class RedisWritableDataSource<T> implements WritableDataSource<T> {
    private final JedisPool jedisPool;
    private final String key;
    
    @Override
    public void write(T value) throws Exception {
        try (Jedis jedis = jedisPool.getResource()) {
            String json = JSON.toJSONString(value);
            jedis.set(key, json);
        }
    }
}

Error Handling

Command handlers provide comprehensive error handling:

Common Error Responses

// Invalid JSON format
{
  "result": "failed", 
  "msg": "Invalid JSON format in request body"
}

// Missing required fields
{
  "result": "failed",
  "msg": "Missing required field: resource"
}

// Invalid rule configuration
{
  "result": "failed", 
  "msg": "Invalid rule: count must be positive"
}

// Persistence failure
{
  "result": "failed",
  "msg": "Failed to persist configuration: database connection timeout"
}

Error Handling Implementation

public class CommandErrorHandling {
    public CommandResponse<String> safeHandleUpdate(String requestBody) {
        try {
            // Parse and validate request
            Set<GatewayFlowRule> rules = parseRules(requestBody);
            validateRules(rules);
            
            // Update rules
            boolean success = GatewayRuleManager.loadRules(rules);
            if (!success) {
                return CommandResponse.ofFailure("Failed to load rules");
            }
            
            // Persist if configured
            persistRules(rules);
            
            return CommandResponse.ofSuccess("Rules updated successfully");
            
        } catch (JsonParseException e) {
            return CommandResponse.ofFailure("Invalid JSON format: " + e.getMessage());
        } catch (ValidationException e) {
            return CommandResponse.ofFailure("Validation error: " + e.getMessage());
        } catch (Exception e) {
            return CommandResponse.ofFailure("Internal error: " + e.getMessage());
        }
    }
}

Security Considerations

When using command handlers in production:

Authentication and Authorization

// Custom command handler with authentication
public class SecureGatewayRuleCommandHandler implements CommandHandler<String> {
    @Override
    public CommandResponse<String> handle(CommandRequest request) {
        // Validate authentication token
        String token = request.getMetadata().get("Authorization");
        if (!isValidToken(token)) {
            return CommandResponse.ofFailure("Unauthorized");
        }
        
        // Check permissions
        if (!hasUpdatePermission(token)) {
            return CommandResponse.ofFailure("Insufficient permissions");
        }
        
        // Process request
        return handleUpdate(request);
    }
}

Network Security

// Configure command center for internal network only
System.setProperty("csp.sentinel.api.host", "127.0.0.1");  // Localhost only
System.setProperty("csp.sentinel.api.port", "8719");

// Or disable command center entirely for production
System.setProperty("csp.sentinel.api.port", "");  // Disable command center

Best Practices

  1. Configure persistent storage to maintain rules across restarts
  2. Implement proper error handling for all command operations
  3. Validate input data thoroughly before applying rule changes
  4. Use authentication in production environments
  5. Monitor command handler usage for security and operational insights
  6. Test rule updates in non-production environments first
  7. Implement rollback mechanisms for failed rule updates
  8. Use appropriate network security to protect command endpoints
  9. Log all rule changes for audit trails
  10. Consider rate limiting on command endpoints to prevent abuse

Install with Tessl CLI

npx tessl i tessl/maven-com-alibaba-csp--sentinel-api-gateway-adapter-common

docs

api-definitions.md

command-handlers.md

constants-configuration.md

gateway-flow-rules.md

index.md

parameter-processing.md

sentinel-integration.md

tile.json