diff --git a/apier/v1/chargers_it_test.go b/apier/v1/chargers_it_test.go index f323777ee..99d90f293 100755 --- a/apier/v1/chargers_it_test.go +++ b/apier/v1/chargers_it_test.go @@ -88,6 +88,7 @@ var ( testChargerSRemChargerProfile, testChargerSPing, testChargerSProcessWithNotFoundAttribute, + testChargerSProccessEventWithProcceSRunS, testChargerSKillEngine, } ) @@ -432,6 +433,7 @@ func testChargerSProcessWithNotFoundAttribute(t *testing.T) { } processedEv := []*engine.ChrgSProcessEventReply{ { + Opts: map[string]interface{}{utils.Subsys: utils.MetaChargers}, ChargerSProfile: "ChargerWithoutAttribute", AttributeSProfiles: []string{}, AlteredFields: []string{utils.MetaReqRunID}, @@ -450,7 +452,7 @@ func testChargerSProcessWithNotFoundAttribute(t *testing.T) { if err := chargerRPC.Call(utils.ChargerSv1ProcessEvent, ev, &rply); err != nil { t.Error(err) } else if !reflect.DeepEqual(rply, processedEv) { - t.Errorf("Expecting : %+v, received: %+v", processedEv, rply) + t.Errorf("Expecting : %+v, received: %+v", utils.ToJSON(processedEv), utils.ToJSON(rply)) } } @@ -459,3 +461,69 @@ func testChargerSKillEngine(t *testing.T) { t.Error(err) } } + +func testChargerSProccessEventWithProcceSRunS(t *testing.T) { + chargerProfile = &ChargerWithCache{ + ChargerProfile: &engine.ChargerProfile{ + Tenant: "cgrates.org", + ID: "ApierTest", + FilterIDs: []string{"*string:~*req.Account:1010"}, + ActivationInterval: &utils.ActivationInterval{ + ActivationTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC), + ExpiryTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC), + }, + RunID: utils.MetaDefault, + AttributeIDs: []string{"*constant:*req.Account:1002", "*constant:*req.Account:1003"}, + Weight: 20, + }, + } + var result string + if err := chargerRPC.Call(utils.APIerSv1SetChargerProfile, chargerProfile, &result); err != nil { + t.Error(err) + } else if result != utils.OK { + t.Error("Unexpected reply returned", result) + } + var reply *engine.ChargerProfile + if err := chargerRPC.Call(utils.APIerSv1GetChargerProfile, + &utils.TenantID{Tenant: "cgrates.org", ID: "ApierTest"}, &reply); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(chargerProfile.ChargerProfile, reply) { + t.Errorf("Expecting : %+v, received: %+v", chargerProfile.ChargerProfile, reply) + } + + processedEv := []*engine.ChrgSProcessEventReply{ + { + ChargerSProfile: "ApierTest", + AttributeSProfiles: []string{"*constant:*req.Account:1002"}, + AlteredFields: []string{utils.MetaReqRunID, "*req.Account"}, + Opts: map[string]interface{}{ + utils.Subsys: utils.MetaChargers, + utils.OptsAttributesProcessRuns: 1., + }, + CGREvent: &utils.CGREvent{ // matching Charger1 + Tenant: "cgrates.org", + ID: "event1", + Event: map[string]interface{}{ + utils.Account: "1002", + utils.RunID: "*default", + }, + }, + }, + } + cgrEv := &utils.CGREventWithOpts{ + CGREvent: &utils.CGREvent{ // matching Charger1 + Tenant: "cgrates.org", + ID: "event1", + Event: map[string]interface{}{ + utils.Account: "1010", + }, + }, + Opts: map[string]interface{}{utils.OptsAttributesProcessRuns: 1}, + } + var result2 []*engine.ChrgSProcessEventReply + if err := chargerRPC.Call(utils.ChargerSv1ProcessEvent, cgrEv, &result2); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(result2, processedEv) { + t.Errorf("Expecting : %s, received: %s", utils.ToJSON(processedEv), utils.ToJSON(result2)) + } +} diff --git a/ees/ees.go b/ees/ees.go index 7022cb289..3f6486f38 100644 --- a/ees/ees.go +++ b/ees/ees.go @@ -112,12 +112,19 @@ func (eeS *EventExporterS) attrSProcessEvent(cgrEv *utils.CGREventWithOpts, attr cgrEv.Opts = make(map[string]interface{}) } cgrEv.Opts[utils.Subsys] = utils.MetaEEs + var processRuns *int + if val, has := cgrEv.Opts[utils.OptsAttributesProcessRuns]; has { + if v, err := utils.IfaceAsTInt64(val); err == nil { + processRuns = utils.IntPointer(int(v)) + } + } attrArgs := &engine.AttrArgsProcessEvent{ AttributeIDs: attrIDs, Context: utils.StringPointer(ctx), Opts: cgrEv.Opts, CGREvent: cgrEv.CGREvent, ArgDispatcher: cgrEv.ArgDispatcher, + ProcessRuns: processRuns, } if err = eeS.connMgr.Call( eeS.cfg.EEsNoLksCfg().AttributeSConns, nil, diff --git a/engine/cdrs.go b/engine/cdrs.go index b7151212b..a39f8c8b7 100644 --- a/engine/cdrs.go +++ b/engine/cdrs.go @@ -350,6 +350,12 @@ func (cdrS *CDRServer) attrSProcessEvent(cgrEv *utils.CGREventWithOpts) (err err cgrEv.Opts = make(map[string]interface{}) } cgrEv.Opts[utils.Subsys] = utils.MetaCDRs + var processRuns *int + if val, has := cgrEv.Opts[utils.OptsAttributesProcessRuns]; has { + if v, err := utils.IfaceAsTInt64(val); err == nil { + processRuns = utils.IntPointer(int(v)) + } + } attrArgs := &AttrArgsProcessEvent{ Context: utils.StringPointer(utils.FirstNonEmpty( utils.IfaceAsString(cgrEv.Opts[utils.OptsContext]), @@ -357,6 +363,7 @@ func (cdrS *CDRServer) attrSProcessEvent(cgrEv *utils.CGREventWithOpts) (err err CGREvent: cgrEv.CGREvent, ArgDispatcher: cgrEv.ArgDispatcher, Opts: cgrEv.Opts, + ProcessRuns: processRuns, } if err = cdrS.connMgr.Call(cdrS.cgrCfg.CdrsCfg().AttributeSConns, nil, utils.AttributeSv1ProcessEvent, diff --git a/engine/chargers.go b/engine/chargers.go index 8b38ce4f0..9971e4e3f 100644 --- a/engine/chargers.go +++ b/engine/chargers.go @@ -117,6 +117,12 @@ func (cS *ChargerService) processEvent(cgrEv *utils.CGREventWithOpts) (rply []*C cgrEv.Opts = make(map[string]interface{}) } cgrEv.Opts[utils.Subsys] = utils.MetaChargers + var processRuns *int + if val, has := cgrEv.Opts[utils.OptsAttributesProcessRuns]; has { + if v, err := utils.IfaceAsTInt64(val); err == nil { + processRuns = utils.IntPointer(int(v)) + } + } if cPs, err = cS.matchingChargerProfilesForEvent(cgrEv); err != nil { return nil, err } @@ -140,7 +146,7 @@ func (cS *ChargerService) processEvent(cgrEv *utils.CGREventWithOpts) (rply []*C Context: utils.StringPointer(utils.FirstNonEmpty( utils.IfaceAsString(opts[utils.OptsContext]), utils.MetaChargers)), - ProcessRuns: nil, + ProcessRuns: processRuns, CGREvent: clonedEv.CGREvent, ArgDispatcher: clonedEv.ArgDispatcher, Opts: opts, diff --git a/engine/routes.go b/engine/routes.go index ff6078114..ee8d2b285 100644 --- a/engine/routes.go +++ b/engine/routes.go @@ -621,6 +621,12 @@ func (rpS *RouteService) V1GetRoutes(args *ArgsGetRoutes, reply *SortedRoutes) ( args.Opts = make(map[string]interface{}) } args.Opts[utils.Subsys] = utils.MetaRoutes + var processRuns *int + if val, has := args.Opts[utils.OptsAttributesProcessRuns]; has { + if v, err := utils.IfaceAsTInt64(val); err == nil { + processRuns = utils.IntPointer(int(v)) + } + } attrArgs := &AttrArgsProcessEvent{ Context: utils.StringPointer(utils.FirstNonEmpty( utils.IfaceAsString(args.CGREvent.Event[utils.OptsContext]), @@ -628,6 +634,7 @@ func (rpS *RouteService) V1GetRoutes(args *ArgsGetRoutes, reply *SortedRoutes) ( CGREvent: args.CGREvent, ArgDispatcher: args.ArgDispatcher, Opts: args.Opts, + ProcessRuns: processRuns, } var rplyEv AttrSProcessEventReply if err := rpS.connMgr.Call(rpS.cgrcfg.RouteSCfg().AttributeSConns, nil, diff --git a/packages/debian/changelog b/packages/debian/changelog index 8bffc1f60..235bbf349 100644 --- a/packages/debian/changelog +++ b/packages/debian/changelog @@ -85,6 +85,7 @@ cgrates (0.11.0~dev) UNRELEASED; urgency=medium * [Templates] Added new dataconverter: *string2hex * [AttributeS] Updated AttributeProfile matching to match the second AttributeProfile with the same weight * [AttributeS] Updated inline AttributeProfiles to unite all consecutive inline attributes in a single profile + * [SessionS] Added *attributesProcessRuns option to control the process runs for AttributeS -- DanB Wed, 19 Feb 2020 13:25:52 +0200 diff --git a/sessions/sessions.go b/sessions/sessions.go index ed77ab764..53b8ce518 100644 --- a/sessions/sessions.go +++ b/sessions/sessions.go @@ -3829,6 +3829,12 @@ func (sS *SessionS) processAttributes(cgrEv *utils.CGREvent, argDisp *utils.ArgD opts = make(engine.MapEvent) } opts[utils.Subsys] = utils.MetaSessionS + var processRuns *int + if val, has := opts[utils.OptsAttributesProcessRuns]; has { + if v, err := utils.IfaceAsTInt64(val); err == nil { + processRuns = utils.IntPointer(int(v)) + } + } attrArgs := &engine.AttrArgsProcessEvent{ Context: utils.StringPointer(utils.FirstNonEmpty( opts.GetStringIgnoreErrors(utils.OptsContext), @@ -3837,6 +3843,7 @@ func (sS *SessionS) processAttributes(cgrEv *utils.CGREvent, argDisp *utils.ArgD ArgDispatcher: argDisp, Opts: opts, AttributeIDs: attrIDs, + ProcessRuns: processRuns, } err = sS.connMgr.Call(sS.cgrCfg.SessionSCfg().AttrSConns, nil, utils.AttributeSv1ProcessEvent, attrArgs, &rplyEv) diff --git a/utils/consts.go b/utils/consts.go index 01707234a..e5d544526 100755 --- a/utils/consts.go +++ b/utils/consts.go @@ -2261,8 +2261,9 @@ const ( OptsAPIKey = "*dispatcherApiKey" OptsRouteID = "*dispatcherRouteID" // Others - OptsContext = "*context" - Subsys = "*subsys" + OptsContext = "*context" + Subsys = "*subsys" + OptsAttributesProcessRuns = "*attributesProcessRuns" ) // Event Flags