Go运行Grule引擎实现计费规则管理
- github位置:
https://github.com/hyperjumptech/grule-rule-engine
shell
# 安装grule模块
go get -u github.com/hyperjumptech/grule-rule-engine
Grule的示例代码
-
示例位置:
https://github.com/hyperjumptech/grule-rule-engine/tree/master/examples
- 使用
go test
运行
shellcd examples $ go test NumberExponentExample_test.go ok command-line-arguments 0.011s
- 使用
-
Grule规则
rule {}
表示规则salience 10
表示优先级为10- 优先级高的先执行
go
type ExponentData struct {
Check float64
Set float64
}
/*
条件部分 (when):
当ExponentData 结构体中的 Check 等于 6.67428e-11 时,规则会触发
动作部分 (then):
当条件满足时,将 ExponentData 结构体中的 Set 设置为 .12345E+5
然後,使用 Retract("ExponentCheck") 將這個规则從工作记忆中移除,
以防止它再次被觸發。
*/
const ExponentRule = `
rule ExponentCheck "User Related Rule" salience 10 {
when
ExponentData.Check == 6.67428e-11
Then
ExponentData.Set = .12345E+5;
Retract("ExponentCheck");
}
`
// 往下是 运行"github.com/stretchr/testify/assert"的测试代码, 忽略
func TestEvaluateAndAssignExponentNumber(t *testing.T) {
exponent := &ExponentData{
Check: 6.67428e-11,
Set: 0,
}
...
}
- 总结:Grule规则使用
when
判断条件, 当条件满足时执行then
编写计费规则代码
-
仿照示例代码,编写计费规则代码
- 对云服务器
cpu
计费, 每小时 0.05元 * 核数 - 对云服务器
内存
计费, 每小时 0.01元 * GB
goconst ( 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"); } ` )
- 将
cpu
内存
总费用
封装为结构体
gotype CloudResource struct { CPU float64 Memory float64 TotalCost float64 }
- 对云服务器
-
使用
go test
执行完整代码
go
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
,最后得出结果
shell
$ go test
PASS
ok grule_study/example/test 0.007s