Avoid panic error for Attributes (Substitute:*none) and update test with new modify

This commit is contained in:
TeoV
2018-02-15 15:36:40 +02:00
committed by Dan Christian Bogos
parent 0e35021fe1
commit 296ef1bf97
10 changed files with 284 additions and 145 deletions

View File

@@ -181,6 +181,9 @@ func (sm *FSsessions) onChannelPark(fsev FSEvent, connId string) {
if authArgs.GetAttributes {
if authReply.Attributes != nil {
for _, fldName := range authReply.Attributes.AlteredFields {
if _, has := authReply.Attributes.CGREvent.Event[fldName]; !has {
continue //maybe removed
}
if _, err := sm.conns[connId].SendApiCmd(
fmt.Sprintf("uuid_setvar %s %s %s\n\n", fsev.GetUUID(), fldName,
authReply.Attributes.CGREvent.Event[fldName])); err != nil {

View File

@@ -56,6 +56,7 @@ var sTestsAlsPrf = []func(t *testing.T){
testAttributeSProcessEvent,
testAttributeSProcessEventWithNoneSubstitute,
testAttributeSProcessEventWithNoneSubstitute2,
testAttributeSProcessEventWithNoneSubstitute3,
testAttributeSGetAlsPrfBeforeSet,
testAttributeSSetAlsPrf,
testAttributeSUpdateAlsPrf,
@@ -146,7 +147,7 @@ func testAttributeSGetAttributeForEvent(t *testing.T) {
ev := &utils.CGREvent{
Tenant: "cgrates.org",
ID: "testAttributeSGetAttributeForEvent",
Context: utils.StringPointer(utils.MetaRating),
Context: utils.StringPointer(utils.MetaSessionS),
Event: map[string]interface{}{
utils.Account: "1007",
utils.Destination: "+491511231234",
@@ -156,7 +157,7 @@ func testAttributeSGetAttributeForEvent(t *testing.T) {
Tenant: ev.Tenant,
ID: "ATTR_1",
FilterIDs: []string{"*string:Account:1007"},
Contexts: []string{utils.MetaRating},
Contexts: []string{utils.MetaSessionS, utils.MetaCDRs},
ActivationInterval: &utils.ActivationInterval{
ActivationTime: time.Date(2014, 1, 14, 0, 0, 0, 0, time.UTC)},
Attributes: []*engine.Attribute{
@@ -199,7 +200,7 @@ func testAttributeSGetAttributeForEventNotFound(t *testing.T) {
Tenant: ev.Tenant,
ID: "ATTR_3",
FilterIDs: []string{"*string:Account:dan"},
Contexts: []string{utils.MetaRating},
Contexts: []string{utils.MetaSessionS},
ActivationInterval: &utils.ActivationInterval{
ActivationTime: time.Date(2014, 1, 14, 0, 0, 0, 0, time.UTC)},
Attributes: []*engine.Attribute{
@@ -285,7 +286,7 @@ func testAttributeSProcessEvent(t *testing.T) {
ev := &utils.CGREvent{
Tenant: "cgrates.org",
ID: "testAttributeSProcessEvent",
Context: utils.StringPointer(utils.MetaRating),
Context: utils.StringPointer(utils.MetaSessionS),
Event: map[string]interface{}{
utils.Account: "1007",
utils.Destination: "+491511231234",
@@ -293,11 +294,11 @@ func testAttributeSProcessEvent(t *testing.T) {
}
eRply := &engine.AttrSProcessEventReply{
MatchedProfile: "ATTR_1",
AlteredFields: []string{"Subject", "Account"},
AlteredFields: []string{utils.Subject, utils.Account},
CGREvent: &utils.CGREvent{
Tenant: "cgrates.org",
ID: "testAttributeSProcessEvent",
Context: utils.StringPointer(utils.MetaRating),
Context: utils.StringPointer(utils.MetaSessionS),
Event: map[string]interface{}{
utils.Account: "1001",
utils.Subject: "1001",
@@ -307,14 +308,14 @@ func testAttributeSProcessEvent(t *testing.T) {
}
eRply2 := &engine.AttrSProcessEventReply{
MatchedProfile: "ATTR_1",
AlteredFields: []string{"Account", "Subject"},
AlteredFields: []string{utils.Account, utils.Subject},
CGREvent: &utils.CGREvent{
Tenant: "cgrates.org",
ID: "testAttributeSProcessEvent",
Context: utils.StringPointer(utils.MetaRating),
Context: utils.StringPointer(utils.MetaSessionS),
Event: map[string]interface{}{
"Account": "1001",
"Subject": "1001",
utils.Account: "1001",
utils.Subject: "1001",
"Destination": "+491511231234",
},
},
@@ -334,7 +335,7 @@ func testAttributeSProcessEventWithNoneSubstitute(t *testing.T) {
ev := &utils.CGREvent{
Tenant: "cgrates.org",
ID: "testAttributeSWithNoneSubstitute",
Context: utils.StringPointer(utils.MetaRating),
Context: utils.StringPointer(utils.MetaSessionS),
Event: map[string]interface{}{
utils.Account: "1008",
utils.Destination: "+491511231234",
@@ -343,7 +344,7 @@ func testAttributeSProcessEventWithNoneSubstitute(t *testing.T) {
alsPrf = &engine.AttributeProfile{
Tenant: "cgrates.org",
ID: "AttributeWithNonSubstitute",
Contexts: []string{"*rating"},
Contexts: []string{utils.MetaSessionS, utils.MetaCDRs},
FilterIDs: []string{"*string:Account:1008"},
ActivationInterval: &utils.ActivationInterval{
ActivationTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC),
@@ -351,14 +352,14 @@ func testAttributeSProcessEventWithNoneSubstitute(t *testing.T) {
},
Attributes: []*engine.Attribute{
&engine.Attribute{
FieldName: "Account",
FieldName: utils.Account,
Initial: "1008",
Substitute: "1001",
Append: false,
},
&engine.Attribute{
FieldName: "Subject",
Initial: "*any",
FieldName: utils.Subject,
Initial: utils.ANY,
Substitute: "*none",
Append: true,
},
@@ -373,11 +374,24 @@ func testAttributeSProcessEventWithNoneSubstitute(t *testing.T) {
}
eRply := &engine.AttrSProcessEventReply{
MatchedProfile: "AttributeWithNonSubstitute",
AlteredFields: []string{"Account"},
AlteredFields: []string{utils.Account, utils.Subject},
CGREvent: &utils.CGREvent{
Tenant: "cgrates.org",
ID: "testAttributeSWithNoneSubstitute",
Context: utils.StringPointer(utils.MetaRating),
Context: utils.StringPointer(utils.MetaSessionS),
Event: map[string]interface{}{
utils.Account: "1001",
utils.Destination: "+491511231234",
},
},
}
eRply2 := &engine.AttrSProcessEventReply{
MatchedProfile: "AttributeWithNonSubstitute",
AlteredFields: []string{utils.Subject, utils.Account},
CGREvent: &utils.CGREvent{
Tenant: "cgrates.org",
ID: "testAttributeSWithNoneSubstitute",
Context: utils.StringPointer(utils.MetaSessionS),
Event: map[string]interface{}{
utils.Account: "1001",
utils.Destination: "+491511231234",
@@ -388,7 +402,8 @@ func testAttributeSProcessEventWithNoneSubstitute(t *testing.T) {
if err := attrSRPC.Call(utils.AttributeSv1ProcessEvent,
ev, &rplyEv); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(eRply, &rplyEv) {
} else if !reflect.DeepEqual(eRply, &rplyEv) &&
!reflect.DeepEqual(eRply2, &rplyEv) {
t.Errorf("Expecting: %s, received: %s",
utils.ToJSON(eRply), utils.ToJSON(rplyEv))
}
@@ -398,7 +413,7 @@ func testAttributeSProcessEventWithNoneSubstitute2(t *testing.T) {
ev := &utils.CGREvent{
Tenant: "cgrates.org",
ID: "testAttributeSWithNoneSubstitute",
Context: utils.StringPointer(utils.MetaRating),
Context: utils.StringPointer(utils.MetaSessionS),
Event: map[string]interface{}{
utils.Account: "1008",
utils.Subject: "1008",
@@ -408,7 +423,7 @@ func testAttributeSProcessEventWithNoneSubstitute2(t *testing.T) {
alsPrf = &engine.AttributeProfile{
Tenant: "cgrates.org",
ID: "AttributeWithNonSubstitute",
Contexts: []string{"*rating"},
Contexts: []string{utils.MetaSessionS},
FilterIDs: []string{"*string:Account:1008"},
ActivationInterval: &utils.ActivationInterval{
ActivationTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC),
@@ -416,15 +431,15 @@ func testAttributeSProcessEventWithNoneSubstitute2(t *testing.T) {
},
Attributes: []*engine.Attribute{
&engine.Attribute{
FieldName: "Account",
FieldName: utils.Account,
Initial: "1008",
Substitute: "1001",
Append: false,
},
&engine.Attribute{
FieldName: "Subject",
Initial: "*any",
Substitute: "*none",
FieldName: utils.Subject,
Initial: utils.ANY,
Substitute: utils.META_NONE,
Append: false,
},
},
@@ -438,11 +453,24 @@ func testAttributeSProcessEventWithNoneSubstitute2(t *testing.T) {
}
eRply := &engine.AttrSProcessEventReply{
MatchedProfile: "AttributeWithNonSubstitute",
AlteredFields: []string{"Account"},
AlteredFields: []string{"Account", "Subject"},
CGREvent: &utils.CGREvent{
Tenant: "cgrates.org",
ID: "testAttributeSWithNoneSubstitute",
Context: utils.StringPointer(utils.MetaRating),
Context: utils.StringPointer(utils.MetaSessionS),
Event: map[string]interface{}{
utils.Account: "1001",
utils.Destination: "+491511231234",
},
},
}
eRply2 := &engine.AttrSProcessEventReply{
MatchedProfile: "AttributeWithNonSubstitute",
AlteredFields: []string{utils.Subject, utils.Account},
CGREvent: &utils.CGREvent{
Tenant: "cgrates.org",
ID: "testAttributeSWithNoneSubstitute",
Context: utils.StringPointer(utils.MetaSessionS),
Event: map[string]interface{}{
utils.Account: "1001",
utils.Destination: "+491511231234",
@@ -453,7 +481,86 @@ func testAttributeSProcessEventWithNoneSubstitute2(t *testing.T) {
if err := attrSRPC.Call(utils.AttributeSv1ProcessEvent,
ev, &rplyEv); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(eRply, &rplyEv) {
} else if !reflect.DeepEqual(eRply, &rplyEv) &&
!reflect.DeepEqual(eRply2, &rplyEv) {
t.Errorf("Expecting: %s, received: %s",
utils.ToJSON(eRply), utils.ToJSON(rplyEv))
}
}
func testAttributeSProcessEventWithNoneSubstitute3(t *testing.T) {
ev := &utils.CGREvent{
Tenant: "cgrates.org",
ID: "testAttributeSWithNoneSubstitute",
Context: utils.StringPointer(utils.MetaSessionS),
Event: map[string]interface{}{
utils.Account: "1008",
utils.Destination: "+491511231234",
},
}
alsPrf = &engine.AttributeProfile{
Tenant: "cgrates.org",
ID: "AttributeWithNonSubstitute",
Contexts: []string{utils.MetaSessionS},
FilterIDs: []string{"*string:Account:1008"},
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),
},
Attributes: []*engine.Attribute{
&engine.Attribute{
FieldName: utils.Account,
Initial: "1008",
Substitute: "1001",
Append: false,
},
&engine.Attribute{
FieldName: utils.Subject,
Initial: "1008",
Substitute: utils.META_NONE,
Append: false,
},
},
Weight: 20,
}
var result string
if err := attrSRPC.Call("ApierV1.SetAttributeProfile", alsPrf, &result); err != nil {
t.Error(err)
} else if result != utils.OK {
t.Error("Unexpected reply returned", result)
}
eRply := &engine.AttrSProcessEventReply{
MatchedProfile: "AttributeWithNonSubstitute",
AlteredFields: []string{"Account", "Subject"},
CGREvent: &utils.CGREvent{
Tenant: "cgrates.org",
ID: "testAttributeSWithNoneSubstitute",
Context: utils.StringPointer(utils.MetaSessionS),
Event: map[string]interface{}{
utils.Account: "1001",
utils.Destination: "+491511231234",
},
},
}
eRply2 := &engine.AttrSProcessEventReply{
MatchedProfile: "AttributeWithNonSubstitute",
AlteredFields: []string{utils.Subject, utils.Account},
CGREvent: &utils.CGREvent{
Tenant: "cgrates.org",
ID: "testAttributeSWithNoneSubstitute",
Context: utils.StringPointer(utils.MetaSessionS),
Event: map[string]interface{}{
utils.Account: "1001",
utils.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) {
t.Errorf("Expecting: %s, received: %s",
utils.ToJSON(eRply), utils.ToJSON(rplyEv))
}
@@ -463,7 +570,7 @@ func testAttributeSSetAlsPrf(t *testing.T) {
alsPrf = &engine.AttributeProfile{
Tenant: "cgrates.org",
ID: "ApierTest",
Contexts: []string{"*rating"},
Contexts: []string{utils.MetaSessionS, utils.MetaCDRs},
FilterIDs: []string{"FLTR_ACNT_dan", "FLTR_DST_DE"},
ActivationInterval: &utils.ActivationInterval{
ActivationTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC),

View File

@@ -1280,7 +1280,7 @@ func testV1FIdxSetAttributeProfileIndexes(t *testing.T) {
alsPrf = &engine.AttributeProfile{
Tenant: "cgrates.org",
ID: "ApierTest",
Contexts: []string{"*rating"},
Contexts: []string{utils.MetaSessionS},
FilterIDs: []string{"FLTR_1"},
ActivationInterval: &utils.ActivationInterval{
ActivationTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC),
@@ -1392,7 +1392,7 @@ func testV1FIdxSetSecondAttributeProfileIndexes(t *testing.T) {
alsPrf = &engine.AttributeProfile{
Tenant: "cgrates.org",
ID: "ApierTest2",
Contexts: []string{"*rating"},
Contexts: []string{utils.MetaSessionS},
FilterIDs: []string{"FLTR_2"},
ActivationInterval: &utils.ActivationInterval{
ActivationTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC),
@@ -1493,13 +1493,13 @@ func testV1FIdxRemoveAttributeProfile(t *testing.T) {
t.Errorf("Error: %+v", reply2)
}
if err := tFIdxRpc.Call("ApierV1.RemAttributeProfile",
&ArgRemoveAttrProfile{Tenant: "cgrates.org", ID: "ApierTest", Contexts: []string{"*rating"}}, &resp); err != nil {
&ArgRemoveAttrProfile{Tenant: "cgrates.org", ID: "ApierTest", Contexts: []string{utils.MetaSessionS}}, &resp); err != nil {
t.Error(err)
} else if resp != utils.OK {
t.Error("Unexpected reply returned", resp)
}
if err := tFIdxRpc.Call("ApierV1.RemAttributeProfile",
&ArgRemoveAttrProfile{Tenant: "cgrates.org", ID: "ApierTest2", Contexts: []string{"*rating"}}, &resp); err != nil {
&ArgRemoveAttrProfile{Tenant: "cgrates.org", ID: "ApierTest2", Contexts: []string{utils.MetaSessionS}}, &resp); err != nil {
t.Error(err)
} else if resp != utils.OK {
t.Error("Unexpected reply returned", resp)

View File

@@ -196,7 +196,7 @@ func testV1FIdxCaSetThresholdProfile(t *testing.T) {
ID: "TestFilter",
Rules: []*engine.FilterRule{
&engine.FilterRule{
FieldName: "Account",
FieldName: utils.Account,
Type: "*string",
Values: []string{"1001"},
},
@@ -305,7 +305,7 @@ func testV1FIdxCaUpdateThresholdProfile(t *testing.T) {
ID: "TestFilter2",
Rules: []*engine.FilterRule{
&engine.FilterRule{
FieldName: "Account",
FieldName: utils.Account,
Type: "*string",
Values: []string{"1002"},
},
@@ -392,7 +392,7 @@ func testV1FIdxCaUpdateThresholdProfileFromTP(t *testing.T) {
ID: "TestFilter3",
Rules: []*engine.FilterRule{
&engine.FilterRule{
FieldName: "Account",
FieldName: utils.Account,
Type: "*string",
Values: []string{"1003"},
},
@@ -575,7 +575,7 @@ func testV1FIdxCaSetStatQueueProfile(t *testing.T) {
ID: "FLTR_1",
Rules: []*engine.FilterRule{
&engine.FilterRule{
FieldName: "Account",
FieldName: utils.Account,
Type: "*string",
Values: []string{"1001"},
},
@@ -720,7 +720,7 @@ func testV1FIdxCaUpdateStatQueueProfile(t *testing.T) {
ID: "FLTR_2",
Rules: []*engine.FilterRule{
&engine.FilterRule{
FieldName: "Account",
FieldName: utils.Account,
Type: "*string",
Values: []string{"1002"},
},
@@ -796,7 +796,7 @@ func testV1FIdxCaUpdateStatQueueProfileFromTP(t *testing.T) {
ID: "FLTR_3",
Rules: []*engine.FilterRule{
&engine.FilterRule{
FieldName: "Account",
FieldName: utils.Account,
Type: "*string",
Values: []string{"1003"},
},
@@ -930,10 +930,10 @@ func testV1FIdxCaProcessAttributeProfileEventWithNotFound(t *testing.T) {
ev := &utils.CGREvent{
Tenant: "cgrates.org",
ID: "testAttributeSProcessEvent",
Context: utils.StringPointer(utils.MetaRating),
Context: utils.StringPointer(utils.MetaSessionS),
Event: map[string]interface{}{
"Account": "3009",
"Destination": "+492511231234",
utils.Account: "3009",
utils.Destination: "+492511231234",
},
}
var rplyEv engine.AttrSProcessEventReply
@@ -953,12 +953,12 @@ func testV1FIdxCaSetAttributeProfile(t *testing.T) {
ID: "TestFilter",
Rules: []*engine.FilterRule{
&engine.FilterRule{
FieldName: "Account",
FieldName: utils.Account,
Type: "*string",
Values: []string{"1009"},
},
&engine.FilterRule{
FieldName: "Destination",
FieldName: utils.Destination,
Type: "*string",
Values: []string{"+491511231234"},
},
@@ -976,21 +976,21 @@ func testV1FIdxCaSetAttributeProfile(t *testing.T) {
alsPrf := &engine.AttributeProfile{
Tenant: "cgrates.org",
ID: "TEST_PROFILE1",
Contexts: []string{"*rating"},
Contexts: []string{utils.MetaSessionS},
FilterIDs: []string{"TestFilter"},
ActivationInterval: &utils.ActivationInterval{
ActivationTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC),
},
Attributes: []*engine.Attribute{
&engine.Attribute{
FieldName: "Account",
Initial: "*any",
FieldName: utils.Account,
Initial: utils.META_ANY,
Substitute: "1001",
Append: false,
},
&engine.Attribute{
FieldName: "Subject",
Initial: "*any",
FieldName: utils.Subject,
Initial: utils.META_ANY,
Substitute: "1001",
Append: true,
},
@@ -1006,10 +1006,10 @@ func testV1FIdxCaSetAttributeProfile(t *testing.T) {
ev := &utils.CGREvent{
Tenant: "cgrates.org",
ID: "testAttributeSProcessEvent",
Context: utils.StringPointer(utils.MetaRating),
Context: utils.StringPointer(utils.MetaSessionS),
Event: map[string]interface{}{
"Account": "1009",
"Destination": "+491511231234",
utils.Account: "1009",
utils.Destination: "+491511231234",
},
}
var rplyEv engine.AttrSProcessEventReply
@@ -1019,7 +1019,7 @@ func testV1FIdxCaSetAttributeProfile(t *testing.T) {
//test to make sure indexes are made as expected
fldNameVal := map[string]string{"TEST_PROFILE1": ""}
expectedRevIDX := map[string]utils.StringMap{"TEST_PROFILE1": {"*string:Account:1009": true, "*string:Destination:+491511231234": true}}
if indexes, err = onStor.GetFilterReverseIndexes(engine.GetDBIndexKey(utils.AttributeProfilePrefix, "cgrates.org:*rating", true),
if indexes, err = onStor.GetFilterReverseIndexes(engine.GetDBIndexKey(utils.AttributeProfilePrefix, "cgrates.org:*sessions", true),
fldNameVal); err != nil {
t.Error(err)
}
@@ -1033,10 +1033,10 @@ func testV1FIdxCaGetAttributeProfileFromTP(t *testing.T) {
ev := &utils.CGREvent{
Tenant: "cgrates.org",
ID: "testAttributeSProcessEvent",
Context: utils.StringPointer(utils.MetaRating),
Context: utils.StringPointer(utils.MetaSessionS),
Event: map[string]interface{}{
"Account": "1007",
"Destination": "+491511231234",
utils.Account: "1007",
utils.Destination: "+491511231234",
},
}
var rplyEv engine.AttrSProcessEventReply
@@ -1046,7 +1046,7 @@ func testV1FIdxCaGetAttributeProfileFromTP(t *testing.T) {
//test to make sure indexes are made as expected
idx := map[string]utils.StringMap{"ATTR_1": {"*string:Account:1007": true}}
fldNameVal := map[string]string{"ATTR_1": ""}
if indexes, err = onStor.GetFilterReverseIndexes(engine.GetDBIndexKey(utils.AttributeProfilePrefix, "cgrates.org:*rating", true),
if indexes, err = onStor.GetFilterReverseIndexes(engine.GetDBIndexKey(utils.AttributeProfilePrefix, "cgrates.org:*sessions", true),
fldNameVal); err != nil {
t.Error(err)
}
@@ -1061,12 +1061,12 @@ func testV1FIdxCaUpdateAttributeProfile(t *testing.T) {
ID: "TestFilter2",
Rules: []*engine.FilterRule{
&engine.FilterRule{
FieldName: "Account",
FieldName: utils.Account,
Type: "*string",
Values: []string{"2009"},
},
&engine.FilterRule{
FieldName: "Destination",
FieldName: utils.Destination,
Type: "*string",
Values: []string{"+492511231234"},
},
@@ -1084,20 +1084,20 @@ func testV1FIdxCaUpdateAttributeProfile(t *testing.T) {
alsPrf := &engine.AttributeProfile{
Tenant: "cgrates.org",
ID: "TEST_PROFILE1",
Contexts: []string{"*rating"},
Contexts: []string{utils.MetaSessionS},
FilterIDs: []string{"TestFilter2"},
ActivationInterval: &utils.ActivationInterval{
ActivationTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC),
},
Attributes: []*engine.Attribute{
&engine.Attribute{
FieldName: "Account",
Initial: "*any",
FieldName: utils.Account,
Initial: utils.META_ANY,
Substitute: "1001",
Append: false,
},
&engine.Attribute{
FieldName: "Subject",
FieldName: utils.Subject,
Initial: "*any",
Substitute: "1001",
Append: true,
@@ -1114,10 +1114,10 @@ func testV1FIdxCaUpdateAttributeProfile(t *testing.T) {
ev := &utils.CGREvent{
Tenant: "cgrates.org",
ID: "testAttributeSProcessEvent",
Context: utils.StringPointer(utils.MetaRating),
Context: utils.StringPointer(utils.MetaSessionS),
Event: map[string]interface{}{
"Account": "2009",
"Destination": "+492511231234",
utils.Account: "2009",
utils.Destination: "+492511231234",
},
}
var rplyEv engine.AttrSProcessEventReply
@@ -1127,7 +1127,7 @@ func testV1FIdxCaUpdateAttributeProfile(t *testing.T) {
//test to make sure indexes are made as expected
idx := map[string]utils.StringMap{"TEST_PROFILE1": {"*string:Account:2009": true, "*string:Destination:+492511231234": true}}
fldNameVal := map[string]string{"TEST_PROFILE1": ""}
if indexes, err = onStor.GetFilterReverseIndexes(engine.GetDBIndexKey(utils.AttributeProfilePrefix, "cgrates.org:*rating", true),
if indexes, err = onStor.GetFilterReverseIndexes(engine.GetDBIndexKey(utils.AttributeProfilePrefix, "cgrates.org:*sessions", true),
fldNameVal); err != nil {
t.Error(err)
}
@@ -1142,12 +1142,12 @@ func testV1FIdxCaUpdateAttributeProfileFromTP(t *testing.T) {
ID: "TestFilter3",
Rules: []*engine.FilterRule{
&engine.FilterRule{
FieldName: "Account",
FieldName: utils.Account,
Type: "*string",
Values: []string{"3009"},
},
&engine.FilterRule{
FieldName: "Destination",
FieldName: utils.Destination,
Type: "*string",
Values: []string{"+492511231234"},
},
@@ -1176,10 +1176,10 @@ func testV1FIdxCaUpdateAttributeProfileFromTP(t *testing.T) {
ev := &utils.CGREvent{
Tenant: "cgrates.org",
ID: "testAttributeSProcessEvent",
Context: utils.StringPointer(utils.MetaRating),
Context: utils.StringPointer(utils.MetaSessionS),
Event: map[string]interface{}{
"Account": "3009",
"Destination": "+492511231234",
utils.Account: "3009",
utils.Destination: "+492511231234",
},
}
var rplyEv engine.AttrSProcessEventReply
@@ -1189,7 +1189,7 @@ func testV1FIdxCaUpdateAttributeProfileFromTP(t *testing.T) {
//test to make sure indexes are made as expected
idx := map[string]utils.StringMap{"ATTR_1": {"*string:Account:3009": true, "*string:Destination:+492511231234": true}}
fldNameVal := map[string]string{"ATTR_1": ""}
if indexes, err = onStor.GetFilterReverseIndexes(engine.GetDBIndexKey(utils.AttributeProfilePrefix, "cgrates.org:*rating", true),
if indexes, err = onStor.GetFilterReverseIndexes(engine.GetDBIndexKey(utils.AttributeProfilePrefix, "cgrates.org:*sessions", true),
fldNameVal); err != nil {
t.Error(err)
}
@@ -1203,10 +1203,10 @@ func testV1FIdxCaRemoveAttributeProfile(t *testing.T) {
ev := &utils.CGREvent{
Tenant: "cgrates.org",
ID: "testAttributeSProcessEvent",
Context: utils.StringPointer(utils.MetaRating),
Context: utils.StringPointer(utils.MetaSessionS),
Event: map[string]interface{}{
"Account": "3009",
"Destination": "+492511231234",
utils.Account: "3009",
utils.Destination: "+492511231234",
},
}
var rplyEv engine.AttrSProcessEventReply
@@ -1217,10 +1217,10 @@ func testV1FIdxCaRemoveAttributeProfile(t *testing.T) {
ev2 := &utils.CGREvent{
Tenant: "cgrates.org",
ID: "testAttributeSProcessEvent",
Context: utils.StringPointer(utils.MetaRating),
Context: utils.StringPointer(utils.MetaSessionS),
Event: map[string]interface{}{
"Account": "2009",
"Destination": "+492511231234",
utils.Account: "2009",
utils.Destination: "+492511231234",
},
}
if err := tFIdxCaRpc.Call(utils.AttributeSv1ProcessEvent, ev2, &rplyEv); err != nil {
@@ -1228,7 +1228,7 @@ func testV1FIdxCaRemoveAttributeProfile(t *testing.T) {
}
//Remove threshold profile that was set form api
if err := tFIdxCaRpc.Call("ApierV1.RemAttributeProfile", &ArgRemoveAttrProfile{Tenant: "cgrates.org",
ID: "TEST_PROFILE1", Contexts: []string{"*rating"}}, &resp); err != nil {
ID: "TEST_PROFILE1", Contexts: []string{utils.MetaSessionS}}, &resp); err != nil {
t.Error(err)
} else if resp != utils.OK {
t.Error("Unexpected reply returned", resp)
@@ -1242,7 +1242,7 @@ func testV1FIdxCaRemoveAttributeProfile(t *testing.T) {
}
//Remove threshold profile that was set form tariffplan
if err := tFIdxCaRpc.Call("ApierV1.RemAttributeProfile", &ArgRemoveAttrProfile{Tenant: "cgrates.org",
ID: "ATTR_1", Contexts: []string{"*rating"}}, &resp); err != nil {
ID: "ATTR_1", Contexts: []string{utils.MetaSessionS}}, &resp); err != nil {
t.Error(err)
} else if resp != utils.OK {
t.Error("Unexpected reply returned", resp)
@@ -1277,9 +1277,9 @@ func testV1FIdxCaGetResourceProfileWithNotFound(t *testing.T) {
CGREvent: utils.CGREvent{
Tenant: "cgrates.org",
Event: map[string]interface{}{
"Account": "1002",
"Subject": "1001",
"Destination": "1002"},
utils.Account: "1002",
utils.Subject: "1001",
utils.Destination: "1002"},
},
Units: 6,
}
@@ -1302,17 +1302,17 @@ func testV1FIdxCaSetResourceProfile(t *testing.T) {
ID: "FLTR_RES_RCFG1",
Rules: []*engine.FilterRule{
&engine.FilterRule{
FieldName: "Account",
FieldName: utils.Account,
Type: "*string",
Values: []string{"1001"},
},
&engine.FilterRule{
FieldName: "Subject",
FieldName: utils.Subject,
Type: "*string",
Values: []string{"1002"},
},
&engine.FilterRule{
FieldName: "Destination",
FieldName: utils.Destination,
Type: "*string",
Values: []string{"1001"},
},
@@ -1352,9 +1352,9 @@ func testV1FIdxCaSetResourceProfile(t *testing.T) {
CGREvent: utils.CGREvent{
Tenant: "cgrates.org",
Event: map[string]interface{}{
"Account": "1001",
"Subject": "1002",
"Destination": "1001"},
utils.Account: "1001",
utils.Subject: "1002",
utils.Destination: "1001"},
},
Units: 6,
}
@@ -1389,9 +1389,9 @@ func testV1FIdxCaGetResourceProfileFromTP(t *testing.T) {
CGREvent: utils.CGREvent{
Tenant: "cgrates.org",
Event: map[string]interface{}{
"Account": "1001",
"Subject": "1002",
"Destination": "1001"},
utils.Account: "1001",
utils.Subject: "1002",
utils.Destination: "1001"},
},
Units: 6,
}
@@ -1411,9 +1411,9 @@ func testV1FIdxCaGetResourceProfileFromTP(t *testing.T) {
CGREvent: utils.CGREvent{
Tenant: "cgrates.org",
Event: map[string]interface{}{
"Account": "1002",
"Subject": "1001",
"Destination": "1002"},
utils.Account: "1002",
utils.Subject: "1001",
utils.Destination: "1002"},
},
Units: 6,
}
@@ -1440,17 +1440,17 @@ func testV1FIdxCaUpdateResourceProfile(t *testing.T) {
ID: "FLTR_RES_RCFG2",
Rules: []*engine.FilterRule{
&engine.FilterRule{
FieldName: "Account",
FieldName: utils.Account,
Type: "*string",
Values: []string{"2002"},
},
&engine.FilterRule{
FieldName: "Subject",
FieldName: utils.Subject,
Type: "*string",
Values: []string{"2001"},
},
&engine.FilterRule{
FieldName: "Destination",
FieldName: utils.Destination,
Type: "*string",
Values: []string{"2002"},
},
@@ -1490,9 +1490,9 @@ func testV1FIdxCaUpdateResourceProfile(t *testing.T) {
CGREvent: utils.CGREvent{
Tenant: "cgrates.org",
Event: map[string]interface{}{
"Account": "2002",
"Subject": "2001",
"Destination": "2002"},
utils.Account: "2002",
utils.Subject: "2001",
utils.Destination: "2002"},
},
Units: 6,
}
@@ -1518,17 +1518,17 @@ func testV1FIdxCaUpdateResourceProfileFromTP(t *testing.T) {
ID: "FLTR_RES_RCFG3",
Rules: []*engine.FilterRule{
&engine.FilterRule{
FieldName: "Account",
FieldName: utils.Account,
Type: "*string",
Values: []string{"1002"},
},
&engine.FilterRule{
FieldName: "Subject",
FieldName: utils.Subject,
Type: "*string",
Values: []string{"1001"},
},
&engine.FilterRule{
FieldName: "Destination",
FieldName: utils.Destination,
Type: "*string",
Values: []string{"1002"},
},
@@ -1562,9 +1562,9 @@ func testV1FIdxCaUpdateResourceProfileFromTP(t *testing.T) {
CGREvent: utils.CGREvent{
Tenant: "cgrates.org",
Event: map[string]interface{}{
"Account": "1002",
"Subject": "1001",
"Destination": "1002"},
utils.Account: "1002",
utils.Subject: "1001",
utils.Destination: "1002"},
},
Units: 6,
}
@@ -1591,9 +1591,9 @@ func testV1FIdxCaRemoveResourceProfile(t *testing.T) {
CGREvent: utils.CGREvent{
Tenant: "cgrates.org",
Event: map[string]interface{}{
"Account": "2002",
"Subject": "2001",
"Destination": "2002"},
utils.Account: "2002",
utils.Subject: "2001",
utils.Destination: "2002"},
},
Units: 6,
}
@@ -1612,9 +1612,9 @@ func testV1FIdxCaRemoveResourceProfile(t *testing.T) {
CGREvent: utils.CGREvent{
Tenant: "cgrates.org",
Event: map[string]interface{}{
"Account": "1002",
"Subject": "1001",
"Destination": "1002"},
utils.Account: "1002",
utils.Subject: "1001",
utils.Destination: "1002"},
},
Units: 6,
}

View File

@@ -1,3 +1,3 @@
#Tenant,ID,Contexts,FilterIDs,ActivationInterval,FieldName,Initial,Substitute,Append,Weight
cgrates.org,ATTR_1,*rating,*string:Account:1007,2014-01-14T00:00:00Z,Account,*any,1001,false,10
cgrates.org,ATTR_1,*sessions;*cdrs,*string:Account:1007,2014-01-14T00:00:00Z,Account,*any,1001,false,10
cgrates.org,ATTR_1,,,,Subject,*any,1001,true,
1 #Tenant ID Contexts FilterIDs ActivationInterval FieldName Initial Substitute Append Weight
2 cgrates.org ATTR_1 *rating *sessions;*cdrs *string:Account:1007 2014-01-14T00:00:00Z Account *any 1001 false 10
3 cgrates.org ATTR_1 Subject *any 1001 true

View File

@@ -135,6 +135,9 @@ type AttrSProcessEventReply struct {
// format fldName1:fldVal1,fldName2:fldVal2
func (attrReply *AttrSProcessEventReply) Digest() (rplyDigest string) {
for i, fld := range attrReply.AlteredFields {
if _, has := attrReply.CGREvent.Event[fld]; !has {
continue //maybe removed
}
if i != 0 {
rplyDigest += utils.FIELDS_SEP
}
@@ -151,30 +154,28 @@ func (alS *AttributeService) processEvent(ev *utils.CGREvent) (rply *AttrSProces
return nil, err
}
rply = &AttrSProcessEventReply{MatchedProfile: attrPrf.ID, CGREvent: ev.Clone()}
for fldName, intialMp := range attrPrf.attributes {
for fldName, initialMp := 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 {
if anyInitial.Substitute == interface{}(utils.META_NONE) {
delete(rply.CGREvent.Event, fldName)
} else {
rply.CGREvent.Event[fldName] = anyInitial.Substitute
rply.AlteredFields = append(rply.AlteredFields, fldName)
}
if !has {
anyInitial, hasAny := initialMp[utils.ANY]
if hasAny && anyInitial.Append &&
initialMp[utils.ANY].Substitute != interface{}(utils.META_NONE) {
rply.CGREvent.Event[fldName] = anyInitial.Substitute
}
rply.AlteredFields = append(rply.AlteredFields, fldName)
continue
}
attrVal, has := intialMp[initEvValIf]
attrVal, has := initialMp[initEvValIf]
if !has {
attrVal, has = intialMp[utils.ANY]
attrVal, has = initialMp[utils.ANY]
}
if has {
if attrVal.Substitute == interface{}(utils.META_NONE) {
delete(rply.CGREvent.Event, fldName)
} else {
rply.CGREvent.Event[fldName] = attrVal.Substitute
rply.AlteredFields = append(rply.AlteredFields, fldName)
}
rply.AlteredFields = append(rply.AlteredFields, fldName)
}
for _, valIface := range rply.CGREvent.Event {
if valIface == interface{}(utils.MetaAttributes) {

View File

@@ -31,7 +31,7 @@ var (
expTimeAttributes = time.Now().Add(time.Duration(20 * time.Minute))
srv AttributeService
dmAtr *DataManager
context = utils.MetaRating
context = utils.MetaSessionS
mapSubstitutes = map[string]map[interface{}]*Attribute{
"FL1": map[interface{}]*Attribute{
"In1": &Attribute{
@@ -198,7 +198,7 @@ func TestAttributePopulateAttrService(t *testing.T) {
filterS: &FilterS{dm: dmAtr},
}
ref := NewFilterIndexer(dmAtr, utils.AttributeProfilePrefix,
utils.ConcatenatedKey(config.CgrConfig().DefaultTenant, utils.MetaRating))
utils.ConcatenatedKey(config.CgrConfig().DefaultTenant, utils.MetaSessionS))
for _, atr := range atrPs {
if err = dmAtr.SetAttributeProfile(atr, false); err != nil {
t.Errorf("Error: %+v", err)
@@ -321,6 +321,7 @@ func TestAttributeProfileForEvent(t *testing.T) {
func TestAttributeProcessEvent(t *testing.T) {
eRply := &AttrSProcessEventReply{
MatchedProfile: "attributeprofile1",
AlteredFields: []string{"FL1"},
CGREvent: sev,
}
atrp, err := srv.processEvent(sev)
@@ -336,6 +337,7 @@ func TestAttributeProcessEvent(t *testing.T) {
}
eRply = &AttrSProcessEventReply{
MatchedProfile: "attributeprofile2",
AlteredFields: []string{"FL1"},
CGREvent: sev2,
}
atrp, err = srv.processEvent(sev2)
@@ -351,6 +353,7 @@ func TestAttributeProcessEvent(t *testing.T) {
}
eRply = &AttrSProcessEventReply{
MatchedProfile: "attributeprofile3",
AlteredFields: []string{"FL1"},
CGREvent: sev3,
}
atrp, err = srv.processEvent(sev3)
@@ -366,6 +369,7 @@ func TestAttributeProcessEvent(t *testing.T) {
}
eRply = &AttrSProcessEventReply{
MatchedProfile: "attributeprofile4",
AlteredFields: []string{"FL1"},
CGREvent: sev4,
}
atrp, err = srv.processEvent(sev4)
@@ -384,15 +388,15 @@ func TestAttributeProcessEvent(t *testing.T) {
func TestAttrSProcessEventReplyDigest(t *testing.T) {
eRpl := &AttrSProcessEventReply{
MatchedProfile: "ATTR_1",
AlteredFields: []string{"Account", "Subject"},
AlteredFields: []string{utils.Account, utils.Subject},
CGREvent: &utils.CGREvent{
Tenant: "cgrates.org",
ID: "testAttributeSProcessEvent",
Context: utils.StringPointer(utils.MetaRating),
Context: utils.StringPointer(utils.MetaSessionS),
Event: map[string]interface{}{
"Account": "1001",
"Subject": "1001",
"Destination": "+491511231234",
utils.Account: "1001",
utils.Subject: "1001",
utils.Destinations: "+491511231234",
},
},
}
@@ -410,11 +414,11 @@ func TestAttrSProcessEventReplyDigest2(t *testing.T) {
CGREvent: &utils.CGREvent{
Tenant: "cgrates.org",
ID: "testAttributeSProcessEvent",
Context: utils.StringPointer(utils.MetaRating),
Context: utils.StringPointer(utils.MetaSessionS),
Event: map[string]interface{}{
"Account": "1001",
"Subject": "1001",
"Destination": "+491511231234",
utils.Account: "1001",
utils.Subject: "1001",
utils.Destinations: "+491511231234",
},
},
}
@@ -432,11 +436,11 @@ func TestAttrSProcessEventReplyDigest3(t *testing.T) {
CGREvent: &utils.CGREvent{
Tenant: "cgrates.org",
ID: "testAttributeSProcessEvent",
Context: utils.StringPointer(utils.MetaRating),
Context: utils.StringPointer(utils.MetaSessionS),
Event: map[string]interface{}{
"Account": "1001",
"Subject": "1001",
"Destination": "+491511231234",
utils.Account: "1001",
utils.Subject: "1001",
utils.Destinations: "+491511231234",
},
},
}
@@ -446,3 +450,24 @@ func TestAttrSProcessEventReplyDigest3(t *testing.T) {
t.Errorf("Expecting : %+v, received: %+v", utils.ToJSON(expRpl), utils.ToJSON(val))
}
}
func TestAttrSProcessEventReplyDigest4(t *testing.T) {
eRpl := &AttrSProcessEventReply{
MatchedProfile: "ATTR_1",
AlteredFields: []string{"Subject"},
CGREvent: &utils.CGREvent{
Tenant: "cgrates.org",
ID: "testAttributeSProcessEvent",
Context: utils.StringPointer(utils.MetaSessionS),
Event: map[string]interface{}{
utils.Account: "1001",
utils.Destinations: "+491511231234",
},
},
}
expRpl := ""
val := eRpl.Digest()
if !reflect.DeepEqual(val, expRpl) {
t.Errorf("Expecting : %+v, received: %+v", utils.ToJSON(expRpl), utils.ToJSON(val))
}
}

View File

@@ -804,6 +804,9 @@ func (cdr *CDR) AsCGREvent() *utils.CGREvent {
// UpdateFromCGREvent will update CDR with event fields from CGREvent
func (cdr *CDR) UpdateFromCGREvent(cgrEv *utils.CGREvent, fields []string) (err error) {
for _, fldName := range fields {
if _, has := cgrEv.Event[fldName]; !has {
continue //maybe removed
}
switch fldName {
case utils.OriginHost:
if cdr.OriginHost, err = cgrEv.FieldAsString(fldName); err != nil {

View File

@@ -43,7 +43,7 @@ func Testv1AttributeProfileAsAttributeProfile(t *testing.T) {
v1Attribute := &v1AttributeProfile{
Tenant: "cgrates.org",
ID: "attributeprofile1",
Contexts: []string{utils.MetaRating},
Contexts: []string{utils.MetaSessionS},
FilterIDs: []string{"filter1"},
ActivationInterval: &utils.ActivationInterval{
ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),
@@ -55,7 +55,7 @@ func Testv1AttributeProfileAsAttributeProfile(t *testing.T) {
attrPrf := &engine.AttributeProfile{
Tenant: "cgrates.org",
ID: "attributeprofile1",
Contexts: []string{utils.MetaRating},
Contexts: []string{utils.MetaSessionS},
FilterIDs: []string{"filter1"},
ActivationInterval: &utils.ActivationInterval{
ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),

View File

@@ -1826,7 +1826,7 @@ func testMigratorAttributeProfile(t *testing.T) {
v1Attribute := &v1AttributeProfile{
Tenant: "cgrates.org",
ID: "attributeprofile1",
Contexts: []string{utils.MetaRating},
Contexts: []string{utils.MetaSessionS},
FilterIDs: []string{"filter1"},
ActivationInterval: &utils.ActivationInterval{
ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),
@@ -1838,7 +1838,7 @@ func testMigratorAttributeProfile(t *testing.T) {
attrPrf := &engine.AttributeProfile{
Tenant: "cgrates.org",
ID: "attributeprofile1",
Contexts: []string{utils.MetaRating},
Contexts: []string{utils.MetaSessionS},
FilterIDs: []string{"filter1"},
ActivationInterval: &utils.ActivationInterval{
ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),