diff --git a/apier/v1/suppliers.go b/apier/v1/suppliers.go index f5bc0cc79..270781a15 100644 --- a/apier/v1/suppliers.go +++ b/apier/v1/suppliers.go @@ -82,7 +82,7 @@ func (splv1 *SupplierSv1) Call(serviceMethod string, } // GetSuppliers returns sorted list of suppliers for Event -func (splv1 *SupplierSv1) GetSuppliers(args *utils.CGREvent, +func (splv1 *SupplierSv1) GetSuppliers(args *engine.ArgsGetSuppliers, reply *engine.SortedSuppliers) error { return splv1.splS.V1GetSuppliers(args, reply) } diff --git a/apier/v1/suppliers_it_test.go b/apier/v1/suppliers_it_test.go index 3494cd6b1..7fdd73f80 100644 --- a/apier/v1/suppliers_it_test.go +++ b/apier/v1/suppliers_it_test.go @@ -123,12 +123,14 @@ func testV1SplSFromFolder(t *testing.T) { } func testV1SplSGetWeightSuppliers(t *testing.T) { - ev := &utils.CGREvent{ - Tenant: "cgrates.org", - ID: "testV1SplSGetWeightSuppliers", - Event: map[string]interface{}{ - utils.Account: "1007", - utils.Destination: "+491511231234", + ev := &engine.ArgsGetSuppliers{ + CGREvent: utils.CGREvent{ + Tenant: "cgrates.org", + ID: "testV1SplSGetWeightSuppliers", + Event: map[string]interface{}{ + utils.Account: "1007", + utils.Destination: "+491511231234", + }, }, } eSpls := engine.SortedSuppliers{ @@ -160,15 +162,17 @@ func testV1SplSGetWeightSuppliers(t *testing.T) { } func testV1SplSGetLeastCostSuppliers(t *testing.T) { - ev := &utils.CGREvent{ - Tenant: "cgrates.org", - ID: "testV1SplSGetLeastCostSuppliers", - Event: map[string]interface{}{ - utils.Account: "1001", - utils.Subject: "1001", - utils.Destination: "1002", - utils.AnswerTime: time.Date(2017, 12, 1, 14, 25, 0, 0, time.UTC), - utils.Usage: "1m20s", + ev := &engine.ArgsGetSuppliers{ + CGREvent: utils.CGREvent{ + Tenant: "cgrates.org", + ID: "testV1SplSGetLeastCostSuppliers", + Event: map[string]interface{}{ + utils.Account: "1001", + utils.Subject: "1001", + utils.Destination: "1002", + utils.AnswerTime: time.Date(2017, 12, 1, 14, 25, 0, 0, time.UTC), + utils.Usage: "1m20s", + }, }, } eSpls := engine.SortedSuppliers{ diff --git a/engine/attributes_test.go b/engine/attributes_test.go index 3103a4b44..acd7f9c52 100644 --- a/engine/attributes_test.go +++ b/engine/attributes_test.go @@ -28,6 +28,7 @@ import ( var ( atrPs AttributeProfiles + sev *utils.CGREvent srv AttributeService dmAtr *DataManager ) diff --git a/engine/suppliers.go b/engine/suppliers.go index a912ae1c6..6df50a000 100644 --- a/engine/suppliers.go +++ b/engine/suppliers.go @@ -273,9 +273,9 @@ func (spS *SupplierService) resourceUsage(resIDs []string) (tUsage float64, err // supliersForEvent will return the list of valid supplier IDs // for event based on filters and sorting algorithms -func (spS *SupplierService) sortedSuppliersForEvent(ev *utils.CGREvent) (sortedSuppls *SortedSuppliers, err error) { +func (spS *SupplierService) sortedSuppliersForEvent(args *ArgsGetSuppliers) (sortedSuppls *SortedSuppliers, err error) { var suppPrfls SupplierProfiles - if suppPrfls, err = spS.matchingSupplierProfilesForEvent(ev); err != nil { + if suppPrfls, err = spS.matchingSupplierProfilesForEvent(&args.CGREvent); err != nil { return } else if len(suppPrfls) == 0 { return nil, utils.ErrNotFound @@ -284,8 +284,8 @@ func (spS *SupplierService) sortedSuppliersForEvent(ev *utils.CGREvent) (sortedS var spls []*Supplier for _, s := range splPrfl.Suppliers { if len(s.FilterIDs) != 0 { // filters should be applied, check them here - if pass, err := spS.filterS.PassFiltersForEvent(ev.Tenant, - ev.Event, s.FilterIDs); err != nil { + if pass, err := spS.filterS.PassFiltersForEvent(args.Tenant, + args.Event, s.FilterIDs); err != nil { return nil, err } else if !pass { continue @@ -293,12 +293,31 @@ func (spS *SupplierService) sortedSuppliersForEvent(ev *utils.CGREvent) (sortedS } spls = append(spls, s) } - return spS.sorter.SortSuppliers(splPrfl.ID, splPrfl.Sorting, spls, ev) + sortedSuppliers, err := spS.sorter.SortSuppliers(splPrfl.ID, splPrfl.Sorting, spls, &args.CGREvent) + if err != nil { + return nil, err + } + if args.Paginator.Offset != nil { + if *args.Paginator.Offset <= len(sortedSuppliers.SortedSuppliers) { + sortedSuppliers.SortedSuppliers = sortedSuppliers.SortedSuppliers[*args.Paginator.Offset:] + } + } + if args.Paginator.Limit != nil { + if *args.Paginator.Limit <= len(sortedSuppliers.SortedSuppliers) { + sortedSuppliers.SortedSuppliers = sortedSuppliers.SortedSuppliers[:*args.Paginator.Limit] + } + } + return sortedSuppliers, nil +} + +type ArgsGetSuppliers struct { + utils.CGREvent + utils.Paginator } // V1GetSuppliersForEvent returns the list of valid supplier IDs -func (spS *SupplierService) V1GetSuppliers(args *utils.CGREvent, reply *SortedSuppliers) (err error) { - if missing := utils.MissingStructFields(args, []string{"Tenant", "ID"}); len(missing) != 0 { +func (spS *SupplierService) V1GetSuppliers(args *ArgsGetSuppliers, reply *SortedSuppliers) (err error) { + if missing := utils.MissingStructFields(&args.CGREvent, []string{"Tenant", "ID"}); len(missing) != 0 { return utils.NewErrMandatoryIeMissing(missing...) } sSps, err := spS.sortedSuppliersForEvent(args) diff --git a/engine/suppliers_test.go b/engine/suppliers_test.go index 3d47083c5..8c0d3ec02 100644 --- a/engine/suppliers_test.go +++ b/engine/suppliers_test.go @@ -28,7 +28,7 @@ import ( var ( splserv SupplierService - sev *utils.CGREvent + argPagEv *ArgsGetSuppliers dmspl *DataManager sprsmatch SupplierProfiles ) @@ -193,16 +193,18 @@ func TestSuppliersPopulateSupplierService(t *testing.T) { sorter: ssd, } ssd[utils.MetaLeastCost] = NewLeastCostSorter(&splserv) - sev = &utils.CGREvent{ - Tenant: "cgrates.org", - ID: "utils.CGREvent1", - Event: map[string]interface{}{ - "supplierprofile1": "Supplier", - "supplierprofile2": "Supplier", - utils.AnswerTime: time.Date(2014, 7, 14, 14, 30, 0, 0, time.UTC).Local(), - "UsageInterval": "1s", - "PddInterval": "1s", - "Weight": "20.0", + argPagEv = &ArgsGetSuppliers{ + CGREvent: utils.CGREvent{ + Tenant: "cgrates.org", + ID: "utils.CGREvent1", + Event: map[string]interface{}{ + "supplierprofile1": "Supplier", + "supplierprofile2": "Supplier", + utils.AnswerTime: time.Date(2014, 7, 14, 14, 30, 0, 0, time.UTC).Local(), + "UsageInterval": "1s", + "PddInterval": "1s", + "Weight": "20.0", + }, }, } sprsmatch = SupplierProfiles{ @@ -291,7 +293,7 @@ func TestSuppliersPopulateSupplierService(t *testing.T) { } func TestSuppliersmatchingSupplierProfilesForEvent(t *testing.T) { - sprf, err := splserv.matchingSupplierProfilesForEvent(sev) + sprf, err := splserv.matchingSupplierProfilesForEvent(&argPagEv.CGREvent) if err != nil { t.Errorf("Error: %+v", err) } @@ -330,7 +332,7 @@ func TestSuppliersSortedForEvent(t *testing.T) { }, }, } - sprf, err := splserv.sortedSuppliersForEvent(sev) + sprf, err := splserv.sortedSuppliersForEvent(argPagEv) if err != nil { t.Errorf("Error: %+v", err) } @@ -338,3 +340,89 @@ func TestSuppliersSortedForEvent(t *testing.T) { t.Errorf("Expecting: %+v, received: %+v", eFirstSupplierProfile, sprf) } } + +func TestSuppliersSortedForEventWithLimit(t *testing.T) { + eFirstSupplierProfile := &SortedSuppliers{ + ProfileID: "supplierprofile2", + Sorting: utils.MetaWeight, + SortedSuppliers: []*SortedSupplier{ + &SortedSupplier{ + SupplierID: "supplier1", + SortingData: map[string]interface{}{ + "Weight": 30.0, + }, + SupplierParameters: "param1", + }, + &SortedSupplier{ + SupplierID: "supplier2", + SortingData: map[string]interface{}{ + "Weight": 20.0, + }, + SupplierParameters: "param2", + }, + }, + } + argPagEv.Paginator = utils.Paginator{ + Limit: utils.IntPointer(2), + } + sprf, err := splserv.sortedSuppliersForEvent(argPagEv) + if err != nil { + t.Errorf("Error: %+v", err) + } + if !reflect.DeepEqual(eFirstSupplierProfile, sprf) { + t.Errorf("Expecting: %+v, received: %+v", eFirstSupplierProfile, sprf) + } +} + +func TestSuppliersSortedForEventWithOffset(t *testing.T) { + eFirstSupplierProfile := &SortedSuppliers{ + ProfileID: "supplierprofile2", + Sorting: utils.MetaWeight, + SortedSuppliers: []*SortedSupplier{ + &SortedSupplier{ + SupplierID: "supplier3", + SortingData: map[string]interface{}{ + "Weight": 10.0, + }, + SupplierParameters: "param3", + }, + }, + } + argPagEv.Paginator = utils.Paginator{ + Offset: utils.IntPointer(2), + } + sprf, err := splserv.sortedSuppliersForEvent(argPagEv) + if err != nil { + t.Errorf("Error: %+v", err) + } + if !reflect.DeepEqual(eFirstSupplierProfile, sprf) { + t.Errorf("Expecting: %+v,received: %+v", utils.ToJSON(eFirstSupplierProfile), utils.ToJSON(sprf)) + } +} + +func TestSuppliersSortedForEventWithLimitAndOffset(t *testing.T) { + eFirstSupplierProfile := &SortedSuppliers{ + ProfileID: "supplierprofile2", + Sorting: utils.MetaWeight, + SortedSuppliers: []*SortedSupplier{ + &SortedSupplier{ + SupplierID: "supplier2", + SortingData: map[string]interface{}{ + "Weight": 20.0, + }, + SupplierParameters: "param2", + }, + }, + } + argPagEv.Paginator = utils.Paginator{ + Limit: utils.IntPointer(1), + Offset: utils.IntPointer(1), + } + sprf, err := splserv.sortedSuppliersForEvent(argPagEv) + if err != nil { + t.Errorf("Error: %+v", err) + } + if !reflect.DeepEqual(eFirstSupplierProfile, sprf) { + t.Errorf("Expecting: %+v,received: %+v", utils.ToJSON(eFirstSupplierProfile), utils.ToJSON(sprf)) + } +} diff --git a/sessionmanager/smgeneric.go b/sessionmanager/smgeneric.go index 095cb9633..d330bf225 100644 --- a/sessionmanager/smgeneric.go +++ b/sessionmanager/smgeneric.go @@ -1356,8 +1356,12 @@ func (smg *SMGeneric) BiRPCv1AuthorizeEvent(clnt rpcclient.RpcClientConnection, return utils.NewErrNotConnected(utils.SupplierS) } var splsReply engine.SortedSuppliers + sArgs := &engine.ArgsGetSuppliers{ + CGREvent: args.CGREvent, + Paginator: args.Paginator, + } if err = smg.splS.Call(utils.SupplierSv1GetSuppliers, - args.CGREvent, &splsReply); err != nil { + sArgs, &splsReply); err != nil { return utils.NewErrSupplierS(err) } if splsReply.SortedSuppliers != nil {