Go运行Grule引擎实现计费规则管理
- github位置:
https://github.com/hyperjumptech/grule-rule-engine
go get -u github.com/hyperjumptech/grule-rule-engine
Grule的示例代码
type ExponentData struct {
Check float64
Set float64
}
const ExponentRule = `
rule ExponentCheck "User Related Rule" salience 10 {
when
ExponentData.Check == 6.67428e-11
Then
ExponentData.Set = .12345E+5;
Retract("ExponentCheck");
}
`
func TestEvaluateAndAssignExponentNumber(t *testing.T) {
exponent := &ExponentData{
Check: 6.67428e-11,
Set: 0,
}
...
}
- 总结:Grule规则使用
when
判断条件, 当条件满足时执行 then
编写计费规则代码
- 仿照示例代码,编写计费规则代码
- 对云服务器
cpu
计费, 每小时 0.05元 * 核数 - 对云服务器
内存
计费, 每小时 0.01元 * GB
const (
rule = `
rule CalculateCost "Calculate the total cost based on CPU and Memory usage" {
when
CloudResource.CPU > 0 &&
CloudResource.Memory > 0
then
costPerCPUHour = 0.05;
costPerGBMemoryHour = 0.01;
cpuCost = CloudResource.CPU * costPerCPUHour;
memoryCost = CloudResource.Memory * costPerGBMemoryHour;
CloudResource.TotalCost = cpuCost + memoryCost;
Retract("CalculateCost");
}
`
)
type CloudResource struct {
CPU float64
Memory float64
TotalCost float64
}
- 使用
go test
执行完整代码
package example
import (
"testing"
"github.com/hyperjumptech/grule-rule-engine/ast"
"github.com/hyperjumptech/grule-rule-engine/builder"
"github.com/hyperjumptech/grule-rule-engine/engine"
"github.com/hyperjumptech/grule-rule-engine/pkg"
"github.com/stretchr/testify/assert"
)
const (
rule = `
rule CalculateCost "Calculate the total cost based on CPU and Memory usage" {
when
CloudResource.CPU > 0 &&
CloudResource.Memory > 0
then
costPerCPUHour = 0.05;
costPerGBMemoryHour = 0.01;
cpuCost = CloudResource.CPU * costPerCPUHour;
memoryCost = CloudResource.Memory * costPerGBMemoryHour;
CloudResource.TotalCost = cpuCost + memoryCost;
Retract("CalculateCost");
}
`
)
type CloudResource struct {
CPU float64
Memory float64
TotalCost float64
}
func TestCloudResource(t *testing.T) {
myResource := &CloudResource{
CPU: 2,
Memory: 4,
}
dataContext := ast.NewDataContext()
err := dataContext.Add("CloudResource", myResource)
if err != nil {
t.Fatal(err)
}
lib := ast.NewKnowledgeLibrary()
ruleBuilder := builder.NewRuleBuilder(lib)
err = ruleBuilder.BuildRuleFromResource("Test", "0.1.1", pkg.NewBytesResource([]byte(rule)))
assert.NoError(t, err)
kb, err := lib.NewKnowledgeBaseInstance("Test", "0.1.1")
assert.NoError(t, err)
eng1 := &engine.GruleEngine{MaxCycle: 1}
err = eng1.Execute(dataContext, kb)
assert.NoError(t, err)
expectedTotalCost := (2 * 0.05) + (4 * 0.01)
assert.Equal(t, expectedTotalCost, myResource.TotalCost)
}
- 总结: 使用
assert.Equal
校验 expectedTotalCost
,最后得出结果
$ go test
PASS
ok grule_study/example/test 0.007s