diff --git a/apier/v1/dispatcher.go b/apier/v1/dispatcher.go index 80bacb0af..35f7d7aa5 100644 --- a/apier/v1/dispatcher.go +++ b/apier/v1/dispatcher.go @@ -749,9 +749,9 @@ type DispatcherSv1 struct { } // GetProfileForEvent returns the matching dispatcher profile for the provided event -func (dSv1 DispatcherSv1) GetProfileForEvent(ev *utils.CGREvent, - dPrfl *engine.DispatcherProfile) error { - return dSv1.dS.V1GetProfileForEvent(ev, dPrfl) +func (dSv1 DispatcherSv1) GetProfilesForEvent(ev *utils.CGREvent, + dPrfl *engine.DispatcherProfiles) error { + return dSv1.dS.V1GetProfilesForEvent(ev, dPrfl) } /* diff --git a/apier/v1/dispatchersv1_it_test.go b/apier/v1/dispatchersv1_it_test.go index 8ef004267..2244836c7 100644 --- a/apier/v1/dispatchersv1_it_test.go +++ b/apier/v1/dispatchersv1_it_test.go @@ -139,10 +139,11 @@ func testDspDspv1GetProfileForEvent(t *testing.T) { utils.EventName: "Event1", }, APIOpts: map[string]interface{}{ - utils.Subsys: utils.MetaAny, + utils.Subsys: utils.MetaAny, + utils.OptsDispatchersProfilesCount: 1, }, } - var reply engine.DispatcherProfile + var reply engine.DispatcherProfiles expected := engine.DispatcherProfile{ Tenant: "cgrates.org", ID: "EVENT1", @@ -171,12 +172,14 @@ func testDspDspv1GetProfileForEvent(t *testing.T) { expected.Hosts[1].FilterIDs = nil } expected.Hosts.Sort() - if err := dspRPC.Call(utils.DispatcherSv1GetProfileForEvent, &arg, &reply); err != nil { + if err := dspRPC.Call(utils.DispatcherSv1GetProfilesForEvent, &arg, &reply); err != nil { t.Fatal(err) + } else if len(reply) != 1 { + t.Fatalf("Unexpected number of profiles:%v", len(reply)) } - reply.Hosts.Sort() - if !reflect.DeepEqual(expected, reply) { - t.Errorf("expected: %s ,\n received: %s", utils.ToJSON(expected), utils.ToJSON(reply)) + reply[0].Hosts.Sort() + if !reflect.DeepEqual(expected, *reply[0]) { + t.Errorf("expected: %s ,\n received: %s", utils.ToJSON(expected), utils.ToJSON(reply[0])) } arg2 := &utils.CGREvent{ @@ -185,16 +188,19 @@ func testDspDspv1GetProfileForEvent(t *testing.T) { utils.EventName: "Event1", }, APIOpts: map[string]interface{}{ - utils.Subsys: utils.MetaAny, + utils.Subsys: utils.MetaAny, + utils.OptsDispatchersProfilesCount: 1, }, } expected.Hosts.Sort() - if err := dspRPC.Call(utils.DispatcherSv1GetProfileForEvent, &arg2, &reply); err != nil { + if err := dspRPC.Call(utils.DispatcherSv1GetProfilesForEvent, &arg2, &reply); err != nil { t.Fatal(err) + } else if len(reply) != 1 { + t.Fatalf("Unexpected number of profiles:%v", len(reply)) } - reply.Hosts.Sort() - if !reflect.DeepEqual(expected, reply) { - t.Errorf("expected: %s ,\n received: %s", utils.ToJSON(expected), utils.ToJSON(reply)) + reply[0].Hosts.Sort() + if !reflect.DeepEqual(expected, *reply[0]) { + t.Errorf("expected: %s ,\n received: %s", utils.ToJSON(expected), utils.ToJSON(reply[0])) } } @@ -204,11 +210,12 @@ func testDspDspv1GetProfileForEventWithMethod(t *testing.T) { ID: "testDspv2", Event: map[string]interface{}{}, APIOpts: map[string]interface{}{ - utils.Subsys: utils.MetaAny, - "*method": utils.DispatcherSv1GetProfileForEvent, + utils.Subsys: utils.MetaAny, + "*method": utils.DispatcherSv1GetProfilesForEvent, + utils.OptsDispatchersProfilesCount: 1, }, } - var reply engine.DispatcherProfile + var reply engine.DispatcherProfiles expected := engine.DispatcherProfile{ Tenant: "cgrates.org", ID: "EVENT6", @@ -230,12 +237,14 @@ func testDspDspv1GetProfileForEventWithMethod(t *testing.T) { expected.Hosts[0].FilterIDs = nil } expected.Hosts.Sort() - if err := dspRPC.Call(utils.DispatcherSv1GetProfileForEvent, &arg, &reply); err != nil { + if err := dspRPC.Call(utils.DispatcherSv1GetProfilesForEvent, &arg, &reply); err != nil { t.Fatal(err) + } else if len(reply) != 1 { + t.Fatalf("Unexpected number of profiles:%v", len(reply)) } - reply.Hosts.Sort() - if !reflect.DeepEqual(expected, reply) { - t.Errorf("expected: %s ,\n received: %s", utils.ToJSON(expected), utils.ToJSON(reply)) + reply[0].Hosts.Sort() + if !reflect.DeepEqual(expected, *reply[0]) { + t.Errorf("expected: %s ,\n received: %s", utils.ToJSON(expected), utils.ToJSON(reply[0])) } } diff --git a/apier/v1/routes_it_test.go b/apier/v1/routes_it_test.go index 48551463e..be65fa2cc 100644 --- a/apier/v1/routes_it_test.go +++ b/apier/v1/routes_it_test.go @@ -185,7 +185,7 @@ func testV1RouteGetWeightRoutes(t *testing.T) { utils.AccountField: "1007", utils.Destination: "+491511231234", }, - APIOpts: map[string]interface{}{utils.OptsRouteProfilesCount: 1}, + APIOpts: map[string]interface{}{utils.OptsRoutesProfilesCount: 1}, }, } eSpls := engine.SortedRoutesList{{ @@ -237,7 +237,7 @@ func testV1RouteGetLeastCostRoutes(t *testing.T) { utils.SetupTime: time.Date(2017, 12, 1, 14, 25, 0, 0, time.UTC), utils.Usage: "1m20s", }, - APIOpts: map[string]interface{}{utils.OptsRouteProfilesCount: 1}, + APIOpts: map[string]interface{}{utils.OptsRoutesProfilesCount: 1}, }, } eSpls := engine.SortedRoutesList{{ @@ -291,7 +291,7 @@ func testV1RouteGetLeastCostRoutesWithoutUsage(t *testing.T) { utils.Destination: "1002", utils.SetupTime: time.Date(2017, 12, 1, 14, 25, 0, 0, time.UTC), }, - APIOpts: map[string]interface{}{utils.OptsRouteProfilesCount: 1}, + APIOpts: map[string]interface{}{utils.OptsRoutesProfilesCount: 1}, }, } eSpls := engine.SortedRoutesList{{ @@ -347,7 +347,7 @@ func testV1RouteGetLeastCostRoutesWithMaxCost(t *testing.T) { utils.SetupTime: time.Date(2017, 12, 1, 14, 25, 0, 0, time.UTC), utils.Usage: "1m20s", }, - APIOpts: map[string]interface{}{utils.OptsRouteProfilesCount: 1}, + APIOpts: map[string]interface{}{utils.OptsRoutesProfilesCount: 1}, }, } eSpls := engine.SortedRoutesList{{ @@ -418,7 +418,7 @@ func testV1RouteGetLeastCostRoutesWithMaxCost2(t *testing.T) { utils.Usage: "10m20s", utils.Category: "call", }, - APIOpts: map[string]interface{}{utils.OptsRouteProfilesCount: 1}, + APIOpts: map[string]interface{}{utils.OptsRoutesProfilesCount: 1}, }, } eSpls := engine.SortedRoutesList{{ @@ -465,7 +465,7 @@ func testV1RouteGetHighestCostRoutes(t *testing.T) { utils.Usage: "1m20s", "DistinctMatch": "*highest_cost", }, - APIOpts: map[string]interface{}{utils.OptsRouteProfilesCount: 1}, + APIOpts: map[string]interface{}{utils.OptsRoutesProfilesCount: 1}, }, } eSpls := engine.SortedRoutesList{{ @@ -1162,7 +1162,7 @@ func testV1RoutesOneRouteWithoutDestination(t *testing.T) { utils.SetupTime: utils.MetaNow, utils.Usage: "2m", }, - APIOpts: map[string]interface{}{utils.OptsRouteProfilesCount: 1}, + APIOpts: map[string]interface{}{utils.OptsRoutesProfilesCount: 1}, }, } eSpls := engine.SortedRoutesList{{ @@ -1239,7 +1239,7 @@ func testV1RouteMultipleRouteSameID(t *testing.T) { utils.Usage: "2m", "Month": "April", }, - APIOpts: map[string]interface{}{utils.OptsRouteProfilesCount: 1}, + APIOpts: map[string]interface{}{utils.OptsRoutesProfilesCount: 1}, }, } eSpls := engine.SortedRoutesList{{ @@ -1277,7 +1277,7 @@ func testV1RouteMultipleRouteSameID(t *testing.T) { utils.Usage: "2m", "Month": "May", }, - APIOpts: map[string]interface{}{utils.OptsRouteProfilesCount: 1}, + APIOpts: map[string]interface{}{utils.OptsRoutesProfilesCount: 1}, }, } eSpls = engine.SortedRoutesList{{ @@ -1375,7 +1375,7 @@ func testV1RouteAccountWithRatingPlan(t *testing.T) { utils.Usage: "30s", "EventType": "testV1RouteAccountWithRatingPlan", }, - APIOpts: map[string]interface{}{utils.OptsRouteProfilesCount: 1}, + APIOpts: map[string]interface{}{utils.OptsRoutesProfilesCount: 1}, }, } eSpls := &engine.SortedRoutesList{{ @@ -1445,7 +1445,7 @@ func testV1RouteAccountWithRatingPlan(t *testing.T) { utils.Usage: "60s", "EventType": "testV1RouteAccountWithRatingPlan", }, - APIOpts: map[string]interface{}{utils.OptsRouteProfilesCount: 1}, + APIOpts: map[string]interface{}{utils.OptsRoutesProfilesCount: 1}, }, } eSpls = &engine.SortedRoutesList{{ @@ -1517,7 +1517,7 @@ func testV1RouteAccountWithRatingPlan(t *testing.T) { utils.Usage: "1m1s", "EventType": "testV1RouteAccountWithRatingPlan", }, - APIOpts: map[string]interface{}{utils.OptsRouteProfilesCount: 1}, + APIOpts: map[string]interface{}{utils.OptsRoutesProfilesCount: 1}, }, } eSpls = &engine.SortedRoutesList{{ diff --git a/apier/v1/sessionsv1_it_test.go b/apier/v1/sessionsv1_it_test.go index 5ce776246..b6c9b1c61 100644 --- a/apier/v1/sessionsv1_it_test.go +++ b/apier/v1/sessionsv1_it_test.go @@ -311,7 +311,7 @@ func testSSv1ItAuthWithDigest(t *testing.T) { utils.SetupTime: time.Date(2018, time.January, 7, 16, 60, 0, 0, time.UTC), utils.Usage: authUsage, }, - APIOpts: map[string]interface{}{utils.OptsRouteProfilesCount: 1}, + APIOpts: map[string]interface{}{utils.OptsRoutesProfilesCount: 1}, }, } var rply sessions.V1AuthorizeReplyWithDigest diff --git a/console/dispatchers_for_event.go b/console/dispatchers_for_event.go index 6ba61a640..26533ba71 100644 --- a/console/dispatchers_for_event.go +++ b/console/dispatchers_for_event.go @@ -26,7 +26,7 @@ import ( func init() { c := &CmdDispatcherProfile{ name: "dispatches_for_event", - rpcMethod: utils.DispatcherSv1GetProfileForEvent, + rpcMethod: utils.DispatcherSv1GetProfilesForEvent, } commands[c.Name()] = c c.CommandExecuter = &CommandExecuter{c} @@ -60,6 +60,6 @@ func (self *CmdDispatcherProfile) PostprocessRpcParams() error { } func (self *CmdDispatcherProfile) RpcResult() interface{} { - var s engine.DispatcherProfile + var s engine.DispatcherProfiles return &s } diff --git a/dispatchers/dispatchers.go b/dispatchers/dispatchers.go index 4c4aa5d2f..6aaee0ae8 100644 --- a/dispatchers/dispatchers.go +++ b/dispatchers/dispatchers.go @@ -102,8 +102,8 @@ func (dS *DispatcherService) authorize(method, tenant string, apiKey string, evT // dispatcherForEvent returns a dispatcher instance configured for specific event // or utils.ErrNotFound if none present -func (dS *DispatcherService) dispatcherProfileForEvent(tnt string, ev *utils.CGREvent, - subsys string) (dPrlf *engine.DispatcherProfile, err error) { +func (dS *DispatcherService) dispatcherProfilesForEvent(tnt string, ev *utils.CGREvent, + subsys string) (dPrlfs engine.DispatcherProfiles, err error) { // find out the matching profiles anyIdxPrfx := utils.ConcatenatedKey(tnt, utils.MetaAny) idxKeyPrfx := anyIdxPrfx @@ -146,6 +146,7 @@ func (dS *DispatcherService) dispatcherProfileForEvent(tnt string, ev *utils.CGR } err = nil // make sure we ignore the error from *any subsystem matching } + dPrlfs = make(engine.DispatcherProfiles, 0, len(prflIDs)) for prflID := range prflIDs { prfl, err := dS.dm.GetDispatcherProfile(tnt, prflID, true, true, utils.NonTransactional) if err != nil { @@ -167,13 +168,22 @@ func (dS *DispatcherService) dispatcherProfileForEvent(tnt string, ev *utils.CGR } else if !pass { continue } - if dPrlf == nil || prfl.Weight > dPrlf.Weight { - dPrlf = prfl - } + dPrlfs = append(dPrlfs, prfl) } - if dPrlf == nil { + if len(dPrlfs) == 0 { err = utils.ErrNotFound + return } + prfCount := len(dPrlfs) // if the option is not present return for all profiles + if prfCountOpt, err := ev.OptAsInt64(utils.OptsDispatchersProfilesCount); err != nil { + if err != utils.ErrNotFound { // is an conversion error + return nil, err + } + } else if prfCount > int(prfCountOpt) { // it has the option and is smaller that the current number of profiles + prfCount = int(prfCountOpt) + } + dPrlfs.Sort() + dPrlfs = dPrlfs[:prfCount] return } @@ -184,36 +194,41 @@ func (dS *DispatcherService) Dispatch(ev *utils.CGREvent, subsys string, if tnt == utils.EmptyString { tnt = dS.cfg.GeneralCfg().DefaultTenant } - dPrfl, errDsp := dS.dispatcherProfileForEvent(tnt, ev, subsys) - if errDsp != nil { - return utils.NewErrDispatcherS(errDsp) - } - tntID := dPrfl.TenantID() - // get or build the Dispatcher for the config - var d Dispatcher - if x, ok := engine.Cache.Get(utils.CacheDispatchers, - tntID); ok && x != nil { - d = x.(Dispatcher) - } else if d, err = newDispatcher(dS.dm, dPrfl); err != nil { + var dPrfls engine.DispatcherProfiles + if dPrfls, err = dS.dispatcherProfilesForEvent(tnt, ev, subsys); err != nil { return utils.NewErrDispatcherS(err) } - if errCh := engine.Cache.Set(utils.CacheDispatchers, tntID, d, nil, true, utils.EmptyString); errCh != nil { - return utils.NewErrDispatcherS(errCh) + for _, dPrfl := range dPrfls { + tntID := dPrfl.TenantID() + // get or build the Dispatcher for the config + var d Dispatcher + if x, ok := engine.Cache.Get(utils.CacheDispatchers, + tntID); ok && x != nil { + d = x.(Dispatcher) + } else if d, err = newDispatcher(dS.dm, dPrfl); err != nil { + return utils.NewErrDispatcherS(err) + } + if err = engine.Cache.Set(utils.CacheDispatchers, tntID, d, nil, true, utils.EmptyString); err != nil { + return utils.NewErrDispatcherS(err) + } + if err = d.Dispatch(utils.IfaceAsString(ev.APIOpts[utils.OptsRouteID]), subsys, serviceMethod, args, reply); !rpcclient.IsNetworkError(err) { + return + } } - return d.Dispatch(utils.IfaceAsString(ev.APIOpts[utils.OptsRouteID]), subsys, serviceMethod, args, reply) + return // return the last error } -func (dS *DispatcherService) V1GetProfileForEvent(ev *utils.CGREvent, - dPfl *engine.DispatcherProfile) (err error) { +func (dS *DispatcherService) V1GetProfilesForEvent(ev *utils.CGREvent, + dPfl *engine.DispatcherProfiles) (err error) { tnt := ev.Tenant if tnt == utils.EmptyString { tnt = dS.cfg.GeneralCfg().DefaultTenant } - retDPfl, errDpfl := dS.dispatcherProfileForEvent(tnt, ev, utils.IfaceAsString(ev.APIOpts[utils.Subsys])) + retDPfl, errDpfl := dS.dispatcherProfilesForEvent(tnt, ev, utils.IfaceAsString(ev.APIOpts[utils.Subsys])) if errDpfl != nil { return utils.NewErrDispatcherS(errDpfl) } - *dPfl = *retDPfl + *dPfl = retDPfl return } diff --git a/dispatchers/dispatchers_it_test.go b/dispatchers/dispatchers_it_test.go index 3c5f84596..29c734761 100644 --- a/dispatchers/dispatchers_it_test.go +++ b/dispatchers/dispatchers_it_test.go @@ -187,7 +187,7 @@ func TestDispatcherServiceDispatcherProfileForEventGetDispatchertWithoutAuthenti }, } tnt := ev.Tenant - _, err = dss.dispatcherProfileForEvent(tnt, ev, utils.MetaAccounts) + _, err = dss.dispatcherProfilesForEvent(tnt, ev, utils.MetaAccounts) expected := utils.ErrNotImplemented if err == nil || err != expected { t.Errorf("\nExpected <%+v>, \nReceived <%+v>", expected, err) diff --git a/dispatchers/dispatchers_test.go b/dispatchers/dispatchers_test.go index 334f125a9..6f8009e9d 100644 --- a/dispatchers/dispatchers_test.go +++ b/dispatchers/dispatchers_test.go @@ -84,7 +84,7 @@ func TestDispatcherServiceDispatcherProfileForEventGetDispatcherProfileNF(t *tes } tnt := ev.Tenant subsys := utils.IfaceAsString(ev.APIOpts[utils.Subsys]) - _, err = dss.dispatcherProfileForEvent(tnt, ev, subsys) + _, err = dss.dispatcherProfilesForEvent(tnt, ev, subsys) expected := utils.ErrNotImplemented if err == nil || err != expected { t.Errorf("\nExpected <%+v>, \nReceived <%+v>", expected, err) @@ -102,7 +102,7 @@ func TestDispatcherServiceDispatcherProfileForEventMIIDENotFound(t *testing.T) { ev := &utils.CGREvent{} tnt := "" subsys := utils.IfaceAsString(ev.APIOpts[utils.Subsys]) - _, err := dss.dispatcherProfileForEvent(tnt, ev, subsys) + _, err := dss.dispatcherProfilesForEvent(tnt, ev, subsys) if err == nil || err != utils.ErrNotFound { t.Errorf("\nExpected <%+v>, \nReceived <%+v>", utils.ErrNotFound, err) } @@ -170,8 +170,8 @@ func TestDispatcherV1GetProfileForEventErr(t *testing.T) { cfg.GeneralCfg().DefaultTenant = utils.EmptyString dsp := NewDispatcherService(nil, cfg, nil, nil) ev := &utils.CGREvent{} - dPfl := &engine.DispatcherProfile{} - err := dsp.V1GetProfileForEvent(ev, dPfl) + dPfl := &engine.DispatcherProfiles{} + err := dsp.V1GetProfilesForEvent(ev, dPfl) expected := "DISPATCHER_ERROR:NO_DATABASE_CONNECTION" if err == nil || err.Error() != expected { t.Errorf("\nExpected <%+v>, \nReceived <%+v>", expected, err) @@ -183,8 +183,8 @@ func TestDispatcherV1GetProfileForEvent(t *testing.T) { cfg.GeneralCfg().DefaultTenant = utils.EmptyString dsp := NewDispatcherService(nil, cfg, nil, nil) ev := &utils.CGREvent{} - dPfl := &engine.DispatcherProfile{} - err := dsp.V1GetProfileForEvent(ev, dPfl) + dPfl := &engine.DispatcherProfiles{} + err := dsp.V1GetProfilesForEvent(ev, dPfl) expected := "DISPATCHER_ERROR:NO_DATABASE_CONNECTION" if err == nil || err.Error() != expected { t.Errorf("\nExpected <%+v>, \nReceived <%+v>", expected, err) @@ -571,7 +571,7 @@ func TestDispatcherServiceDispatcherProfileForEventErrNil(t *testing.T) { } tnt := ev.Tenant subsys := utils.IfaceAsString(ev.APIOpts[utils.Subsys]) - _, err = dss.dispatcherProfileForEvent(tnt, ev, subsys) + _, err = dss.dispatcherProfilesForEvent(tnt, ev, subsys) if err != nil { t.Errorf("\nExpected <%+v>, \nReceived <%+v>", nil, err) } @@ -615,12 +615,12 @@ func TestDispatcherV1GetProfileForEventReturn(t *testing.T) { } tnt := ev.Tenant subsys := utils.IfaceAsString(ev.APIOpts[utils.Subsys]) - _, err = dss.dispatcherProfileForEvent(tnt, ev, subsys) + _, err = dss.dispatcherProfilesForEvent(tnt, ev, subsys) if err != nil { t.Errorf("\nExpected <%+v>, \nReceived <%+v>", nil, err) } - dPfl := &engine.DispatcherProfile{} - err = dss.V1GetProfileForEvent(ev, dPfl) + dPfl := &engine.DispatcherProfiles{} + err = dss.V1GetProfilesForEvent(ev, dPfl) expected := "DISPATCHER_ERROR:NO_DATABASE_CONNECTION" if err != nil { t.Errorf("\nExpected <%+v>, \nReceived <%+v>", expected, err) @@ -665,7 +665,7 @@ func TestDispatcherServiceDispatcherProfileForEventErrNotFound(t *testing.T) { } tnt := ev.Tenant subsys := utils.IfaceAsString(ev.APIOpts[utils.Subsys]) - _, err = dss.dispatcherProfileForEvent(tnt, ev, subsys) + _, err = dss.dispatcherProfilesForEvent(tnt, ev, subsys) if err == nil || err != utils.ErrNotFound { t.Errorf("\nExpected <%+v>, \nReceived <%+v>", utils.ErrNotFound, err) } @@ -709,7 +709,7 @@ func TestDispatcherServiceDispatcherProfileForEventErrNotFound2(t *testing.T) { } tnt := "" subsys := utils.IfaceAsString(ev.APIOpts[utils.Subsys]) - _, err = dss.dispatcherProfileForEvent(tnt, ev, subsys) + _, err = dss.dispatcherProfilesForEvent(tnt, ev, subsys) if err == nil || err != utils.ErrNotFound { t.Errorf("\nExpected <%+v>, \nReceived <%+v>", utils.ErrNotFound, err) } @@ -757,7 +757,7 @@ func TestDispatcherServiceDispatcherProfileForEventErrNotFoundTime(t *testing.T) } tnt := ev.Tenant subsys := utils.IfaceAsString(ev.APIOpts[utils.Subsys]) - _, err = dss.dispatcherProfileForEvent(tnt, ev, subsys) + _, err = dss.dispatcherProfilesForEvent(tnt, ev, subsys) if err == nil || err != utils.ErrNotFound { t.Errorf("\nExpected <%+v>, \nReceived <%+v>", utils.ErrNotFound, err) } @@ -801,7 +801,7 @@ func TestDispatcherServiceDispatcherProfileForEventErrNotFoundFilter(t *testing. } tnt := ev.Tenant subsys := utils.IfaceAsString(ev.APIOpts[utils.Subsys]) - _, err = dss.dispatcherProfileForEvent(tnt, ev, subsys) + _, err = dss.dispatcherProfilesForEvent(tnt, ev, subsys) if err == nil || err.Error() != "NOT_FOUND:filter" { t.Errorf("\nExpected <%+v>, \nReceived <%+v>", "NOT_FOUND:filter", err) } @@ -956,7 +956,7 @@ func TestDispatcherServiceDispatcherProfileForEventFoundFilter(t *testing.T) { } tnt := ev.Tenant subsys := utils.IfaceAsString(ev.APIOpts[utils.Subsys]) - _, err = dss.dispatcherProfileForEvent(tnt, ev, subsys) + _, err = dss.dispatcherProfilesForEvent(tnt, ev, subsys) if err == nil || err.Error() != "NOT_FOUND" { t.Errorf("\nExpected <%+v>, \nReceived <%+v>", "NOT_FOUND:filter", err) } @@ -996,7 +996,7 @@ func TestDispatcherServiceDispatcherProfileForEventNotNotFound(t *testing.T) { } tnt := ev.Tenant subsys := utils.IfaceAsString(ev.APIOpts[utils.Subsys]) - _, err := dss.dispatcherProfileForEvent(tnt, ev, subsys) + _, err := dss.dispatcherProfilesForEvent(tnt, ev, subsys) expected := utils.ErrNotImplemented if err == nil || err != expected { t.Errorf("\nExpected <%+v>, \nReceived <%+v>", expected, err) @@ -1054,7 +1054,7 @@ func TestDispatcherServiceDispatcherProfileForEventGetDispatcherError(t *testing } tnt := ev.Tenant subsys := utils.IfaceAsString(ev.APIOpts[utils.Subsys]) - _, err = dss.dispatcherProfileForEvent(tnt, ev, subsys) + _, err = dss.dispatcherProfilesForEvent(tnt, ev, subsys) if err == nil || err.Error() != "NOT_FOUND" { t.Errorf("\nExpected <%+v>, \nReceived <%+v>", "NOT_FOUND:filter", err) } @@ -1323,12 +1323,17 @@ func TestDispatchersdispatcherProfileForEventAnySSfalses(t *testing.T) { Event: map[string]interface{}{ utils.AccountField: "1001", }, + APIOpts: map[string]interface{}{ + utils.OptsDispatchersProfilesCount: 1, + }, } subsys := utils.MetaSessionS - if rcv, err := dS.dispatcherProfileForEvent(tnt, ev, subsys); err != nil { + if rcv, err := dS.dispatcherProfilesForEvent(tnt, ev, subsys); err != nil { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", nil, err) - } else if !reflect.DeepEqual(rcv, dsp2) { + } else if len(rcv) != 1 { + t.Errorf("Unexpected number of profiles:%v", len(rcv)) + } else if !reflect.DeepEqual(rcv[0], dsp2) { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", dsp2, rcv) } @@ -1343,9 +1348,11 @@ func TestDispatchersdispatcherProfileForEventAnySSfalses(t *testing.T) { t.Error(err) } - if rcv, err := dS.dispatcherProfileForEvent(tnt, ev, subsys); err != nil { + if rcv, err := dS.dispatcherProfilesForEvent(tnt, ev, subsys); err != nil { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", nil, err) - } else if !reflect.DeepEqual(rcv, dsp1) { + } else if len(rcv) != 1 { + t.Errorf("Unexpected number of profiles:%v", len(rcv)) + } else if !reflect.DeepEqual(rcv[0], dsp1) { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", dsp1, rcv) } } @@ -1400,12 +1407,17 @@ func TestDispatchersdispatcherProfileForEventAnySSfalseFirstNotFound(t *testing. Event: map[string]interface{}{ utils.AccountField: "1001", }, + APIOpts: map[string]interface{}{ + utils.OptsDispatchersProfilesCount: 1, + }, } subsys := utils.MetaSessionS - if rcv, err := dS.dispatcherProfileForEvent(tnt, ev, subsys); err != nil { + if rcv, err := dS.dispatcherProfilesForEvent(tnt, ev, subsys); err != nil { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", nil, err) - } else if !reflect.DeepEqual(rcv, dsp2) { + } else if len(rcv) != 1 { + t.Errorf("Unexpected number of profiles:%v", len(rcv)) + } else if !reflect.DeepEqual(rcv[0], dsp2) { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", dsp2, rcv) } } @@ -1460,12 +1472,17 @@ func TestDispatchersdispatcherProfileForEventAnySSfalseFound(t *testing.T) { Event: map[string]interface{}{ utils.AccountField: "1001", }, + APIOpts: map[string]interface{}{ + utils.OptsDispatchersProfilesCount: 1, + }, } subsys := utils.MetaSessionS - if rcv, err := dS.dispatcherProfileForEvent(tnt, ev, subsys); err != nil { + if rcv, err := dS.dispatcherProfilesForEvent(tnt, ev, subsys); err != nil { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", nil, err) - } else if !reflect.DeepEqual(rcv, dsp1) { + } else if len(rcv) != 1 { + t.Errorf("Unexpected number of profiles:%v", len(rcv)) + } else if !reflect.DeepEqual(rcv[0], dsp1) { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", dsp1, rcv) } } @@ -1520,10 +1537,13 @@ func TestDispatchersdispatcherProfileForEventAnySSfalseNotFound(t *testing.T) { Event: map[string]interface{}{ utils.AccountField: "1001", }, + APIOpts: map[string]interface{}{ + utils.OptsDispatchersProfilesCount: 1, + }, } subsys := utils.MetaSessionS - if rcv, err := dS.dispatcherProfileForEvent(tnt, ev, subsys); err == nil || err != utils.ErrNotFound { + if rcv, err := dS.dispatcherProfilesForEvent(tnt, ev, subsys); err == nil || err != utils.ErrNotFound { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", utils.ErrNotFound, err) } else if rcv != nil { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", nil, rcv) @@ -1579,10 +1599,13 @@ func TestDispatchersdispatcherProfileForEventAnySStrueNotFound(t *testing.T) { Event: map[string]interface{}{ utils.AccountField: "1001", }, + APIOpts: map[string]interface{}{ + utils.OptsDispatchersProfilesCount: 1, + }, } subsys := utils.MetaSessionS - if rcv, err := dS.dispatcherProfileForEvent(tnt, ev, subsys); err == nil || err != utils.ErrNotFound { + if rcv, err := dS.dispatcherProfilesForEvent(tnt, ev, subsys); err == nil || err != utils.ErrNotFound { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", utils.ErrNotFound, err) } else if rcv != nil { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", nil, rcv) @@ -1638,12 +1661,17 @@ func TestDispatchersdispatcherProfileForEventAnySStrueBothFound(t *testing.T) { Event: map[string]interface{}{ utils.AccountField: "1001", }, + APIOpts: map[string]interface{}{ + utils.OptsDispatchersProfilesCount: 1, + }, } subsys := utils.MetaSessionS - if rcv, err := dS.dispatcherProfileForEvent(tnt, ev, subsys); err != nil { + if rcv, err := dS.dispatcherProfilesForEvent(tnt, ev, subsys); err != nil { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", nil, err) - } else if !reflect.DeepEqual(rcv, dsp2) { + } else if len(rcv) != 1 { + t.Errorf("Unexpected number of profiles:%v", len(rcv)) + } else if !reflect.DeepEqual(rcv[0], dsp2) { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", dsp2, rcv) } @@ -1653,9 +1681,11 @@ func TestDispatchersdispatcherProfileForEventAnySStrueBothFound(t *testing.T) { t.Error(err) } - if rcv, err := dS.dispatcherProfileForEvent(tnt, ev, subsys); err != nil { + if rcv, err := dS.dispatcherProfilesForEvent(tnt, ev, subsys); err != nil { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", nil, err) - } else if !reflect.DeepEqual(rcv, dsp1) { + } else if len(rcv) != 1 { + t.Errorf("Unexpected number of profiles:%v", len(rcv)) + } else if !reflect.DeepEqual(rcv[0], dsp1) { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", dsp1, rcv) } } diff --git a/dispatchers/sessions_it_test.go b/dispatchers/sessions_it_test.go index f56f610e0..4bda4a893 100644 --- a/dispatchers/sessions_it_test.go +++ b/dispatchers/sessions_it_test.go @@ -242,8 +242,8 @@ func testDspSessionAuthorize(t *testing.T) { }, APIOpts: map[string]interface{}{ - utils.OptsAPIKey: "ses12345", - utils.OptsRouteProfilesCount: 1., + utils.OptsAPIKey: "ses12345", + utils.OptsRoutesProfilesCount: 1., }, }, } diff --git a/engine/routes.go b/engine/routes.go index 3e082f59c..f8ade084b 100644 --- a/engine/routes.go +++ b/engine/routes.go @@ -698,7 +698,7 @@ func (rpS *RouteService) sortedRoutesForEvent(tnt string, args *ArgsGetRoutes) ( return } prfCount := len(rPrfs) // if the option is not present return for all profiles - if prfCountOpt, err := args.OptAsInt64(utils.OptsRouteProfilesCount); err != nil { + if prfCountOpt, err := args.OptAsInt64(utils.OptsRoutesProfilesCount); err != nil { if err != utils.ErrNotFound { // is an conversion error return nil, err } diff --git a/engine/routes_test.go b/engine/routes_test.go index a65fc6cec..3ee4b97ba 100644 --- a/engine/routes_test.go +++ b/engine/routes_test.go @@ -2283,7 +2283,7 @@ func TestRoutesSortedForEventWithLimitAndOffset2(t *testing.T) { Tenant: "cgrates.org", ID: "utils.CGREvent1", Event: map[string]interface{}{}, - APIOpts: map[string]interface{}{utils.OptsRouteProfilesCount: 3}, + APIOpts: map[string]interface{}{utils.OptsRoutesProfilesCount: 3}, }, } diff --git a/general_tests/sessionroutes_it_test.go b/general_tests/sessionroutes_it_test.go index a4fef3aad..626ec1806 100644 --- a/general_tests/sessionroutes_it_test.go +++ b/general_tests/sessionroutes_it_test.go @@ -131,7 +131,7 @@ func testSesRoutesAuthorizeEvent(t *testing.T) { utils.SetupTime: time.Date(2018, 8, 24, 16, 00, 00, 0, time.UTC), utils.Usage: time.Minute, }, - APIOpts: map[string]interface{}{utils.OptsRouteProfilesCount: 1}, + APIOpts: map[string]interface{}{utils.OptsRoutesProfilesCount: 1}, } args := sessions.NewV1AuthorizeArgs(false, []string{}, false, []string{}, false, []string{}, false, false, @@ -262,7 +262,7 @@ func testSesRoutesProcessMessage(t *testing.T) { utils.SetupTime: time.Date(2018, 8, 24, 16, 00, 00, 0, time.UTC), utils.Usage: time.Minute, }, - APIOpts: map[string]interface{}{utils.OptsRouteProfilesCount: 1}, + APIOpts: map[string]interface{}{utils.OptsRoutesProfilesCount: 1}, } args := sessions.NewV1ProcessMessageArgs(false, []string{}, false, []string{}, false, []string{}, false, false, @@ -395,7 +395,7 @@ func testSesRoutesProcessEvent(t *testing.T) { utils.SetupTime: time.Date(2018, 8, 24, 16, 00, 00, 0, time.UTC), utils.Usage: time.Minute, }, - APIOpts: map[string]interface{}{utils.OptsRouteProfilesCount: 1}, + APIOpts: map[string]interface{}{utils.OptsRoutesProfilesCount: 1}, } args := sessions.V1ProcessEventArgs{ Flags: []string{"*routes"}, diff --git a/registrarc/libregistrarc_test.go b/registrarc/libregistrarc_test.go index 338ebe19a..b2c9cc786 100644 --- a/registrarc/libregistrarc_test.go +++ b/registrarc/libregistrarc_test.go @@ -281,7 +281,7 @@ func TestRegister(t *testing.T) { if _, err := register(req); err == nil { t.Errorf("Expected error,received: nil") } - args2 = utils.NewServerRequest(utils.DispatcherSv1GetProfileForEvent, id, id) + args2 = utils.NewServerRequest(utils.DispatcherSv1GetProfilesForEvent, id, id) args2JSON, err = json.Marshal(args2) if err != nil { t.Fatal(err) @@ -290,7 +290,7 @@ func TestRegister(t *testing.T) { if _, err := register(req); err == nil { t.Errorf("Expected error,received: nil") } - args2 = utils.NewServerRequest(utils.DispatcherSv1GetProfileForEvent, id, id) + args2 = utils.NewServerRequest(utils.DispatcherSv1GetProfilesForEvent, id, id) args2JSON, err = json.Marshal(args2) if err != nil { t.Fatal(err) diff --git a/utils/consts.go b/utils/consts.go index 6bde1b971..c723a26be 100644 --- a/utils/consts.go +++ b/utils/consts.go @@ -1645,11 +1645,11 @@ const ( // DispatcherS APIs const ( - DispatcherSv1 = "DispatcherSv1" - DispatcherSv1Ping = "DispatcherSv1.Ping" - DispatcherSv1GetProfileForEvent = "DispatcherSv1.GetProfileForEvent" - DispatcherSv1Apier = "DispatcherSv1.Apier" - DispatcherServicePing = "DispatcherService.Ping" + DispatcherSv1 = "DispatcherSv1" + DispatcherSv1Ping = "DispatcherSv1.Ping" + DispatcherSv1GetProfilesForEvent = "DispatcherSv1.GetProfilesForEvent" + DispatcherSv1Apier = "DispatcherSv1.Apier" + DispatcherServicePing = "DispatcherService.Ping" ) // RegistrarS APIs @@ -2408,7 +2408,7 @@ var CGROptionsSet = NewStringSet([]string{OptsRatesStartTime, OptsRatesUsage, Op OptsStirOriginatorTn, OptsStirOriginatorURI, OptsStirDestinationTn, OptsStirDestinationURI, OptsStirPublicKeyPath, OptsStirPrivateKeyPath, OptsAPIKey, OptsRouteID, OptsContext, OptsAttributesProcessRuns, OptsRoutesLimit, OptsRoutesOffset, OptsChargeable, - RemoteHostOpt, CacheOpt}) + RemoteHostOpt, CacheOpt, OptsRoutesProfilesCount, OptsDispatchersProfilesCount}) // EventExporter metrics const ( @@ -2430,7 +2430,7 @@ const ( // Event Opts const ( - OptsRouteProfilesCount = "*routeProfilesCount" + OptsRoutesProfilesCount = "*routesProfilesCount" OptsRoutesLimit = "*routes_limit" OptsRoutesOffset = "*routes_offset" OptsRatesStartTime = "*ratesStartTime" @@ -2453,8 +2453,9 @@ const ( OptsStirPublicKeyPath = "*stirPublicKeyPath" OptsStirPrivateKeyPath = "*stirPrivateKeyPath" // DispatcherS - OptsAPIKey = "*apiKey" - OptsRouteID = "*routeID" + OptsAPIKey = "*apiKey" + OptsRouteID = "*routeID" + OptsDispatchersProfilesCount = "*dispatchersProfilesCount" // EEs OptsEEsVerbose = "*eesVerbose" // Others