diff --git a/chargers/apis.go b/chargers/apis.go index 700b5c47c..9beb2059c 100644 --- a/chargers/apis.go +++ b/chargers/apis.go @@ -47,7 +47,7 @@ func (cS *ChargerS) V1ProcessEvent(ctx *context.Context, args *utils.CGREvent, // V1GetChargersForEvent exposes the list of ordered matching ChargingProfiles for an event func (cS *ChargerS) V1GetChargersForEvent(ctx *context.Context, args *utils.CGREvent, - rply *utils.ChargerProfiles) (err error) { + rply *[]*utils.ChargerProfile) (err error) { tnt := args.Tenant if tnt == utils.EmptyString { tnt = cS.cfg.GeneralCfg().DefaultTenant diff --git a/chargers/chargers.go b/chargers/chargers.go index adcbb5c20..39a8da51b 100644 --- a/chargers/chargers.go +++ b/chargers/chargers.go @@ -19,6 +19,9 @@ along with this program. If not, see package chargers import ( + "cmp" + "slices" + "github.com/cgrates/birpc/context" "github.com/cgrates/cgrates/config" "github.com/cgrates/cgrates/engine" @@ -40,7 +43,7 @@ func NewChargerService(dm *engine.DataManager, filterS *engine.FilterS, } // matchingChargingProfilesForEvent returns ordered list of matching chargers which are active by the time of the function call -func (cS *ChargerS) matchingChargerProfilesForEvent(ctx *context.Context, tnt string, cgrEv *utils.CGREvent) (cPs utils.ChargerProfiles, err error) { +func (cS *ChargerS) matchingChargerProfilesForEvent(ctx *context.Context, tnt string, cgrEv *utils.CGREvent) (cPs []*utils.ChargerProfile, err error) { evNm := utils.MapStorage{ utils.MetaReq: cgrEv.Event, utils.MetaOpts: cgrEv.APIOpts, @@ -58,6 +61,8 @@ func (cS *ChargerS) matchingChargerProfilesForEvent(ctx *context.Context, tnt st if err != nil { return nil, err } + + weights := make(map[string]float64) // stores sorting weights by profile ID for cpID := range cpIDs { cP, err := cS.dm.GetChargerProfile(ctx, tnt, cpID, true, true, utils.NonTransactional) if err != nil { @@ -76,13 +81,18 @@ func (cS *ChargerS) matchingChargerProfilesForEvent(ctx *context.Context, tnt st if err != nil { return nil, err } - cP.ApplySortingWeight(weight) + weights[cP.ID] = weight cPs = append(cPs, cP) } if len(cPs) == 0 { return nil, utils.ErrNotFound } - cPs.Sort() + + // Sort by weight (higher values first). + slices.SortFunc(cPs, func(a, b *utils.ChargerProfile) int { + return cmp.Compare(weights[b.ID], weights[a.ID]) + }) + for i, cp := range cPs { var blocker bool if blocker, err = engine.BlockerFromDynamics(ctx, cp.Blockers, cS.fltrS, tnt, evNm); err != nil { @@ -104,8 +114,8 @@ type ChrgSProcessEventReply struct { } func (cS *ChargerS) processEvent(ctx *context.Context, tnt string, cgrEv *utils.CGREvent) (rply []*ChrgSProcessEventReply, err error) { - var cPs utils.ChargerProfiles - if cPs, err = cS.matchingChargerProfilesForEvent(ctx, tnt, cgrEv); err != nil { + cPs, err := cS.matchingChargerProfilesForEvent(ctx, tnt, cgrEv) + if err != nil { return nil, err } diff --git a/chargers/chargers_it_test.go b/chargers/chargers_it_test.go index af48ede4e..d0d51fc56 100644 --- a/chargers/chargers_it_test.go +++ b/chargers/chargers_it_test.go @@ -761,7 +761,7 @@ func testChargersSetGetChargerProfileEvent(t *testing.T) { } func testChargersGetChargersForEvent(t *testing.T) { - expected := &utils.ChargerProfiles{ + expected := []*utils.ChargerProfile{ { Tenant: "cgrates.org", ID: "TEST_CHARGERS_IT_TEST", @@ -783,7 +783,7 @@ func testChargersGetChargersForEvent(t *testing.T) { }, APIOpts: map[string]any{}, } - reply := &utils.ChargerProfiles{} + var reply []*utils.ChargerProfile if err := chargersRPC.Call(context.Background(), utils.ChargerSv1GetChargersForEvent, cgrEv, &reply); err != nil { t.Error(err) @@ -956,7 +956,7 @@ func testChargersBlockerGetChargersForEvent(t *testing.T) { }, APIOpts: map[string]any{}, } - expected := utils.ChargerProfiles{ + expected := []*utils.ChargerProfile{ { ID: "CHARGER_TEST_1", Tenant: "cgrates.org", @@ -1001,7 +1001,7 @@ func testChargersBlockerGetChargersForEvent(t *testing.T) { RunID: "run2", }, } - var reply utils.ChargerProfiles + var reply utils.ChargerProfile if err := chargersRPC.Call(context.Background(), utils.ChargerSv1GetChargersForEvent, args, &reply); err != nil { t.Error(err) } else if !reflect.DeepEqual(reply, expected) { diff --git a/chargers/chargers_test.go b/chargers/chargers_test.go index 956af37ca..f53f11c81 100644 --- a/chargers/chargers_test.go +++ b/chargers/chargers_test.go @@ -34,8 +34,8 @@ import ( func TestChargerSetChargerProfiles(t *testing.T) { var dmCharger *engine.DataManager - cPPs := utils.ChargerProfiles{ - &utils.ChargerProfile{ + cPPs := []*utils.ChargerProfile{ + { Tenant: "cgrates.org", ID: "CPP_1", FilterIDs: []string{"FLTR_CP_1", "FLTR_CP_4", "*string:~*opts.*subsys:*chargers", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, @@ -47,7 +47,7 @@ func TestChargerSetChargerProfiles(t *testing.T) { }, }, }, - &utils.ChargerProfile{ + { Tenant: "cgrates.org", ID: "CPP_2", FilterIDs: []string{"FLTR_CP_2", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, @@ -59,7 +59,7 @@ func TestChargerSetChargerProfiles(t *testing.T) { }, }, }, - &utils.ChargerProfile{ + { Tenant: "cgrates.org", ID: "CPP_3", FilterIDs: []string{"FLTR_CP_3", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, @@ -152,8 +152,8 @@ func TestChargerMatchingChargerProfilesForEvent(t *testing.T) { cfg := config.NewDefaultCGRConfig() var chargerSrv *ChargerS var dmCharger *engine.DataManager - cPPs := utils.ChargerProfiles{ - &utils.ChargerProfile{ + cPPs := []*utils.ChargerProfile{ + { Tenant: "cgrates.org", ID: "CPP_1", FilterIDs: []string{"FLTR_CP_1", "FLTR_CP_4", "*string:~*opts.*subsys:*chargers", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, @@ -165,7 +165,7 @@ func TestChargerMatchingChargerProfilesForEvent(t *testing.T) { }, }, }, - &utils.ChargerProfile{ + { Tenant: "cgrates.org", ID: "CPP_2", FilterIDs: []string{"FLTR_CP_2", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, @@ -177,7 +177,7 @@ func TestChargerMatchingChargerProfilesForEvent(t *testing.T) { }, }, }, - &utils.ChargerProfile{ + { Tenant: "cgrates.org", ID: "CPP_3", FilterIDs: []string{"FLTR_CP_3", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, @@ -322,8 +322,8 @@ func TestChargerProcessEvent(t *testing.T) { cfg := config.NewDefaultCGRConfig() var chargerSrv *ChargerS var dmCharger *engine.DataManager - cPPs := utils.ChargerProfiles{ - &utils.ChargerProfile{ + cPPs := []*utils.ChargerProfile{ + { Tenant: "cgrates.org", ID: "CPP_1", FilterIDs: []string{"FLTR_CP_1", "FLTR_CP_4", "*string:~*opts.*subsys:*chargers", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, @@ -335,7 +335,7 @@ func TestChargerProcessEvent(t *testing.T) { }, }, }, - &utils.ChargerProfile{ + { Tenant: "cgrates.org", ID: "CPP_2", FilterIDs: []string{"FLTR_CP_2", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, @@ -347,7 +347,7 @@ func TestChargerProcessEvent(t *testing.T) { }, }, }, - &utils.ChargerProfile{ + { Tenant: "cgrates.org", ID: "CPP_3", FilterIDs: []string{"FLTR_CP_3", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, @@ -461,7 +461,6 @@ func TestChargerProcessEvent(t *testing.T) { } //verify each charger from cache for _, cp := range cPPs { - cp.ApplySortingWeight(20) // cached ChargerProfiles have weight==20 if tempCp, err := dmCharger.GetChargerProfile(context.Background(), cp.Tenant, cp.ID, true, false, utils.NonTransactional); err != nil { t.Errorf("Error: %+v", err) @@ -886,7 +885,7 @@ func TestChargersmatchingChargerProfilesForEventBlockerTrue(t *testing.T) { }, } - exp := utils.ChargerProfiles{ + exp := []*utils.ChargerProfile{ { Tenant: "cgrates.org", ID: "CPP_2", @@ -1445,9 +1444,9 @@ func TestChargersV1GetChargersForEventNilErr(t *testing.T) { utils.AccountField: "1001", }, } - reply := &utils.ChargerProfiles{} + var reply []*utils.ChargerProfile - exp := &utils.ChargerProfiles{ + exp := []*utils.ChargerProfile{ { Tenant: "cgrates.org", ID: "1001", @@ -1455,7 +1454,7 @@ func TestChargersV1GetChargersForEventNilErr(t *testing.T) { RunID: "*default", }, } - err := cS.V1GetChargersForEvent(context.Background(), args, reply) + err := cS.V1GetChargersForEvent(context.Background(), args, &reply) if err != nil { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", nil, err) @@ -1495,11 +1494,10 @@ func TestChargersV1GetChargersForEventErr(t *testing.T) { utils.AccountField: "1001", }, } - reply := &utils.ChargerProfiles{} - - exp := &utils.ChargerProfiles{} + var reply []*utils.ChargerProfile + var exp []*utils.ChargerProfile experr := fmt.Sprintf("SERVER_ERROR: %s", utils.ErrNotImplemented) - err := cS.V1GetChargersForEvent(context.Background(), args, reply) + err := cS.V1GetChargersForEvent(context.Background(), args, &reply) if err == nil || err.Error() != experr { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", experr, err) diff --git a/console/chargers_for_event.go b/console/chargers_for_event.go index e4f12c81d..58b441f4b 100644 --- a/console/chargers_for_event.go +++ b/console/chargers_for_event.go @@ -59,6 +59,6 @@ func (self *CmdGetChargersForEvent) PostprocessRpcParams() error { } func (self *CmdGetChargersForEvent) RpcResult() any { - var atr utils.ChargerProfiles + var atr []*utils.ChargerProfile return &atr } diff --git a/utils/chargers.go b/utils/chargers.go index e932b832f..69d7ca6d6 100644 --- a/utils/chargers.go +++ b/utils/chargers.go @@ -18,18 +18,6 @@ along with this program. If not, see package utils -import ( - "sort" -) - -// ChargerProfiles is a sortable list of Charger profiles -type ChargerProfiles []*ChargerProfile - -// Sort is part of sort interface, sort based on Weight. -func (cp ChargerProfiles) Sort() { - sort.Slice(cp, func(i, j int) bool { return cp[i].weight > cp[j].weight }) -} - // ChargerProfile defines the configuration of a Charger. type ChargerProfile struct { Tenant string @@ -39,12 +27,6 @@ type ChargerProfile struct { Blockers DynamicBlockers RunID string AttributeIDs []string // perform data aliasing based on these Attributes - weight float64 -} - -// ApplySortingWeight assigns a weight value used for sorting ChargerProfiles. -func (cp *ChargerProfile) ApplySortingWeight(weight float64) { - cp.weight = weight } // TenantID returns the concatenated tenant and ID. diff --git a/utils/chargers_test.go b/utils/chargers_test.go index 275d5365c..76ad7f41c 100644 --- a/utils/chargers_test.go +++ b/utils/chargers_test.go @@ -71,25 +71,6 @@ func TestChargerProfileSet(t *testing.T) { } } -func TestChargerProfilesSort(t *testing.T) { - cp := ChargerProfiles{{}, {Weights: DynamicWeights{ - { - Weight: 20, - }, - }, - weight: 20}} - exp := ChargerProfiles{{Weights: DynamicWeights{ - { - Weight: 20, - }, - }, - weight: 20}, {}} - cp.Sort() - if !reflect.DeepEqual(exp, cp) { - t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(cp)) - } -} - func TestChargerProfileAsInterface(t *testing.T) { cp := ChargerProfile{ Tenant: "cgrates.org",