mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-21 23:28:44 +05:00
Integration test for AttributeSv1.ProcessEvent
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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,
|
||||
|
||||
|
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -630,6 +630,7 @@ const (
|
||||
// AliasS APIs
|
||||
const (
|
||||
AttributeSv1GetAttributeForEvent = "AttributeSv1.GetAttributeForEvent"
|
||||
AttributeSv1ProcessEvent = "AttributeSv1.ProcessEvent"
|
||||
)
|
||||
|
||||
func buildCacheInstRevPrefixes() {
|
||||
|
||||
Reference in New Issue
Block a user