DynamicWeights in ActionProfile

This commit is contained in:
andronache98
2022-02-09 15:14:51 +02:00
committed by Dan Christian Bogos
parent ff5f69cd15
commit b6ff4ba8d8
22 changed files with 217 additions and 102 deletions

View File

@@ -24,6 +24,7 @@ import (
"strings"
"time"
"github.com/cgrates/birpc/context"
"github.com/cgrates/cgrates/config"
"github.com/cgrates/cgrates/utils"
)
@@ -33,11 +34,12 @@ type ActionProfile struct {
Tenant string
ID string
FilterIDs []string
Weight float64
Weights utils.DynamicWeights
Schedule string
Targets map[string]utils.StringSet
Actions []*APAction
weight float64
}
func (aP *ActionProfile) TenantID() string {
@@ -49,7 +51,15 @@ type ActionProfiles []*ActionProfile
// Sort is part of sort interface, sort based on Weight
func (aps ActionProfiles) Sort() {
sort.Slice(aps, func(i, j int) bool { return aps[i].Weight > aps[j].Weight })
sort.Slice(aps, func(i, j int) bool { return aps[i].weight > aps[j].weight })
}
func (ap *ActionProfile) GetWeightFromDynamics(ctx *context.Context,
fltrS *FilterS, tnt string, ev utils.DataProvider) (err error) {
if ap.weight, err = WeightFromDynamics(ctx, ap.Weights, fltrS, tnt, ev); err != nil {
return
}
return
}
// APAction defines action related information used within a ActionProfile
@@ -111,7 +121,7 @@ func (aP *ActionProfile) Set(path []string, val interface{}, newBranch bool, _ s
aP.FilterIDs = append(aP.FilterIDs, valA...)
case utils.Weight:
if val != utils.EmptyString {
aP.Weight, err = utils.IfaceAsFloat64(val)
aP.Weights, err = utils.NewDynamicWeightsFromString(utils.IfaceAsString(val), utils.InfieldSep, utils.ANDSep)
}
}
return
@@ -229,9 +239,7 @@ func (ap *ActionProfile) Merge(v2 interface{}) {
equal = false
}
if vi.Weight != 0 {
ap.Weight = vi.Weight
}
ap.Weights = append(ap.Weights, vi.Weights...)
if len(vi.Schedule) != 0 {
ap.Schedule = vi.Schedule
}
@@ -308,7 +316,7 @@ func (ap *ActionProfile) FieldAsInterface(fldPath []string) (_ interface{}, err
case utils.FilterIDs:
return ap.FilterIDs, nil
case utils.Weight:
return ap.Weight, nil
return ap.Weights, nil
case utils.Actions:
return ap.Actions, nil
case utils.Schedule:

View File

@@ -31,35 +31,59 @@ func TestActionProfileSort(t *testing.T) {
{
Tenant: "test_tenantA",
ID: "test_idA",
Weight: 1,
Weights: utils.DynamicWeights{
{
Weight: 1,
},
},
},
{
Tenant: "test_tenantB",
ID: "test_idB",
Weight: 2,
Weights: utils.DynamicWeights{
{
Weight: 2,
},
},
},
{
Tenant: "test_tenantC",
ID: "test_idC",
Weight: 3,
Weights: utils.DynamicWeights{
{
Weight: 3,
},
},
},
}
expStruct := &ActionProfiles{
{
Tenant: "test_tenantC",
ID: "test_idC",
Weight: 3,
Weights: utils.DynamicWeights{
{
Weight: 3,
},
},
},
{
Tenant: "test_tenantB",
ID: "test_idB",
Weight: 2,
Weights: utils.DynamicWeights{
{
Weight: 2,
},
},
},
{
Tenant: "test_tenantA",
ID: "test_idA",
Weight: 1,
Weights: utils.DynamicWeights{
{
Weight: 1,
},
},
},
}
testStruct.Sort()
@@ -137,7 +161,11 @@ func TestActionProfileSet(t *testing.T) {
ID: "ID",
FilterIDs: []string{"fltr1", "*string:~*req.Account:1001"},
Schedule: utils.MetaNow,
Weight: 10,
Weights: utils.DynamicWeights{
{
Weight: 10,
},
},
Targets: map[string]utils.StringSet{
utils.MetaAccounts: utils.NewStringSet([]string{"1001", "1002"}),
utils.MetaThresholds: utils.NewStringSet([]string{"TH1", "TH2"}),
@@ -253,7 +281,11 @@ func TestActionProfileFieldAsInterface(t *testing.T) {
ID: "ID",
FilterIDs: []string{"fltr1", "*string:~*req.Account:1001"},
Schedule: utils.MetaNow,
Weight: 10,
Weights: utils.DynamicWeights{
{
Weight: 10,
},
},
Targets: map[string]utils.StringSet{
utils.MetaAccounts: utils.NewStringSet([]string{"1001", "1002"}),
utils.MetaThresholds: utils.NewStringSet([]string{"TH1", "TH2"}),
@@ -307,7 +339,7 @@ func TestActionProfileFieldAsInterface(t *testing.T) {
}
if val, err := ap.FieldAsInterface([]string{utils.Weight}); err != nil {
t.Fatal(err)
} else if exp := ap.Weight; !reflect.DeepEqual(exp, val) {
} else if exp := ap.Weights; !reflect.DeepEqual(exp, val) {
t.Errorf("Expected %v \n but received \n %v", utils.ToJSON(exp), utils.ToJSON(val))
}
if val, err := ap.FieldAsInterface([]string{utils.Actions}); err != nil {
@@ -501,19 +533,27 @@ func TestActionProfileMerge(t *testing.T) {
Tenant: "cgrates.org",
ID: "ID",
FilterIDs: []string{"fltr1"},
Weight: 65,
Schedule: "* * * * *",
Targets: map[string]utils.StringSet{utils.MetaAccounts: {"1001": {}}},
Actions: []*APAction{{}},
Weights: utils.DynamicWeights{
{
Weight: 65,
},
},
Schedule: "* * * * *",
Targets: map[string]utils.StringSet{utils.MetaAccounts: {"1001": {}}},
Actions: []*APAction{{}},
}
if acc.Merge(&ActionProfile{
Tenant: "cgrates.org",
ID: "ID",
FilterIDs: []string{"fltr1"},
Weight: 65,
Schedule: "* * * * *",
Targets: map[string]utils.StringSet{utils.MetaAccounts: {"1001": {}}},
Actions: []*APAction{{}},
Weights: utils.DynamicWeights{
{
Weight: 65,
},
},
Schedule: "* * * * *",
Targets: map[string]utils.StringSet{utils.MetaAccounts: {"1001": {}}},
Actions: []*APAction{{}},
}); !reflect.DeepEqual(exp, acc) {
t.Errorf("Expected %v \n but received \n %v", utils.ToJSON(exp), utils.ToJSON(acc))
}

View File

@@ -574,7 +574,7 @@ func TestLoadActionProfiles(t *testing.T) {
TPid: testTPID,
Tenant: "cgrates.org",
ID: "ONE_TIME_ACT",
Weight: 10,
Weights: ";10",
Schedule: utils.MetaASAP,
Targets: []*utils.TPActionTarget{
{

View File

@@ -2025,8 +2025,8 @@ func (apm ActionProfileMdls) AsTPActionProfile() (result []*utils.TPActionProfil
}
filterIDsMap[tenID].AddSlice(strings.Split(tp.FilterIDs, utils.InfieldSep))
}
if tp.Weight != 0 {
aPrf.Weight = tp.Weight
if tp.Weights != "" {
aPrf.Weights = tp.Weights
}
if tp.Schedule != utils.EmptyString {
aPrf.Schedule = tp.Schedule
@@ -2092,7 +2092,7 @@ func APItoModelTPActionProfile(tPrf *utils.TPActionProfile) (mdls ActionProfileM
if i == 0 {
mdl.FilterIDs = strings.Join(tPrf.FilterIDs, utils.InfieldSep)
mdl.Weight = tPrf.Weight
mdl.Weights = tPrf.Weights
mdl.Schedule = tPrf.Schedule
for _, target := range tPrf.Targets {
mdl.TargetType = target.TargetType
@@ -2129,11 +2129,15 @@ func APItoActionProfile(tpAp *utils.TPActionProfile, timezone string) (ap *Actio
Tenant: tpAp.Tenant,
ID: tpAp.ID,
FilterIDs: make([]string, len(tpAp.FilterIDs)),
Weight: tpAp.Weight,
Schedule: tpAp.Schedule,
Targets: make(map[string]utils.StringSet),
Actions: make([]*APAction, len(tpAp.Actions)),
}
if tpAp.Weights != utils.EmptyString {
if ap.Weights, err = utils.NewDynamicWeightsFromString(tpAp.Weights, utils.InfieldSep, utils.ANDSep); err != nil {
return
}
}
for i, stp := range tpAp.FilterIDs {
ap.FilterIDs[i] = stp
}
@@ -2179,7 +2183,7 @@ func ActionProfileToAPI(ap *ActionProfile) (tpAp *utils.TPActionProfile) {
Tenant: ap.Tenant,
ID: ap.ID,
FilterIDs: make([]string, len(ap.FilterIDs)),
Weight: ap.Weight,
Weights: ap.Weights.String(utils.InfieldSep, utils.ANDSep),
Schedule: ap.Schedule,
Targets: make([]*utils.TPActionTarget, 0, len(ap.Targets)),
Actions: make([]*utils.TPAPAction, len(ap.Actions)),

View File

@@ -3690,7 +3690,7 @@ func TestActionProfileMdlsAsTPActionProfileTimeLen1(t *testing.T) {
Tenant: "cgrates.org",
ID: "RP1",
FilterIDs: "*string:~*req.Subject:1001;*ai:~*req.AnswerTime:2014-07-29T15:00:00Z",
Weight: 1,
Weights: ";1",
Schedule: "test_schedule",
ActionID: "test_action_id",
ActionFilterIDs: "test_action_filter_ids",
@@ -3702,7 +3702,7 @@ func TestActionProfileMdlsAsTPActionProfileTimeLen1(t *testing.T) {
Tenant: "cgrates.org",
ID: "RP1",
FilterIDs: []string{"*ai:~*req.AnswerTime:2014-07-29T15:00:00Z", "*string:~*req.Subject:1001"},
Weight: 1,
Weights: ";1",
Schedule: "test_schedule",
Actions: []*utils.TPAPAction{
{
@@ -3727,7 +3727,7 @@ func TestActionProfileMdlsAsTPActionProfile(t *testing.T) {
Tenant: "cgrates.org",
ID: "RP1",
FilterIDs: "*string:~*req.Subject:1001;*ai:~*req.AnswerTime:2014-07-29T15:00:00Z|2014-08-29T15:00:00Z",
Weight: 1,
Weights: ";1",
Schedule: "test_schedule",
TargetType: utils.MetaAccounts,
TargetIDs: "test_account_id1;test_account_id2",
@@ -3741,7 +3741,7 @@ func TestActionProfileMdlsAsTPActionProfile(t *testing.T) {
Tenant: "cgrates.org",
ID: "RP1",
FilterIDs: []string{"*ai:~*req.AnswerTime:2014-07-29T15:00:00Z|2014-08-29T15:00:00Z", "*string:~*req.Subject:1001"},
Weight: 1,
Weights: ";1",
Schedule: "test_schedule",
Targets: []*utils.TPActionTarget{
&utils.TPActionTarget{
@@ -3784,7 +3784,7 @@ func TestAPItoModelTPActionProfileTPActionProfile(t *testing.T) {
Tenant: "cgrates.org",
ID: "RP1",
FilterIDs: []string{"*string:~*req.Subject:1001", "*string:~*req.Subject:1002", "*ai:~*req.AnswerTime:2014-07-29T15:00:00Z|2014-08-29T15:00:00Z"},
Weight: 1,
Weights: ";1",
Schedule: "test_schedule",
Targets: []*utils.TPActionTarget{{
TargetType: utils.MetaAccounts,
@@ -3804,7 +3804,7 @@ func TestAPItoModelTPActionProfileTPActionProfile(t *testing.T) {
Tenant: "cgrates.org",
ID: "RP1",
FilterIDs: "*string:~*req.Subject:1001;*string:~*req.Subject:1002;*ai:~*req.AnswerTime:2014-07-29T15:00:00Z|2014-08-29T15:00:00Z",
Weight: 1,
Weights: ";1",
Schedule: "test_schedule",
TargetType: utils.MetaAccounts,
TargetIDs: "test_account_id1;test_account_id2",
@@ -3822,7 +3822,7 @@ func TestModelHelpersAPItoActionProfile(t *testing.T) {
Tenant: "cgrates.org",
ID: "RP1",
FilterIDs: []string{"*string:~*req.Subject:1001", "*string:~*req.Subject:1002", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z|2014-07-15T14:25:00Z"},
Weight: 1,
Weights: ";1",
Schedule: "test_schedule",
Targets: []*utils.TPActionTarget{
&utils.TPActionTarget{
@@ -3850,8 +3850,12 @@ func TestModelHelpersAPItoActionProfile(t *testing.T) {
Tenant: "cgrates.org",
ID: "RP1",
FilterIDs: []string{"*ai:~*req.AnswerTime:2014-07-14T14:25:00Z|2014-07-15T14:25:00Z", "*string:~*req.Subject:1001", "*string:~*req.Subject:1002"},
Weight: 1,
Schedule: "test_schedule",
Weights: utils.DynamicWeights{
{
Weight: 1,
},
},
Schedule: "test_schedule",
Targets: map[string]utils.StringSet{
utils.MetaAccounts: utils.NewStringSet([]string{"test_account_id1", "test_account_id2"}),
utils.MetaResources: utils.NewStringSet([]string{"test_ID1", "test_ID2"}),
@@ -3883,7 +3887,7 @@ func TestModelHelpersAPItoActionProfileError3(t *testing.T) {
Tenant: "cgrates.org",
ID: "RP1",
FilterIDs: []string{"*string:~*req.Subject:1001", "*string:~*req.Subject:1002", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z|2014-07-15T14:25:00Z"},
Weight: 1,
Weights: ";1",
Schedule: "test_schedule",
Actions: []*utils.TPAPAction{
{
@@ -3908,7 +3912,7 @@ func TestModelHelpersAPItoActionProfileError4(t *testing.T) {
Tenant: "cgrates.org",
ID: "RP1",
FilterIDs: []string{"*string:~*req.Subject:1001", "*string:~*req.Subject:1002", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z|2014-07-15T14:25:00Z"},
Weight: 1,
Weights: ";1",
Schedule: "test_schedule",
Actions: []*utils.TPAPAction{
{
@@ -3933,8 +3937,12 @@ func TestModelHelpersActionProfileToAPI(t *testing.T) {
Tenant: "cgrates.org",
ID: "RP1",
FilterIDs: []string{"*string:~*req.Subject:1001", "*string:~*req.Subject:1002", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z|2014-07-15T14:25:00Z"},
Weight: 1,
Schedule: "test_schedule",
Weights: utils.DynamicWeights{
{
Weight: 1,
},
},
Schedule: "test_schedule",
Actions: []*APAction{
{
ID: "test_action_id",
@@ -3953,7 +3961,7 @@ func TestModelHelpersActionProfileToAPI(t *testing.T) {
Tenant: "cgrates.org",
ID: "RP1",
FilterIDs: []string{"*string:~*req.Subject:1001", "*string:~*req.Subject:1002", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z|2014-07-15T14:25:00Z"},
Weight: 1,
Weights: ";1",
Schedule: "test_schedule",
Targets: []*utils.TPActionTarget{},
Actions: []*utils.TPAPAction{
@@ -4936,7 +4944,7 @@ func TestModelHelpersActionProfileToAPICase2(t *testing.T) {
Tenant: "cgrates.org",
ID: "RP1",
FilterIDs: []string{"*string:~*req.Subject:1001", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z|2014-07-15T14:25:00Z"},
Weight: 1,
Weights: ";1",
Schedule: "test_schedule",
Targets: []*utils.TPActionTarget{
&utils.TPActionTarget{
@@ -4960,7 +4968,7 @@ func TestModelHelpersActionProfileToAPICase2(t *testing.T) {
Tenant: "cgrates.org",
ID: "RP1",
FilterIDs: []string{"*string:~*req.Subject:1001", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z|2014-07-15T14:25:00Z"},
Weight: 1,
Weights: ";1",
Schedule: "test_schedule",
Targets: []*utils.TPActionTarget{
&utils.TPActionTarget{

View File

@@ -324,21 +324,21 @@ func (RateProfileMdl) TableName() string {
type ActionProfileMdl struct {
PK uint `gorm:"primary_key"`
Tpid string
Tenant string `index:"0" re:""`
ID string `index:"1" re:""`
FilterIDs string `index:"2" re:""`
Weight float64 `index:"3" re:"\d+\.?\d*"`
Schedule string `index:"4" re:""`
TargetType string `index:"5" re:""`
TargetIDs string `index:"6" re:""`
ActionID string `index:"7" re:""`
ActionFilterIDs string `index:"8" re:""`
ActionBlocker bool `index:"9" re:""`
ActionTTL string `index:"10" re:""`
ActionType string `index:"11" re:""`
ActionOpts string `index:"12" re:""`
ActionPath string `index:"13" re:""`
ActionValue string `index:"14" re:""`
Tenant string `index:"0" re:""`
ID string `index:"1" re:""`
FilterIDs string `index:"2" re:""`
Weights string `index:"3" re:"\d+\.?\d*"`
Schedule string `index:"4" re:""`
TargetType string `index:"5" re:""`
TargetIDs string `index:"6" re:""`
ActionID string `index:"7" re:""`
ActionFilterIDs string `index:"8" re:""`
ActionBlocker bool `index:"9" re:""`
ActionTTL string `index:"10" re:""`
ActionType string `index:"11" re:""`
ActionOpts string `index:"12" re:""`
ActionPath string `index:"13" re:""`
ActionValue string `index:"14" re:""`
CreatedAt time.Time
}

View File

@@ -1108,8 +1108,12 @@ func testOnStorITActionProfile(t *testing.T) {
Tenant: "cgrates.org",
ID: "TEST_ID1",
FilterIDs: []string{"*string:~*req.Account:1001"},
Weight: 20,
Schedule: utils.MetaASAP,
Weights: utils.DynamicWeights{
{
Weight: 20,
},
},
Schedule: utils.MetaASAP,
Targets: map[string]utils.StringSet{
utils.MetaAccounts: utils.NewStringSet([]string{"acc1", "acc2", "acc3"}),
},

View File

@@ -226,7 +226,7 @@ func testStorDBitCRUDTPActionProfiles(t *testing.T) {
TPid: "TEST_ID1",
ID: "sub_id1",
FilterIDs: []string{"*string:~*req.Account:1001"},
Weight: 20,
Weights: ";20",
Schedule: utils.MetaASAP,
Actions: []*utils.TPAPAction{
{
@@ -243,7 +243,7 @@ func testStorDBitCRUDTPActionProfiles(t *testing.T) {
TPid: "TEST_ID1",
ID: "sub_id2",
FilterIDs: []string{"*string:~*req.Destination:10"},
Weight: 10,
Weights: ";10",
Schedule: utils.MetaASAP,
Actions: []*utils.TPAPAction{
{
@@ -269,7 +269,7 @@ func testStorDBitCRUDTPActionProfiles(t *testing.T) {
//UPDATE AND READ
actPrf[0].FilterIDs = []string{"*string:~*req.Account:1007"}
actPrf[1].Weight = 20
actPrf[1].Weights = ";20"
if err := storDB.SetTPActionProfiles(actPrf); err != nil {
t.Error(err)
} else if rcv, err := storDB.GetTPActionProfiles(actPrf[0].TPid,