From 0a7529f114f3d5f01373ccceace42cc56b065724 Mon Sep 17 00:00:00 2001 From: Tripon Alexandru-Ionut Date: Thu, 18 Apr 2019 13:41:28 +0300 Subject: [PATCH 1/3] Added GetSuppliersForEvent --- apier/v1/dispatcher.go | 6 ++ apier/v1/dispatcher_interface.go | 1 + apier/v1/suppliers.go | 6 ++ apier/v1/suppliers_it_test.go | 66 +++++++++++++++++++ console/supplier_for_event.go | 65 +++++++++++++++++++ data/tariffplans/dispatchers/Attributes.csv | 2 +- dispatchers/suppliers.go | 16 +++++ dispatchers/suppliers_it_test.go | 70 +++++++++++++++++++++ engine/suppliers.go | 22 ++++++- utils/consts.go | 13 ++-- 10 files changed, 259 insertions(+), 8 deletions(-) create mode 100644 console/supplier_for_event.go diff --git a/apier/v1/dispatcher.go b/apier/v1/dispatcher.go index 9a1cd4869..eda1d6b5b 100755 --- a/apier/v1/dispatcher.go +++ b/apier/v1/dispatcher.go @@ -337,6 +337,12 @@ func (dSup *DispatcherSupplierSv1) GetSuppliers(args *engine.ArgsGetSuppliers, return dSup.dSup.SupplierSv1GetSuppliers(args, reply) } +// GetSuppliersProfiles returns a list of suppliers profiles that match for Event +func (dSup *DispatcherSupplierSv1) GetSupplierForEvent(args *utils.CGREventWithArgDispatcher, + reply *engine.SupplierProfile) error { + return dSup.dSup.SupplierSv1GetSupplierForEvent(args, reply) +} + func NewDispatcherAttributeSv1(dps *dispatchers.DispatcherService) *DispatcherAttributeSv1 { return &DispatcherAttributeSv1{dA: dps} } diff --git a/apier/v1/dispatcher_interface.go b/apier/v1/dispatcher_interface.go index 003ae677b..e0c8cfc5e 100644 --- a/apier/v1/dispatcher_interface.go +++ b/apier/v1/dispatcher_interface.go @@ -55,6 +55,7 @@ type ResourceSv1Interface interface { type SupplierSv1Interface interface { GetSuppliers(args *engine.ArgsGetSuppliers, reply *engine.SortedSuppliers) error + GetSupplierForEvent(args *utils.CGREventWithArgDispatcher, reply *engine.SupplierProfile) error Ping(ign *utils.CGREventWithArgDispatcher, reply *string) error } diff --git a/apier/v1/suppliers.go b/apier/v1/suppliers.go index 232a474db..201ce5a73 100644 --- a/apier/v1/suppliers.go +++ b/apier/v1/suppliers.go @@ -133,6 +133,12 @@ func (splv1 *SupplierSv1) GetSuppliers(args *engine.ArgsGetSuppliers, return splv1.splS.V1GetSuppliers(args, reply) } +// GetSuppliersProfiles returns a list of suppliers profiles that match for Event +func (splv1 *SupplierSv1) GetSupplierForEvent(args *utils.CGREventWithArgDispatcher, + reply *engine.SupplierProfile) error { + return splv1.splS.V1GetSupplierForEvent(args, reply) +} + func (splv1 *SupplierSv1) Ping(ign *utils.CGREventWithArgDispatcher, reply *string) error { *reply = utils.Pong return nil diff --git a/apier/v1/suppliers_it_test.go b/apier/v1/suppliers_it_test.go index ad3f00fbc..93847282e 100644 --- a/apier/v1/suppliers_it_test.go +++ b/apier/v1/suppliers_it_test.go @@ -24,6 +24,7 @@ import ( "net/rpc/jsonrpc" "path" "reflect" + "sort" "testing" "time" @@ -65,6 +66,7 @@ var sTestsSupplierSV1 = []func(t *testing.T){ testV1SplSGetSupplierProfileIDs, testV1SplSUpdateSupplierProfiles, testV1SplSRemSupplierProfiles, + testV1SplSGetSupplierForEvent, testV1SplSupplierPing, testV1SplSStopEngine, } @@ -878,6 +880,70 @@ func testV1SplSupplierPing(t *testing.T) { } } +func testV1SplSGetSupplierForEvent(t *testing.T) { + ev := &utils.CGREventWithArgDispatcher{ + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "testV1SplSGetHighestCostSuppliers", + Event: map[string]interface{}{ + utils.Account: "1000", + utils.Destination: "1001", + utils.SetupTime: "*now", + "Subject": "TEST", + }, + }, + } + expected := engine.SupplierProfile{ + Tenant: "cgrates.org", + ID: "SPL_LCR", + FilterIDs: []string{"FLTR_TEST"}, + ActivationInterval: &utils.ActivationInterval{ + ActivationTime: time.Date(2017, 11, 27, 00, 00, 00, 00, time.UTC), + }, + Sorting: "*least_cost", + SortingParameters: []string{}, + Suppliers: []*engine.Supplier{ + &engine.Supplier{ + ID: "supplier_1", + FilterIDs: nil, + AccountIDs: nil, + RatingPlanIDs: []string{"RP_TEST_1"}, + ResourceIDs: nil, + StatIDs: nil, + Weight: 10, + Blocker: false, + SupplierParameters: "", + }, + &engine.Supplier{ + ID: "supplier_2", + FilterIDs: nil, + AccountIDs: nil, + RatingPlanIDs: []string{"RP_TEST_2"}, + ResourceIDs: nil, + StatIDs: nil, + Weight: 0, + Blocker: false, + SupplierParameters: "", + }, + }, + Weight: 50, + } + var supProf engine.SupplierProfile + if err := splSv1Rpc.Call(utils.SupplierSv1GetSupplierForEvent, + ev, &supProf); err != nil { + t.Fatal(err) + } + sort.Slice(expected.Suppliers, func(i, j int) bool { + return supProf.Suppliers[i].Weight < supProf.Suppliers[j].Weight + }) + sort.Slice(supProf.Suppliers, func(i, j int) bool { + return supProf.Suppliers[i].Weight < supProf.Suppliers[j].Weight + }) + if !reflect.DeepEqual(expected, supProf) { + t.Errorf("Expected: %s ,received: %s", utils.ToJSON(expected), utils.ToJSON(supProf)) + } +} + func testV1SplSStopEngine(t *testing.T) { if err := engine.KillEngine(100); err != nil { t.Error(err) diff --git a/console/supplier_for_event.go b/console/supplier_for_event.go new file mode 100644 index 000000000..1ca84f1a2 --- /dev/null +++ b/console/supplier_for_event.go @@ -0,0 +1,65 @@ +/* +Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments +Copyright (C) ITsysCOM GmbH + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +package console + +import ( + "github.com/cgrates/cgrates/engine" + "github.com/cgrates/cgrates/utils" +) + +func init() { + c := &CmdGetSupplierForEvent{ + name: "supplier_for_event", + rpcMethod: utils.SupplierSv1GetSupplierForEvent, + rpcParams: &utils.CGREventWithArgDispatcher{}, + } + commands[c.Name()] = c + c.CommandExecuter = &CommandExecuter{c} +} + +type CmdGetSupplierForEvent struct { + name string + rpcMethod string + rpcParams *utils.CGREventWithArgDispatcher + *CommandExecuter +} + +func (self *CmdGetSupplierForEvent) Name() string { + return self.name +} + +func (self *CmdGetSupplierForEvent) RpcMethod() string { + return self.rpcMethod +} + +func (self *CmdGetSupplierForEvent) RpcParams(reset bool) interface{} { + if reset || self.rpcParams == nil { + self.rpcParams = &utils.CGREventWithArgDispatcher{} + } + return self.rpcParams +} + +func (self *CmdGetSupplierForEvent) PostprocessRpcParams() error { + return nil +} + +func (self *CmdGetSupplierForEvent) RpcResult() interface{} { + atr := engine.SupplierProfile{} + return &atr +} diff --git a/data/tariffplans/dispatchers/Attributes.csv b/data/tariffplans/dispatchers/Attributes.csv index 8f3d64434..2da5c1854 100644 --- a/data/tariffplans/dispatchers/Attributes.csv +++ b/data/tariffplans/dispatchers/Attributes.csv @@ -6,7 +6,7 @@ cgrates.org,ATTR_API_ATTR_FAKE_AUTH,*auth,*string:~APIKey:12345,,,APIMethods,*co cgrates.org,ATTR_API_ATTR_AUTH,*auth,*string:~APIKey:attr12345,,,APIMethods,*constant,AttributeSv1.Ping&AttributeSv1.GetAttributeForEvent&AttributeSv1.ProcessEvent,false,20 cgrates.org,ATTR_API_CHRG_AUTH,*auth,*string:~APIKey:chrg12345,,,APIMethods,*constant,ChargerSv1.Ping&ChargerSv1.GetChargersForEvent&ChargerSv1.ProcessEvent,false,20 cgrates.org,ATTR_API_THR_AUTH,*auth,*string:~APIKey:thr12345,,,APIMethods,*constant,ThresholdSv1.Ping&ThresholdSv1.GetThresholdsForEvent&ThresholdSv1.ProcessEvent&ThresholdSv1.GetThreshold&ThresholdSv1.GetThresholdIDs,false,20 -cgrates.org,ATTR_API_SUP_AUTH,*auth,*string:~APIKey:sup12345,,,APIMethods,*constant,SupplierSv1.Ping&SupplierSv1.GetSuppliers,false,20 +cgrates.org,ATTR_API_SUP_AUTH,*auth,*string:~APIKey:sup12345,,,APIMethods,*constant,SupplierSv1.Ping&SupplierSv1.GetSuppliers&SupplierSv1.GetSupplierForEvent,false,20 cgrates.org,ATTR_API_STAT_AUTH,*auth,*string:~APIKey:stat12345,,,APIMethods,*constant,StatSv1.Ping&StatSv1.GetStatQueuesForEvent&StatSv1.GetQueueStringMetrics&StatSv1.ProcessEvent&StatSv1.GetQueueIDs&StatSv1.GetQueueFloatMetrics,false,20 cgrates.org,ATTR_API_RES_AUTH,*auth,*string:~APIKey:res12345,,,APIMethods,*constant,ResourceSv1.Ping&ResourceSv1.GetResourcesForEvent&ResourceSv1.AuthorizeResources&ResourceSv1.AllocateResources&ResourceSv1.ReleaseResources,false,20 cgrates.org,ATTR_API_SES_AUTH,*auth,*string:~APIKey:ses12345,,,APIMethods,*constant,SessionSv1.Ping&SessionSv1.AuthorizeEvent&SessionSv1.AuthorizeEventWithDigest&SessionSv1.InitiateSession&SessionSv1.InitiateSessionWithDigest&SessionSv1.UpdateSession&SessionSv1.SyncSessions&SessionSv1.TerminateSession&SessionSv1.ProcessCDR&SessionSv1.ProcessEvent&SessionSv1.GetActiveSessions&SessionSv1.GetActiveSessionsCount&SessionSv1.ForceDisconnect&SessionSv1.GetPassiveSessions&SessionSv1.GetPassiveSessionsCount&SessionSv1.ReplicateSessions&SessionSv1.SetPassiveSession,false,20 diff --git a/dispatchers/suppliers.go b/dispatchers/suppliers.go index 54f07db89..a97cbea89 100755 --- a/dispatchers/suppliers.go +++ b/dispatchers/suppliers.go @@ -53,3 +53,19 @@ func (dS *DispatcherService) SupplierSv1GetSuppliers(args *engine.ArgsGetSupplie return dS.Dispatch(&args.CGREvent, utils.MetaSuppliers, args.RouteID, utils.SupplierSv1GetSuppliers, args, reply) } + +func (dS *DispatcherService) SupplierSv1GetSupplierForEvent(args *utils.CGREventWithArgDispatcher, + reply *engine.SupplierProfile) (err error) { + if args.ArgDispatcher == nil { + return utils.NewErrMandatoryIeMissing("ArgDispatcher") + } + if dS.attrS != nil { + if err = dS.authorize(utils.SupplierSv1GetSupplierForEvent, + args.CGREvent.Tenant, + args.APIKey, args.CGREvent.Time); err != nil { + return + } + } + return dS.Dispatch(args.CGREvent, utils.MetaSuppliers, args.RouteID, + utils.SupplierSv1GetSupplierForEvent, args, reply) +} diff --git a/dispatchers/suppliers_it_test.go b/dispatchers/suppliers_it_test.go index f4e91fb08..f0bd1b249 100755 --- a/dispatchers/suppliers_it_test.go +++ b/dispatchers/suppliers_it_test.go @@ -22,6 +22,7 @@ package dispatchers import ( "reflect" + "sort" "testing" "time" @@ -37,6 +38,7 @@ var sTestsDspSup = []func(t *testing.T){ testDspSupPing, testDspSupTestAuthKey, testDspSupTestAuthKey2, + testDspSupGetSupplierForEvent, } //Test start here @@ -322,3 +324,71 @@ func testDspSupGetSupRoundRobin(t *testing.T) { t.Errorf("Expecting : %+v, received: %+v", utils.ToJSON(eRpl), utils.ToJSON(rpl)) } } + +func testDspSupGetSupplierForEvent(t *testing.T) { + ev := &utils.CGREventWithArgDispatcher{ + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "testV1SplSGetHighestCostSuppliers", + Event: map[string]interface{}{ + utils.Account: "1002", + utils.Subject: "1002", + utils.Destination: "1001", + utils.SetupTime: time.Date(2017, 12, 1, 14, 25, 0, 0, time.UTC), + utils.Usage: "1m20s", + }, + }, + ArgDispatcher: &utils.ArgDispatcher{ + APIKey: utils.StringPointer("sup12345"), + }, + } + expected := engine.SupplierProfile{ + Tenant: "cgrates.org", + ID: "SPL_ACNT_1002", + FilterIDs: []string{"FLTR_ACNT_1002"}, + ActivationInterval: &utils.ActivationInterval{ + ActivationTime: time.Date(2017, 11, 27, 00, 00, 00, 00, time.UTC), + }, + Sorting: "*least_cost", + SortingParameters: []string{}, + Suppliers: []*engine.Supplier{ + &engine.Supplier{ + ID: "supplier1", + FilterIDs: nil, + AccountIDs: nil, + RatingPlanIDs: []string{"RP_1002_LOW"}, + ResourceIDs: nil, + StatIDs: nil, + Weight: 10, + Blocker: false, + SupplierParameters: "", + }, + &engine.Supplier{ + ID: "supplier2", + FilterIDs: nil, + AccountIDs: nil, + RatingPlanIDs: []string{"RP_1002"}, + ResourceIDs: nil, + StatIDs: nil, + Weight: 20, + Blocker: false, + SupplierParameters: "", + }, + }, + Weight: 10, + } + var supProf engine.SupplierProfile + if err := dispEngine.RCP.Call(utils.SupplierSv1GetSupplierForEvent, + ev, &supProf); err != nil { + t.Fatal(err) + } + sort.Slice(expected.Suppliers, func(i, j int) bool { + return supProf.Suppliers[i].Weight < supProf.Suppliers[j].Weight + }) + sort.Slice(supProf.Suppliers, func(i, j int) bool { + return supProf.Suppliers[i].Weight < supProf.Suppliers[j].Weight + }) + if !reflect.DeepEqual(expected, supProf) { + t.Errorf("Expected: %s ,received: %s", utils.ToJSON(expected), utils.ToJSON(supProf)) + } +} diff --git a/engine/suppliers.go b/engine/suppliers.go index 7462e652e..c80eff2f0 100644 --- a/engine/suppliers.go +++ b/engine/suppliers.go @@ -469,7 +469,7 @@ type optsGetSuppliers struct { sortingParameters []string //used for QOS strategy } -// V1GetSuppliersForEvent returns the list of valid supplier IDs +// V1GetSupplierForEvent returns the list of valid supplier IDs 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...) @@ -500,3 +500,23 @@ func (spS *SupplierService) V1GetSuppliers(args *ArgsGetSuppliers, reply *Sorted *reply = *sSps return } + +// V1GetSupplierProfiles returns the list of valid supplier profiles +func (spS *SupplierService) V1GetSupplierForEvent(args *utils.CGREventWithArgDispatcher, reply *SupplierProfile) (err error) { + if missing := utils.MissingStructFields(args.CGREvent, []string{"Tenant", "ID"}); len(missing) != 0 { + return utils.NewErrMandatoryIeMissing(missing...) + } else if args.CGREvent.Event == nil { + return utils.NewErrMandatoryIeMissing("Event") + } + sPs, err := spS.matchingSupplierProfilesForEvent(args.CGREvent) + if err != nil { + if err != utils.ErrNotFound { + err = utils.NewErrServerError(err) + } + return err + } + if sPs != nil { + *reply = *sPs + } + return +} diff --git a/utils/consts.go b/utils/consts.go index 7fc36cd44..a679a31b0 100755 --- a/utils/consts.go +++ b/utils/consts.go @@ -754,12 +754,13 @@ const ( // SupplierS APIs const ( - SupplierSv1GetSuppliers = "SupplierSv1.GetSuppliers" - SupplierSv1Ping = "SupplierSv1.Ping" - ApierV1GetSupplierProfile = "ApierV1.GetSupplierProfile" - ApierV1GetSupplierProfileIDs = "ApierV1.GetSupplierProfileIDs" - ApierV1RemoveSupplierProfile = "ApierV1.RemoveSupplierProfile" - ApierV1SetSupplierProfile = "ApierV1.SetSupplierProfile" + SupplierSv1GetSuppliers = "SupplierSv1.GetSuppliers" + SupplierSv1GetSupplierForEvent = "SupplierSv1.GetSupplierForEvent" + SupplierSv1Ping = "SupplierSv1.Ping" + ApierV1GetSupplierProfile = "ApierV1.GetSupplierProfile" + ApierV1GetSupplierProfileIDs = "ApierV1.GetSupplierProfileIDs" + ApierV1RemoveSupplierProfile = "ApierV1.RemoveSupplierProfile" + ApierV1SetSupplierProfile = "ApierV1.SetSupplierProfile" ) // AttributeS APIs From 0f9ad87d509b972d28bdf31876926a1119bdee9f Mon Sep 17 00:00:00 2001 From: Tripon Alexandru-Ionut Date: Thu, 18 Apr 2019 15:04:10 +0300 Subject: [PATCH 2/3] Updated GetSupplierProfilesForEvent --- apier/v1/dispatcher.go | 6 ++-- apier/v1/dispatcher_interface.go | 2 +- apier/v1/suppliers.go | 6 ++-- apier/v1/suppliers_it_test.go | 12 +++---- console/supplier_for_event.go | 6 ++-- data/tariffplans/dispatchers/Attributes.csv | 2 +- dispatchers/suppliers.go | 8 ++--- dispatchers/suppliers_it_test.go | 12 +++---- engine/suppliers.go | 39 ++++++++++++++------- engine/suppliers_test.go | 36 +++++++++---------- utils/consts.go | 14 ++++---- 11 files changed, 78 insertions(+), 65 deletions(-) diff --git a/apier/v1/dispatcher.go b/apier/v1/dispatcher.go index eda1d6b5b..9811c7033 100755 --- a/apier/v1/dispatcher.go +++ b/apier/v1/dispatcher.go @@ -338,9 +338,9 @@ func (dSup *DispatcherSupplierSv1) GetSuppliers(args *engine.ArgsGetSuppliers, } // GetSuppliersProfiles returns a list of suppliers profiles that match for Event -func (dSup *DispatcherSupplierSv1) GetSupplierForEvent(args *utils.CGREventWithArgDispatcher, - reply *engine.SupplierProfile) error { - return dSup.dSup.SupplierSv1GetSupplierForEvent(args, reply) +func (dSup *DispatcherSupplierSv1) GetSupplierProfilesForEvent(args *utils.CGREventWithArgDispatcher, + reply *[]*engine.SupplierProfile) error { + return dSup.dSup.SupplierSv1GetSupplierProfilesForEvent(args, reply) } func NewDispatcherAttributeSv1(dps *dispatchers.DispatcherService) *DispatcherAttributeSv1 { diff --git a/apier/v1/dispatcher_interface.go b/apier/v1/dispatcher_interface.go index e0c8cfc5e..4b22b69d5 100644 --- a/apier/v1/dispatcher_interface.go +++ b/apier/v1/dispatcher_interface.go @@ -55,7 +55,7 @@ type ResourceSv1Interface interface { type SupplierSv1Interface interface { GetSuppliers(args *engine.ArgsGetSuppliers, reply *engine.SortedSuppliers) error - GetSupplierForEvent(args *utils.CGREventWithArgDispatcher, reply *engine.SupplierProfile) error + GetSupplierProfilesForEvent(args *utils.CGREventWithArgDispatcher, reply *[]*engine.SupplierProfile) error Ping(ign *utils.CGREventWithArgDispatcher, reply *string) error } diff --git a/apier/v1/suppliers.go b/apier/v1/suppliers.go index 201ce5a73..533bdbf8c 100644 --- a/apier/v1/suppliers.go +++ b/apier/v1/suppliers.go @@ -134,9 +134,9 @@ func (splv1 *SupplierSv1) GetSuppliers(args *engine.ArgsGetSuppliers, } // GetSuppliersProfiles returns a list of suppliers profiles that match for Event -func (splv1 *SupplierSv1) GetSupplierForEvent(args *utils.CGREventWithArgDispatcher, - reply *engine.SupplierProfile) error { - return splv1.splS.V1GetSupplierForEvent(args, reply) +func (splv1 *SupplierSv1) GetSupplierProfilesForEvent(args *utils.CGREventWithArgDispatcher, + reply *[]*engine.SupplierProfile) error { + return splv1.splS.V1GetSupplierProfilesForEvent(args, reply) } func (splv1 *SupplierSv1) Ping(ign *utils.CGREventWithArgDispatcher, reply *string) error { diff --git a/apier/v1/suppliers_it_test.go b/apier/v1/suppliers_it_test.go index 93847282e..a08516100 100644 --- a/apier/v1/suppliers_it_test.go +++ b/apier/v1/suppliers_it_test.go @@ -928,18 +928,18 @@ func testV1SplSGetSupplierForEvent(t *testing.T) { }, Weight: 50, } - var supProf engine.SupplierProfile - if err := splSv1Rpc.Call(utils.SupplierSv1GetSupplierForEvent, + var supProf []*engine.SupplierProfile + if err := splSv1Rpc.Call(utils.SupplierSv1GetSupplierProfilesForEvent, ev, &supProf); err != nil { t.Fatal(err) } sort.Slice(expected.Suppliers, func(i, j int) bool { - return supProf.Suppliers[i].Weight < supProf.Suppliers[j].Weight + return expected.Suppliers[i].Weight < expected.Suppliers[j].Weight }) - sort.Slice(supProf.Suppliers, func(i, j int) bool { - return supProf.Suppliers[i].Weight < supProf.Suppliers[j].Weight + sort.Slice(supProf[0].Suppliers, func(i, j int) bool { + return supProf[0].Suppliers[i].Weight < supProf[0].Suppliers[j].Weight }) - if !reflect.DeepEqual(expected, supProf) { + if !reflect.DeepEqual(expected, *supProf[0]) { t.Errorf("Expected: %s ,received: %s", utils.ToJSON(expected), utils.ToJSON(supProf)) } } diff --git a/console/supplier_for_event.go b/console/supplier_for_event.go index 1ca84f1a2..ee5a63240 100644 --- a/console/supplier_for_event.go +++ b/console/supplier_for_event.go @@ -25,8 +25,8 @@ import ( func init() { c := &CmdGetSupplierForEvent{ - name: "supplier_for_event", - rpcMethod: utils.SupplierSv1GetSupplierForEvent, + name: "supplier_profiles_for_event", + rpcMethod: utils.SupplierSv1GetSupplierProfilesForEvent, rpcParams: &utils.CGREventWithArgDispatcher{}, } commands[c.Name()] = c @@ -60,6 +60,6 @@ func (self *CmdGetSupplierForEvent) PostprocessRpcParams() error { } func (self *CmdGetSupplierForEvent) RpcResult() interface{} { - atr := engine.SupplierProfile{} + atr := []*engine.SupplierProfile{} return &atr } diff --git a/data/tariffplans/dispatchers/Attributes.csv b/data/tariffplans/dispatchers/Attributes.csv index 2da5c1854..9b49c361e 100644 --- a/data/tariffplans/dispatchers/Attributes.csv +++ b/data/tariffplans/dispatchers/Attributes.csv @@ -6,7 +6,7 @@ cgrates.org,ATTR_API_ATTR_FAKE_AUTH,*auth,*string:~APIKey:12345,,,APIMethods,*co cgrates.org,ATTR_API_ATTR_AUTH,*auth,*string:~APIKey:attr12345,,,APIMethods,*constant,AttributeSv1.Ping&AttributeSv1.GetAttributeForEvent&AttributeSv1.ProcessEvent,false,20 cgrates.org,ATTR_API_CHRG_AUTH,*auth,*string:~APIKey:chrg12345,,,APIMethods,*constant,ChargerSv1.Ping&ChargerSv1.GetChargersForEvent&ChargerSv1.ProcessEvent,false,20 cgrates.org,ATTR_API_THR_AUTH,*auth,*string:~APIKey:thr12345,,,APIMethods,*constant,ThresholdSv1.Ping&ThresholdSv1.GetThresholdsForEvent&ThresholdSv1.ProcessEvent&ThresholdSv1.GetThreshold&ThresholdSv1.GetThresholdIDs,false,20 -cgrates.org,ATTR_API_SUP_AUTH,*auth,*string:~APIKey:sup12345,,,APIMethods,*constant,SupplierSv1.Ping&SupplierSv1.GetSuppliers&SupplierSv1.GetSupplierForEvent,false,20 +cgrates.org,ATTR_API_SUP_AUTH,*auth,*string:~APIKey:sup12345,,,APIMethods,*constant,SupplierSv1.Ping&SupplierSv1.GetSuppliers&SupplierSv1.GetSupplierProfilesForEvent,false,20 cgrates.org,ATTR_API_STAT_AUTH,*auth,*string:~APIKey:stat12345,,,APIMethods,*constant,StatSv1.Ping&StatSv1.GetStatQueuesForEvent&StatSv1.GetQueueStringMetrics&StatSv1.ProcessEvent&StatSv1.GetQueueIDs&StatSv1.GetQueueFloatMetrics,false,20 cgrates.org,ATTR_API_RES_AUTH,*auth,*string:~APIKey:res12345,,,APIMethods,*constant,ResourceSv1.Ping&ResourceSv1.GetResourcesForEvent&ResourceSv1.AuthorizeResources&ResourceSv1.AllocateResources&ResourceSv1.ReleaseResources,false,20 cgrates.org,ATTR_API_SES_AUTH,*auth,*string:~APIKey:ses12345,,,APIMethods,*constant,SessionSv1.Ping&SessionSv1.AuthorizeEvent&SessionSv1.AuthorizeEventWithDigest&SessionSv1.InitiateSession&SessionSv1.InitiateSessionWithDigest&SessionSv1.UpdateSession&SessionSv1.SyncSessions&SessionSv1.TerminateSession&SessionSv1.ProcessCDR&SessionSv1.ProcessEvent&SessionSv1.GetActiveSessions&SessionSv1.GetActiveSessionsCount&SessionSv1.ForceDisconnect&SessionSv1.GetPassiveSessions&SessionSv1.GetPassiveSessionsCount&SessionSv1.ReplicateSessions&SessionSv1.SetPassiveSession,false,20 diff --git a/dispatchers/suppliers.go b/dispatchers/suppliers.go index a97cbea89..7482ff67f 100755 --- a/dispatchers/suppliers.go +++ b/dispatchers/suppliers.go @@ -54,18 +54,18 @@ func (dS *DispatcherService) SupplierSv1GetSuppliers(args *engine.ArgsGetSupplie utils.SupplierSv1GetSuppliers, args, reply) } -func (dS *DispatcherService) SupplierSv1GetSupplierForEvent(args *utils.CGREventWithArgDispatcher, - reply *engine.SupplierProfile) (err error) { +func (dS *DispatcherService) SupplierSv1GetSupplierProfilesForEvent(args *utils.CGREventWithArgDispatcher, + reply *[]*engine.SupplierProfile) (err error) { if args.ArgDispatcher == nil { return utils.NewErrMandatoryIeMissing("ArgDispatcher") } if dS.attrS != nil { - if err = dS.authorize(utils.SupplierSv1GetSupplierForEvent, + if err = dS.authorize(utils.SupplierSv1GetSupplierProfilesForEvent, args.CGREvent.Tenant, args.APIKey, args.CGREvent.Time); err != nil { return } } return dS.Dispatch(args.CGREvent, utils.MetaSuppliers, args.RouteID, - utils.SupplierSv1GetSupplierForEvent, args, reply) + utils.SupplierSv1GetSupplierProfilesForEvent, args, reply) } diff --git a/dispatchers/suppliers_it_test.go b/dispatchers/suppliers_it_test.go index f0bd1b249..89f1634c4 100755 --- a/dispatchers/suppliers_it_test.go +++ b/dispatchers/suppliers_it_test.go @@ -377,18 +377,18 @@ func testDspSupGetSupplierForEvent(t *testing.T) { }, Weight: 10, } - var supProf engine.SupplierProfile - if err := dispEngine.RCP.Call(utils.SupplierSv1GetSupplierForEvent, + var supProf []*engine.SupplierProfile + if err := dispEngine.RCP.Call(utils.SupplierSv1GetSupplierProfilesForEvent, ev, &supProf); err != nil { t.Fatal(err) } sort.Slice(expected.Suppliers, func(i, j int) bool { - return supProf.Suppliers[i].Weight < supProf.Suppliers[j].Weight + return expected.Suppliers[i].Weight < expected.Suppliers[j].Weight }) - sort.Slice(supProf.Suppliers, func(i, j int) bool { - return supProf.Suppliers[i].Weight < supProf.Suppliers[j].Weight + sort.Slice(supProf[0].Suppliers, func(i, j int) bool { + return supProf[0].Suppliers[i].Weight < supProf[0].Suppliers[j].Weight }) - if !reflect.DeepEqual(expected, supProf) { + if !reflect.DeepEqual(expected, *supProf[0]) { t.Errorf("Expected: %s ,received: %s", utils.ToJSON(expected), utils.ToJSON(supProf)) } } diff --git a/engine/suppliers.go b/engine/suppliers.go index c80eff2f0..f1347d418 100644 --- a/engine/suppliers.go +++ b/engine/suppliers.go @@ -125,12 +125,15 @@ func (spS *SupplierService) Shutdown() error { } // matchingSupplierProfilesForEvent returns ordered list of matching resources which are active by the time of the call -func (spS *SupplierService) matchingSupplierProfilesForEvent(ev *utils.CGREvent) (matchingLP *SupplierProfile, err error) { +func (spS *SupplierService) matchingSupplierProfilesForEvent(ev *utils.CGREvent, singleResult bool) (matchingSLP []*SupplierProfile, err error) { sPrflIDs, err := MatchingItemIDsForEvent(ev.Event, spS.stringIndexedFields, spS.prefixIndexedFields, spS.dm, utils.CacheSupplierFilterIndexes, ev.Tenant, spS.filterS.cfg.SupplierSCfg().IndexedSelects) if err != nil { return nil, err } + if singleResult { + matchingSLP = make([]*SupplierProfile, 1) + } for lpID := range sPrflIDs { splPrfl, err := spS.dm.GetSupplierProfile(ev.Tenant, lpID, true, true, utils.NonTransactional) if err != nil { @@ -149,12 +152,23 @@ func (spS *SupplierService) matchingSupplierProfilesForEvent(ev *utils.CGREvent) } else if !pass { continue } - if matchingLP == nil || matchingLP.Weight < splPrfl.Weight { - matchingLP = splPrfl + if singleResult { + if matchingSLP[0] == nil || matchingSLP[0].Weight < splPrfl.Weight { + matchingSLP[0] = splPrfl + } + } else { + matchingSLP = append(matchingSLP, splPrfl) } } - if matchingLP == nil { - return nil, utils.ErrNotFound + if singleResult { + if matchingSLP[0] == nil { + return nil, utils.ErrNotFound + } + } else { + if len(matchingSLP) == 0 { + return nil, utils.ErrNotFound + } + sort.Slice(matchingSLP, func(i, j int) bool { return matchingSLP[i].Weight < matchingSLP[j].Weight }) } return } @@ -402,10 +416,11 @@ func (spS *SupplierService) sortedSuppliersForEvent(args *ArgsGetSuppliers) (sor if _, has := args.CGREvent.Event[utils.Usage]; !has { args.CGREvent.Event[utils.Usage] = time.Duration(time.Minute) // make sure we have default set for Usage } - var splPrfl *SupplierProfile - if splPrfl, err = spS.matchingSupplierProfilesForEvent(&args.CGREvent); err != nil { + var splPrfls []*SupplierProfile + if splPrfls, err = spS.matchingSupplierProfilesForEvent(&args.CGREvent, true); err != nil { return } + splPrfl := splPrfls[0] extraOpts, err := args.asOptsGetSuppliers() // convert suppliers arguments into internal options used to limit data if err != nil { return nil, err @@ -469,7 +484,7 @@ type optsGetSuppliers struct { sortingParameters []string //used for QOS strategy } -// V1GetSupplierForEvent returns the list of valid supplier IDs +// V1GetSupplierProfilesForEvent returns the list of valid supplier IDs 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...) @@ -502,21 +517,19 @@ func (spS *SupplierService) V1GetSuppliers(args *ArgsGetSuppliers, reply *Sorted } // V1GetSupplierProfiles returns the list of valid supplier profiles -func (spS *SupplierService) V1GetSupplierForEvent(args *utils.CGREventWithArgDispatcher, reply *SupplierProfile) (err error) { +func (spS *SupplierService) V1GetSupplierProfilesForEvent(args *utils.CGREventWithArgDispatcher, reply *[]*SupplierProfile) (err error) { if missing := utils.MissingStructFields(args.CGREvent, []string{"Tenant", "ID"}); len(missing) != 0 { return utils.NewErrMandatoryIeMissing(missing...) } else if args.CGREvent.Event == nil { return utils.NewErrMandatoryIeMissing("Event") } - sPs, err := spS.matchingSupplierProfilesForEvent(args.CGREvent) + sPs, err := spS.matchingSupplierProfilesForEvent(args.CGREvent, false) if err != nil { if err != utils.ErrNotFound { err = utils.NewErrServerError(err) } return err } - if sPs != nil { - *reply = *sPs - } + *reply = sPs return } diff --git a/engine/suppliers_test.go b/engine/suppliers_test.go index 72e505a19..54a46d3b8 100644 --- a/engine/suppliers_test.go +++ b/engine/suppliers_test.go @@ -386,28 +386,28 @@ func TestSuppliersCache(t *testing.T) { } func TestSuppliersmatchingSupplierProfilesForEvent(t *testing.T) { - sprf, err := splService.matchingSupplierProfilesForEvent(&argsGetSuppliers[0].CGREvent) + sprf, err := splService.matchingSupplierProfilesForEvent(&argsGetSuppliers[0].CGREvent, true) if err != nil { t.Errorf("Error: %+v", err) } - if !reflect.DeepEqual(sppTest[0], sprf) { - t.Errorf("Expecting: %+v, received: %+v", sppTest[0], sprf) + if !reflect.DeepEqual(sppTest[0], sprf[0]) { + t.Errorf("Expecting: %+v, received: %+v", sppTest[0], sprf[0]) } - sprf, err = splService.matchingSupplierProfilesForEvent(&argsGetSuppliers[1].CGREvent) + sprf, err = splService.matchingSupplierProfilesForEvent(&argsGetSuppliers[1].CGREvent, true) if err != nil { t.Errorf("Error: %+v", err) } - if !reflect.DeepEqual(sppTest[1], sprf) { - t.Errorf("Expecting: %+v, received: %+v", sppTest[1], sprf) + if !reflect.DeepEqual(sppTest[1], sprf[0]) { + t.Errorf("Expecting: %+v, received: %+v", sppTest[1], sprf[0]) } - sprf, err = splService.matchingSupplierProfilesForEvent(&argsGetSuppliers[2].CGREvent) + sprf, err = splService.matchingSupplierProfilesForEvent(&argsGetSuppliers[2].CGREvent, true) if err != nil { t.Errorf("Error: %+v", err) } - if !reflect.DeepEqual(sppTest[2], sprf) { - t.Errorf("Expecting: %+v, received: %+v", sppTest[2], sprf) + if !reflect.DeepEqual(sppTest[2], sprf[0]) { + t.Errorf("Expecting: %+v, received: %+v", sppTest[2], sprf[0]) } } @@ -630,27 +630,27 @@ func TestSuppliersAsOptsGetSuppliersMaxCost(t *testing.T) { func TestSuppliersMatchWithIndexFalse(t *testing.T) { splService.filterS.cfg.SupplierSCfg().IndexedSelects = false - sprf, err := splService.matchingSupplierProfilesForEvent(&argsGetSuppliers[0].CGREvent) + sprf, err := splService.matchingSupplierProfilesForEvent(&argsGetSuppliers[0].CGREvent, true) if err != nil { t.Errorf("Error: %+v", err) } - if !reflect.DeepEqual(sppTest[0], sprf) { - t.Errorf("Expecting: %+v, received: %+v", sppTest[0], sprf) + if !reflect.DeepEqual(sppTest[0], sprf[0]) { + t.Errorf("Expecting: %+v, received: %+v", sppTest[0], sprf[0]) } - sprf, err = splService.matchingSupplierProfilesForEvent(&argsGetSuppliers[1].CGREvent) + sprf, err = splService.matchingSupplierProfilesForEvent(&argsGetSuppliers[1].CGREvent, true) if err != nil { t.Errorf("Error: %+v", err) } - if !reflect.DeepEqual(sppTest[1], sprf) { - t.Errorf("Expecting: %+v, received: %+v", sppTest[1], sprf) + if !reflect.DeepEqual(sppTest[1], sprf[0]) { + t.Errorf("Expecting: %+v, received: %+v", sppTest[1], sprf[0]) } - sprf, err = splService.matchingSupplierProfilesForEvent(&argsGetSuppliers[2].CGREvent) + sprf, err = splService.matchingSupplierProfilesForEvent(&argsGetSuppliers[2].CGREvent, true) if err != nil { t.Errorf("Error: %+v", err) } - if !reflect.DeepEqual(sppTest[2], sprf) { - t.Errorf("Expecting: %+v, received: %+v", sppTest[2], sprf) + if !reflect.DeepEqual(sppTest[2], sprf[0]) { + t.Errorf("Expecting: %+v, received: %+v", sppTest[2], sprf[0]) } } diff --git a/utils/consts.go b/utils/consts.go index a679a31b0..29cad2a56 100755 --- a/utils/consts.go +++ b/utils/consts.go @@ -754,13 +754,13 @@ const ( // SupplierS APIs const ( - SupplierSv1GetSuppliers = "SupplierSv1.GetSuppliers" - SupplierSv1GetSupplierForEvent = "SupplierSv1.GetSupplierForEvent" - SupplierSv1Ping = "SupplierSv1.Ping" - ApierV1GetSupplierProfile = "ApierV1.GetSupplierProfile" - ApierV1GetSupplierProfileIDs = "ApierV1.GetSupplierProfileIDs" - ApierV1RemoveSupplierProfile = "ApierV1.RemoveSupplierProfile" - ApierV1SetSupplierProfile = "ApierV1.SetSupplierProfile" + SupplierSv1GetSuppliers = "SupplierSv1.GetSuppliers" + SupplierSv1GetSupplierProfilesForEvent = "SupplierSv1.GetSupplierProfilesForEvent" + SupplierSv1Ping = "SupplierSv1.Ping" + ApierV1GetSupplierProfile = "ApierV1.GetSupplierProfile" + ApierV1GetSupplierProfileIDs = "ApierV1.GetSupplierProfileIDs" + ApierV1RemoveSupplierProfile = "ApierV1.RemoveSupplierProfile" + ApierV1SetSupplierProfile = "ApierV1.SetSupplierProfile" ) // AttributeS APIs From 362609e174c53b5c1d4b08a0b7ff577e0b2fe6dc Mon Sep 17 00:00:00 2001 From: Tripon Alexandru-Ionut Date: Thu, 18 Apr 2019 15:38:35 +0300 Subject: [PATCH 3/3] Renamed supplier_for_event.go file to supplier_profiles_for_event.go --- console/{supplier_for_event.go => supplier_profiles_for_event.go} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename console/{supplier_for_event.go => supplier_profiles_for_event.go} (100%) diff --git a/console/supplier_for_event.go b/console/supplier_profiles_for_event.go similarity index 100% rename from console/supplier_for_event.go rename to console/supplier_profiles_for_event.go