Common business scenarios often involve frequent rule adjustments such as:
- Seting maximum discounts for specific stores
- Configuring approval thresholds for new locations
- Creating custom contract templates
- Adjusting holiday cost parameters
These changes traditionally require code modifications with varying frequencies (weekly to monthly), leading to scattered rule implementations across codebases and documentation. This results in:
- High knowledge transfer costs
- Increased maintenance cmoplexity
- Repeated boilerplate code patterns
- Extensive testing requirements
RuleLink Architecture
RuleLink is a visual rule management system designed to address these challenges through:
- Centralized rule configuration
- Dynamic rule execution
- Reduced development overhead
The name derives from its core capability: connecting business logic through configurable rules. It leverages Aviatorscript for expression evaluation and integrates with the rule-engine-builder-ui project for UI components.
Implementation Rationale
The project originated from two key motivations:
- Addressing operational needs for dynamic payment account routing
- Rectifying limitations from previous rule menagement approaches
While modern rule engines often use Rete algorithms, RuleLink currently employs traditional pattern matching due to current rule volume constraints.
Core Components
Storage Model
- RuleScene: Scene definitions (currently payment-focused)
- RuleFactObj: Fact object definitions
- RuleBase: Rule expressions with extensible execution capabilities
Date Handling Implementation
@Component
public class TimeConverter implements ApplicationContextAware {
@Override
public void setApplicationContext(ApplicationContext context) {
AviatorEvaluator.addFunction(new TimeTransformer());
}
static class TimeTransformer extends AbstractFunction {
@Override
public AviatorObject call(Map<string object=""> env, AviatorObject arg1, AviatorObject arg2) {
String timeStr = FunctionUtils.getStringValue(arg1, env);
String pattern = FunctionUtils.getStringValue(arg2, env);
return AviatorLong.valueOf(DateUtil.parse(timeStr, pattern).getTime() / 1000);
}
@Override
public String getName() {
return "time_transform";
}
}
}
</string>
Expression Evaluation
public boolean evaluateRule(Object context, String expr) {
Map<string object=""> variables = new HashMap<>();
variables.put("context", context);
Expression compiledExpr = AviatorEvaluator.compile(expr, true);
Boolean result = (Boolean) compiledExpr.execute(variables);
return Boolean.TRUE.equals(result);
}
</string>
This implementation includes expression compilation caching to optimize performance for frequently executed rules.