Integration test for AttributeSv1.ProcessEvent

This commit is contained in:
DanB
2017-12-10 18:47:31 +01:00
parent ba42707f7b
commit 175767f6d5
6 changed files with 140 additions and 22 deletions

View File

@@ -90,6 +90,6 @@ func (alSv1 *AttributeSv1) GetAttributeForEvent(ev *utils.CGREvent,
// ProcessEvent will replace event fields with the ones in maching AttributeProfile
func (alSv1 *AttributeSv1) ProcessEvent(ev *utils.CGREvent,
reply *string) error {
reply *engine.AttrSProcessEventReply) error {
return alSv1.attrS.V1ProcessEvent(ev, reply)
}

View File

@@ -51,6 +51,7 @@ var sTestsAlsPrf = []func(t *testing.T){
testAttributeSRPCConn,
testAttributeSLoadFromFolder,
testAttributeSGetAttributeForEvent,
testAttributeSProcessEvent,
testAttributeSGetAlsPrfBeforeSet,
testAttributeSSetAlsPrf,
testAttributeSUpdateAlsPrf,
@@ -144,7 +145,7 @@ func testAttributeSGetAttributeForEvent(t *testing.T) {
"Destination": "+491511231234",
},
}
eAttrPrf := engine.ExternalAttributeProfile{
eAttrPrf := &engine.ExternalAttributeProfile{
Tenant: ev.Tenant,
ID: "ATTR_1",
FilterIDs: []string{"FLTR_ACNT_1007"},
@@ -156,18 +157,18 @@ func testAttributeSGetAttributeForEvent(t *testing.T) {
FieldName: utils.ACCOUNT,
Initial: utils.ANY,
Alias: "1001",
Append: true,
Append: false,
},
&engine.Attribute{
FieldName: utils.SUBJECT,
Initial: utils.ANY,
Alias: "1001",
Append: false,
Append: true,
},
},
Weight: 10.0,
}
eAttrPrf2 := engine.ExternalAttributeProfile{
eAttrPrf2 := &engine.ExternalAttributeProfile{
Tenant: ev.Tenant,
ID: "ATTR_1",
FilterIDs: []string{"FLTR_ACNT_1007"},
@@ -179,13 +180,13 @@ func testAttributeSGetAttributeForEvent(t *testing.T) {
FieldName: utils.SUBJECT,
Initial: utils.ANY,
Alias: "1001",
Append: false,
Append: true,
},
&engine.Attribute{
FieldName: utils.ACCOUNT,
Initial: utils.ANY,
Alias: "1001",
Append: true,
Append: false,
},
},
Weight: 10.0,
@@ -194,13 +195,62 @@ func testAttributeSGetAttributeForEvent(t *testing.T) {
if err := attrSRPC.Call(utils.AttributeSv1GetAttributeForEvent,
ev, &attrReply); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(eAttrPrf, attrReply) &&
!reflect.DeepEqual(eAttrPrf2, attrReply) { // second for reversed order of attributes
} else if !reflect.DeepEqual(eAttrPrf, &attrReply) &&
!reflect.DeepEqual(eAttrPrf2, &attrReply) { // second for reversed order of attributes
t.Errorf("Expecting: %s, received: %s",
utils.ToJSON(eAttrPrf), utils.ToJSON(attrReply))
}
}
func testAttributeSProcessEvent(t *testing.T) {
ev := &utils.CGREvent{
Tenant: "cgrates.org",
ID: "testAttributeSProcessEvent",
Context: utils.StringPointer(utils.ALIAS_CONTEXT_RATING),
Event: map[string]interface{}{
"Account": "1007",
"Destination": "+491511231234",
},
}
eRply := &engine.AttrSProcessEventReply{
MatchedProfile: "ATTR_1",
AlteredFields: []string{"Subject", "Account"},
CGREvent: &utils.CGREvent{
Tenant: "cgrates.org",
ID: "testAttributeSProcessEvent",
Context: utils.StringPointer(utils.ALIAS_CONTEXT_RATING),
Event: map[string]interface{}{
"Account": "1001",
"Subject": "1001",
"Destination": "+491511231234",
},
},
}
eRply2 := &engine.AttrSProcessEventReply{
MatchedProfile: "ATTR_1",
AlteredFields: []string{"Account", "Subject"},
CGREvent: &utils.CGREvent{
Tenant: "cgrates.org",
ID: "testAttributeSProcessEvent",
Context: utils.StringPointer(utils.ALIAS_CONTEXT_RATING),
Event: map[string]interface{}{
"Account": "1001",
"Subject": "1001",
"Destination": "+491511231234",
},
},
}
var rplyEv engine.AttrSProcessEventReply
if err := attrSRPC.Call(utils.AttributeSv1ProcessEvent,
ev, &rplyEv); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(eRply, &rplyEv) &&
!reflect.DeepEqual(eRply2, &rplyEv) { // second for reversed order of attributes
t.Errorf("Expecting: %s, received: %s",
utils.ToJSON(eRply), utils.ToJSON(rplyEv))
}
}
func testAttributeSSetAlsPrf(t *testing.T) {
alsPrf = &engine.ExternalAttributeProfile{
Tenant: "cgrates.org",

View File

@@ -1,3 +1,3 @@
#Tenant,ID,FilterIDs,ActivationInterval,Context,FieldName,Initial,Alias,Append,Weight
cgrates.org,ATTR_1,FLTR_ACNT_1007,2014-01-14T00:00:00Z,*rating,Account,*any,1001,true,10
cgrates.org,ATTR_1,,,,Subject,*any,1001,false,
cgrates.org,ATTR_1,FLTR_ACNT_1007,2014-01-14T00:00:00Z,*rating,Account,*any,1001,false,10
cgrates.org,ATTR_1,,,,Subject,*any,1001,true,
1 #Tenant ID FilterIDs ActivationInterval Context FieldName Initial Alias Append Weight
2 cgrates.org ATTR_1 FLTR_ACNT_1007 2014-01-14T00:00:00Z *rating Account *any 1001 true false 10
3 cgrates.org ATTR_1 Subject *any 1001 false true

View File

@@ -98,31 +98,80 @@ func (alS *AttributeService) matchingAttributeProfilesForEvent(ev *utils.CGREven
return
}
func (alS *AttributeService) attributeProfileForEvent(ev *utils.CGREvent) (alsPrfl *AttributeProfile, err error) {
var alsPrfls AttributeProfiles
if alsPrfls, err = alS.matchingAttributeProfilesForEvent(ev); err != nil {
func (alS *AttributeService) attributeProfileForEvent(ev *utils.CGREvent) (attrPrfl *AttributeProfile, err error) {
var attrPrfls AttributeProfiles
if attrPrfls, err = alS.matchingAttributeProfilesForEvent(ev); err != nil {
return
} else if len(alsPrfls) == 0 {
} else if len(attrPrfls) == 0 {
return nil, utils.ErrNotFound
}
return alsPrfls[0], nil
return attrPrfls[0], nil
}
type AttrSProcessEventReply struct {
MatchedProfile string
AlteredFields []string
CGREvent *utils.CGREvent
}
// processEvent will match event with attribute profile and do the necessary replacements
func (alS *AttributeService) processEvent(ev *utils.CGREvent) (rply *AttrSProcessEventReply, err error) {
attrPrf, err := alS.attributeProfileForEvent(ev)
if err != nil {
return nil, err
}
rply = &AttrSProcessEventReply{MatchedProfile: attrPrf.ID, CGREvent: ev.Clone()}
for fldName, intialMp := range attrPrf.Attributes {
initEvValIf, has := ev.Event[fldName]
if !has { // we don't have initial in event, try append
if anyInitial, has := intialMp[utils.ANY]; has && anyInitial.Append {
rply.CGREvent.Event[fldName] = anyInitial.Alias
rply.AlteredFields = append(rply.AlteredFields, fldName)
}
continue
}
initEvVal, cast := utils.CastFieldIfToString(initEvValIf)
if !cast {
utils.Logger.Warning(
fmt.Sprintf("<%s> ev: %s, cannot cast field: %s to string",
utils.AttributeS, ev, fldName))
continue
}
attrVal, has := intialMp[initEvVal]
if !has {
attrVal, has = intialMp[utils.ANY]
}
if has {
rply.CGREvent.Event[fldName] = attrVal.Alias
rply.AlteredFields = append(rply.AlteredFields, fldName)
}
}
return
}
func (alS *AttributeService) V1GetAttributeForEvent(ev *utils.CGREvent,
extAlsPrf *ExternalAttributeProfile) (err error) {
alsPrf, err := alS.attributeProfileForEvent(ev)
extattrPrf *ExternalAttributeProfile) (err error) {
attrPrf, err := alS.attributeProfileForEvent(ev)
if err != nil {
if err != utils.ErrNotFound {
err = utils.NewErrServerError(err)
}
return err
}
eAlsPrfl := NewExternalAttributeProfileFromAttributeProfile(alsPrf)
*extAlsPrf = *eAlsPrfl
eattrPrfl := NewExternalAttributeProfileFromAttributeProfile(attrPrf)
*extattrPrf = *eattrPrfl
return
}
func (alS *AttributeService) V1ProcessEvent(ev *utils.CGREvent,
reply *string) (err error) {
reply *AttrSProcessEventReply) (err error) {
evReply, err := alS.processEvent(ev)
if err != nil {
if err != utils.ErrNotFound {
err = utils.NewErrServerError(err)
}
return err
}
*reply = *evReply
return
}

View File

@@ -29,7 +29,7 @@ import (
type CGREvent struct {
Tenant string
ID string
Context string // attach the event to a context
Context *string // attach the event to a context
Time *time.Time // event time
Event map[string]interface{}
}
@@ -142,3 +142,21 @@ func (ev *CGREvent) FilterableEvent(fltredFields []string) (fEv map[string]inter
}
return
}
func (ev *CGREvent) Clone() (clned *CGREvent) {
clned = &CGREvent{
Tenant: ev.Tenant,
ID: ev.ID,
Event: make(map[string]interface{}), // a bit forced but safe
}
if ev.Context != nil {
clned.Context = StringPointer(*ev.Context)
}
if ev.Time != nil {
clned.Time = TimePointer(*ev.Time)
}
for k, v := range ev.Event {
clned.Event[k] = v
}
return
}

View File

@@ -630,6 +630,7 @@ const (
// AliasS APIs
const (
AttributeSv1GetAttributeForEvent = "AttributeSv1.GetAttributeForEvent"
AttributeSv1ProcessEvent = "AttributeSv1.ProcessEvent"
)
func buildCacheInstRevPrefixes() {