From 2e2e97a4ac4bcab0897ff89714d2675048edba6d Mon Sep 17 00:00:00 2001 From: DanB Date: Thu, 19 Jul 2018 19:28:34 +0200 Subject: [PATCH] AttributeSv1.ProcessEvent with multiple process_runs --- agents/kamevent_test.go | 4 +-- engine/attributes.go | 52 ++++++++++++++++++++++++++++++--------- engine/attributes_test.go | 28 ++++++++++----------- engine/chargers.go | 2 +- 4 files changed, 57 insertions(+), 29 deletions(-) diff --git a/agents/kamevent_test.go b/agents/kamevent_test.go index 9dc071981..be6d1de84 100644 --- a/agents/kamevent_test.go +++ b/agents/kamevent_test.go @@ -270,8 +270,8 @@ func TestKamEvAsKamAuthReply(t *testing.T) { } authRply = &sessions.V1AuthorizeReply{ Attributes: &engine.AttrSProcessEventReply{ - MatchedProfile: "ATTR_1001_ACCOUNT_PROFILE", - AlteredFields: []string{"Password", utils.RequestType}, + MatchedProfiles: []string{"ATTR_1001_ACCOUNT_PROFILE"}, + AlteredFields: []string{"Password", utils.RequestType}, CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", ID: "TestKamEvAsKamAuthReply", diff --git a/engine/attributes.go b/engine/attributes.go index 16860a315..1afde2076 100644 --- a/engine/attributes.go +++ b/engine/attributes.go @@ -131,9 +131,9 @@ type AttrSFieldNameValue struct { } type AttrSProcessEventReply struct { - MatchedProfile string - AlteredFields []string - CGREvent *utils.CGREvent + MatchedProfiles []string + AlteredFields []string + CGREvent *utils.CGREvent } // Digest returns serialized version of alteredFields in AttrSProcessEventReply @@ -154,16 +154,20 @@ func (attrReply *AttrSProcessEventReply) Digest() (rplyDigest string) { type AttrArgsProcessEvent struct { AttributeIDs []string + ProcessRuns *int // number of loops for ProcessEvent utils.CGREvent } // processEvent will match event with attribute profile and do the necessary replacements -func (alS *AttributeService) processEvent(args *AttrArgsProcessEvent) (rply *AttrSProcessEventReply, err error) { +func (alS *AttributeService) processEvent(args *AttrArgsProcessEvent) ( + rply *AttrSProcessEventReply, err error) { attrPrf, err := alS.attributeProfileForEvent(args) if err != nil { return nil, err } - rply = &AttrSProcessEventReply{MatchedProfile: attrPrf.ID, CGREvent: args.Clone()} + rply = &AttrSProcessEventReply{ + MatchedProfiles: []string{attrPrf.ID}, + CGREvent: args.Clone()} for fldName, initialMp := range attrPrf.attributes { initEvValIf, has := args.Event[fldName] if !has { @@ -217,13 +221,37 @@ func (alS *AttributeService) V1ProcessEvent(args *AttrArgsProcessEvent, if args.Event == nil { return utils.NewErrMandatoryIeMissing("Event") } - evReply, err := alS.processEvent(args) - if err != nil { - if err != utils.ErrNotFound { - err = utils.NewErrServerError(err) - } - return err + if args.ProcessRuns == nil || *args.ProcessRuns == 0 { + args.ProcessRuns = utils.IntPointer(alS.processRuns) } - *reply = *evReply + var apiRply *AttrSProcessEventReply // aggregate response here + for i := 0; i < *args.ProcessRuns; i++ { + evRply, err := alS.processEvent(args) + if err != nil { + if err != utils.ErrNotFound { + err = utils.NewErrServerError(err) + } else if i != 0 { // ignore "not found" in a loop different than 0 + err = nil + break + } + return err + } + if apiRply == nil { // first reply + apiRply = evRply + continue + } + if utils.IsSliceMember(apiRply.MatchedProfiles, + evRply.MatchedProfiles[0]) { // don't process the same AttributeProfile twice + break + } + apiRply.CGREvent = evRply.CGREvent + for _, fldName := range evRply.AlteredFields { + if utils.IsSliceMember(apiRply.AlteredFields, fldName) { + continue // only add processed fieldName once + } + apiRply.AlteredFields = append(apiRply.AlteredFields, fldName) + } + } + *reply = *apiRply return } diff --git a/engine/attributes_test.go b/engine/attributes_test.go index 526a86dc2..ae8c0e59c 100644 --- a/engine/attributes_test.go +++ b/engine/attributes_test.go @@ -319,9 +319,9 @@ func TestAttributeProfileForEvent(t *testing.T) { func TestAttributeProcessEvent(t *testing.T) { attrEvs[0].CGREvent.Event["Account"] = "1010" //Field added in event after process eRply := &AttrSProcessEventReply{ - MatchedProfile: "AttributeProfile1", - AlteredFields: []string{"Account"}, - CGREvent: &attrEvs[0].CGREvent, + MatchedProfiles: []string{"AttributeProfile1"}, + AlteredFields: []string{"Account"}, + CGREvent: &attrEvs[0].CGREvent, } atrp, err := attrService.processEvent(attrEvs[0]) if err != nil { @@ -343,9 +343,9 @@ func TestAttributeProcessEventWithIDs(t *testing.T) { attrEvs[3].CGREvent.Event["Account"] = "1010" //Field added in event after process attrEvs[3].AttributeIDs = []string{"AttributeIDMatch"} eRply := &AttrSProcessEventReply{ - MatchedProfile: "AttributeIDMatch", - AlteredFields: []string{"Account"}, - CGREvent: &attrEvs[3].CGREvent, + MatchedProfiles: []string{"AttributeIDMatch"}, + AlteredFields: []string{"Account"}, + CGREvent: &attrEvs[3].CGREvent, } if atrp, err := attrService.processEvent(attrEvs[3]); err != nil { } else if !reflect.DeepEqual(eRply, atrp) { @@ -355,8 +355,8 @@ func TestAttributeProcessEventWithIDs(t *testing.T) { func TestAttributeEventReplyDigest(t *testing.T) { eRpl := &AttrSProcessEventReply{ - MatchedProfile: "ATTR_1", - AlteredFields: []string{utils.Account, utils.Subject}, + MatchedProfiles: []string{"ATTR_1"}, + AlteredFields: []string{utils.Account, utils.Subject}, CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", ID: "testAttributeSProcessEvent", @@ -377,8 +377,8 @@ func TestAttributeEventReplyDigest(t *testing.T) { func TestAttributeEventReplyDigest2(t *testing.T) { eRpl := &AttrSProcessEventReply{ - MatchedProfile: "ATTR_1", - AlteredFields: []string{}, + MatchedProfiles: []string{"ATTR_1"}, + AlteredFields: []string{}, CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", ID: "testAttributeSProcessEvent", @@ -399,8 +399,8 @@ func TestAttributeEventReplyDigest2(t *testing.T) { func TestAttributeEventReplyDigest3(t *testing.T) { eRpl := &AttrSProcessEventReply{ - MatchedProfile: "ATTR_1", - AlteredFields: []string{"Subject"}, + MatchedProfiles: []string{"ATTR_1"}, + AlteredFields: []string{"Subject"}, CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", ID: "testAttributeSProcessEvent", @@ -421,8 +421,8 @@ func TestAttributeEventReplyDigest3(t *testing.T) { func TestAttributeEventReplyDigest4(t *testing.T) { eRpl := &AttrSProcessEventReply{ - MatchedProfile: "ATTR_1", - AlteredFields: []string{"Subject"}, + MatchedProfiles: []string{"ATTR_1"}, + AlteredFields: []string{"Subject"}, CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", ID: "testAttributeSProcessEvent", diff --git a/engine/chargers.go b/engine/chargers.go index 002812f68..95556571b 100644 --- a/engine/chargers.go +++ b/engine/chargers.go @@ -115,7 +115,7 @@ func (cS *ChargerService) processEvent(cgrEv *utils.CGREvent) (rply []*AttrSProc } var evReply AttrSProcessEventReply if err = cS.attrS.Call(utils.AttributeSv1ProcessEvent, - &AttrArgsProcessEvent{cP.AttributeIDs, *clonedEv}, + &AttrArgsProcessEvent{cP.AttributeIDs, nil, *clonedEv}, &evReply); err != nil { return nil, err }