diff --git a/apis/attributes_it_test.go b/apis/attributes_it_test.go index ae1e8977c..395dbbab4 100644 --- a/apis/attributes_it_test.go +++ b/apis/attributes_it_test.go @@ -23,6 +23,7 @@ package apis import ( "path" "reflect" + "sort" "testing" "time" @@ -52,6 +53,19 @@ var ( testGetAttributeProfileBeforeSet, //testAttributeSLoadFromFolder, testAttributeSetAttributeProfile, + testAttributeGetAttributeIDs, + testAttributeGetAttributeIDsCount, + testGetAttributeProfileBeforeSet2, + testAttributeSetAttributeProfile2, + testAttributeGetAttributeIDs2, + testAttributeGetAttributeIDsCount2, + testAttributeRemoveAttributeProfile, + testAttributeSetAttributeProfileBrokenReference, + testAttributeSGetAttributeForEventMissingEvent, + testAttributeSGetAttributeForEventAnyContext, + testAttributeSGetAttributeForEventSameAnyContext, + testAttributeSGetAttributeForEventNotFound, + testAttributeSGetAttributeForEvent, testAttributeSKillEngine, } ) @@ -128,7 +142,6 @@ func testAttributeSLoadFromFolder(t *testing.T) { } func testAttributeSetAttributeProfile(t *testing.T) { - time.Sleep(1000 * time.Millisecond) attrPrf := &engine.AttributeWithAPIOpts{ APIAttributeProfile: &engine.APIAttributeProfile{ Tenant: utils.CGRateSorg, @@ -185,7 +198,423 @@ func testAttributeSetAttributeProfile(t *testing.T) { }, &result); err != nil { t.Error(err) } else if !reflect.DeepEqual(result, expectedAttr) { - t.Errorf("Expected %+v, received %+v", utils.ToJSON(expectedAttr), utils.ToJSON(result)) + t.Errorf("Expected %+v \n, received %+v", utils.ToJSON(expectedAttr), utils.ToJSON(result)) + } +} + +func testAttributeGetAttributeIDs(t *testing.T) { + var reply []string + args := &utils.PaginatorWithTenant{ + Tenant: "cgrates.org", + } + expected := []string{"TEST_ATTRIBUTES_IT_TEST"} + if err := attrSRPC.Call(context.Background(), utils.AdminSv1GetAttributeProfileIDs, + args, &reply); err != nil { + t.Error(err) + } else if len(reply) != len(expected) { + t.Errorf("Expected %+v \n, received %+v", expected, reply) + } +} + +func testAttributeGetAttributeIDsCount(t *testing.T) { + var reply int + args := &utils.TenantIDWithAPIOpts{ + TenantID: &utils.TenantID{ + Tenant: utils.CGRateSorg, + }, + } + if err := attrSRPC.Call(context.Background(), utils.AdminSv1GetAttributeProfileIDsCount, + args, &reply); err != nil { + t.Error(err) + } else if reply != 1 { + t.Errorf("Expected %+v \n, received %+v", 1, reply) + } +} + +func testGetAttributeProfileBeforeSet2(t *testing.T) { + var reply *engine.APIAttributeProfile + if err := attrSRPC.Call(context.Background(), utils.AdminSv1GetAttributeProfile, + &utils.TenantIDWithAPIOpts{ + TenantID: &utils.TenantID{ + Tenant: utils.CGRateSorg, + ID: "TEST_ATTRIBUTES_IT_TEST_SECOND", + }, + }, &reply); err == nil || err.Error() != utils.ErrNotFound.Error() { + t.Error(err) + } +} + +func testAttributeSetAttributeProfile2(t *testing.T) { + attrPrf := &engine.AttributeWithAPIOpts{ + APIAttributeProfile: &engine.APIAttributeProfile{ + Tenant: utils.CGRateSorg, + ID: "TEST_ATTRIBUTES_IT_TEST_SECOND", + Contexts: []string{"*sessions"}, + Attributes: []*engine.ExternalAttribute{ + { + Path: "*tenant", + Type: utils.MetaConstant, + Value: "cgrates.itsyscom", + }, + }, + }, + } + var reply string + if err := attrSRPC.Call(context.Background(), utils.AdminSv1SetAttributeProfile, + attrPrf, &reply); err != nil { + t.Error(err) + } else if reply != utils.OK { + t.Error(err) + } + + expectedAttr := &engine.APIAttributeProfile{ + Tenant: utils.CGRateSorg, + ID: "TEST_ATTRIBUTES_IT_TEST_SECOND", + Contexts: []string{"*sessions"}, + Attributes: []*engine.ExternalAttribute{ + { + Path: "*tenant", + Type: utils.MetaConstant, + Value: "cgrates.itsyscom", + }, + }, + } + var result *engine.APIAttributeProfile + if err := attrSRPC.Call(context.Background(), utils.AdminSv1GetAttributeProfile, + &utils.TenantIDWithAPIOpts{ + TenantID: &utils.TenantID{ + Tenant: utils.CGRateSorg, + ID: "TEST_ATTRIBUTES_IT_TEST_SECOND", + }, + }, &result); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(result, expectedAttr) { + t.Errorf("Expected %+v \n, received %+v", utils.ToJSON(expectedAttr), utils.ToJSON(result)) + } +} + +func testAttributeGetAttributeIDs2(t *testing.T) { + var reply []string + args := &utils.PaginatorWithTenant{ + Tenant: "cgrates.org", + } + expected := []string{"TEST_ATTRIBUTES_IT_TEST", "TEST_ATTRIBUTES_IT_TEST_SECOND"} + if err := attrSRPC.Call(context.Background(), utils.AdminSv1GetAttributeProfileIDs, + args, &reply); err != nil { + t.Error(err) + } else if len(reply) != len(expected) { + t.Errorf("Expected %+v \n, received %+v", expected, reply) + } +} + +func testAttributeGetAttributeIDsCount2(t *testing.T) { + var reply int + args := &utils.TenantIDWithAPIOpts{ + TenantID: &utils.TenantID{ + Tenant: utils.CGRateSorg, + }, + } + if err := attrSRPC.Call(context.Background(), utils.AdminSv1GetAttributeProfileIDsCount, + args, &reply); err != nil { + t.Error(err) + } else if reply != 2 { + t.Errorf("Expected %+v \n, received %+v", 2, reply) + } +} + +func testAttributeRemoveAttributeProfile(t *testing.T) { + var reply string + args := &utils.TenantIDWithAPIOpts{ + TenantID: &utils.TenantID{ + ID: "TEST_ATTRIBUTES_IT_TEST_SECOND", + Tenant: utils.CGRateSorg, + }, + } + if err := attrSRPC.Call(context.Background(), utils.AdminSv1RemoveAttributeProfile, + args, &reply); err != nil { + t.Error(err) + } else if reply != utils.OK { + t.Errorf("Expected %+v \n, received %+v", 2, reply) + } + + //nothing to get from db + var result *engine.APIAttributeProfile + if err := attrSRPC.Call(context.Background(), utils.AdminSv1GetAttributeProfile, + &utils.TenantIDWithAPIOpts{ + TenantID: &utils.TenantID{ + Tenant: utils.CGRateSorg, + ID: "TEST_ATTRIBUTES_IT_TEST_SECOND", + }, + }, &result); err == nil || err.Error() != utils.ErrNotFound.Error() { + t.Errorf("Expected %+v \n, received %+v", utils.ErrNotFound, err) + } +} + +func testAttributeSetAttributeProfileBrokenReference(t *testing.T) { + attrPrf := &engine.AttributeWithAPIOpts{ + APIAttributeProfile: &engine.APIAttributeProfile{ + Tenant: utils.CGRateSorg, + ID: "TEST_ATTRIBUTES_IT_TEST_SECOND", + Contexts: []string{"*sessions"}, + FilterIDs: []string{"invalid_filter_format"}, + Attributes: []*engine.ExternalAttribute{ + { + Path: "*tenant", + Type: utils.MetaConstant, + Value: "cgrates.itsyscom", + }, + }, + }, + } + var reply string + expectedErr := "SERVER_ERROR: broken reference to filter: invalid_filter_format for item with ID: cgrates.org:TEST_ATTRIBUTES_IT_TEST_SECOND" + if err := attrSRPC.Call(context.Background(), utils.AdminSv1SetAttributeProfile, + attrPrf, &reply); err == nil || err.Error() != expectedErr { + t.Errorf("Expected %+v \n, received %+v", expectedErr, err) + } +} + +func testAttributeSGetAttributeForEventMissingEvent(t *testing.T) { + var rplyEv engine.AttrSProcessEventReply + if err := attrSRPC.Call(context.Background(), utils.AttributeSv1ProcessEvent, + &engine.AttrArgsProcessEvent{}, &rplyEv); err == nil || + err.Error() != "MANDATORY_IE_MISSING: [CGREvent]" { + t.Error(err) + } +} + +func testAttributeSGetAttributeForEventAnyContext(t *testing.T) { + ev := &engine.AttrArgsProcessEvent{ + Context: utils.StringPointer(utils.MetaCDRs), + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "testAttributeSGetAttributeForEventWihMetaAnyContext", + Event: map[string]interface{}{ + utils.AccountField: "dan", + utils.Destination: "+491511231234", + }, + }, + } + eAttrPrf2 := &engine.AttributeWithAPIOpts{ + APIAttributeProfile: &engine.APIAttributeProfile{ + Tenant: ev.Tenant, + ID: "ATTR_2", + FilterIDs: []string{"*string:~*req.Account:dan"}, + Contexts: []string{utils.MetaAny}, + ActivationInterval: &utils.ActivationInterval{ + ActivationTime: time.Date(2014, 1, 14, 0, 0, 0, 0, time.UTC)}, + Attributes: []*engine.ExternalAttribute{ + { + Path: utils.MetaReq + utils.NestingSep + utils.AccountField, + Type: utils.MetaConstant, + Value: "1001", + }, + }, + Weight: 10.0, + }, + } + var result string + if err := attrSRPC.Call(context.Background(), utils.AdminSv1SetAttributeProfile, + eAttrPrf2, &result); err != nil { + t.Error(err) + } else if result != utils.OK { + t.Error("Unexpected reply returned", result) + } + var reply *engine.APIAttributeProfile + if err := attrSRPC.Call(context.Background(), utils.AdminSv1GetAttributeProfile, + utils.TenantIDWithAPIOpts{TenantID: &utils.TenantID{Tenant: "cgrates.org", ID: "ATTR_2"}}, &reply); err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(eAttrPrf2.APIAttributeProfile, reply) { + t.Errorf("Expecting : %+v, received: %+v", eAttrPrf2.APIAttributeProfile, reply) + } + var attrReply *engine.AttributeProfile + if err := attrSRPC.Call(context.Background(), utils.AttributeSv1GetAttributeForEvent, + ev, &attrReply); err != nil { + t.Fatal(err) + } + + expAttrFromEv := &engine.AttributeProfile{ + Tenant: ev.Tenant, + ID: "ATTR_2", + FilterIDs: []string{"*string:~*req.Account:dan"}, + Contexts: []string{utils.MetaAny}, + ActivationInterval: &utils.ActivationInterval{ + ActivationTime: time.Date(2014, 1, 14, 0, 0, 0, 0, time.UTC)}, + Attributes: []*engine.Attribute{ + { + Path: utils.MetaReq + utils.NestingSep + utils.AccountField, + Type: utils.MetaConstant, + Value: config.NewRSRParsersMustCompile("1001", utils.InfieldSep), + }, + }, + Weight: 10.0, + } + expAttrFromEv.Compile() + attrReply.Compile() + if !reflect.DeepEqual(expAttrFromEv, attrReply) { + t.Errorf("Expecting: %s, received: %s", utils.ToJSON(expAttrFromEv), utils.ToJSON(attrReply)) + } +} + +func testAttributeSGetAttributeForEventSameAnyContext(t *testing.T) { + ev := &engine.AttrArgsProcessEvent{ + Context: utils.StringPointer(utils.MetaAny), + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "testAttributeSGetAttributeForEventWihMetaAnyContext", + Event: map[string]interface{}{ + utils.AccountField: "dan", + utils.Destination: "+491511231234", + }, + }, + } + var attrReply *engine.AttributeProfile + if err := attrSRPC.Call(context.Background(), utils.AttributeSv1GetAttributeForEvent, + ev, &attrReply); err != nil { + t.Fatal(err) + } + + expAttrFromEv := &engine.AttributeProfile{ + Tenant: ev.Tenant, + ID: "ATTR_2", + FilterIDs: []string{"*string:~*req.Account:dan"}, + Contexts: []string{utils.MetaAny}, + ActivationInterval: &utils.ActivationInterval{ + ActivationTime: time.Date(2014, 1, 14, 0, 0, 0, 0, time.UTC)}, + Attributes: []*engine.Attribute{ + { + Path: utils.MetaReq + utils.NestingSep + utils.AccountField, + Type: utils.MetaConstant, + Value: config.NewRSRParsersMustCompile("1001", utils.InfieldSep), + }, + }, + Weight: 10.0, + } + expAttrFromEv.Compile() + attrReply.Compile() + if !reflect.DeepEqual(expAttrFromEv, attrReply) { + t.Errorf("Expecting: %s, received: %s", utils.ToJSON(expAttrFromEv), utils.ToJSON(attrReply)) + } +} + +func testAttributeSGetAttributeForEventNotFound(t *testing.T) { + ev := &engine.AttrArgsProcessEvent{ + Context: utils.StringPointer(utils.MetaCDRs), + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "testAttributeSGetAttributeForEventWihMetaAnyContext", + Event: map[string]interface{}{ + utils.AccountField: "dann", + utils.Destination: "+491511231234", + }, + }, + } + var attrReply *engine.AttributeProfile + if err := attrSRPC.Call(context.Background(), utils.AttributeSv1GetAttributeForEvent, + ev, &attrReply); err == nil || err.Error() != utils.ErrNotFound.Error() { + t.Error(err) + } +} + +func testAttributeSGetAttributeForEvent(t *testing.T) { + ev := &engine.AttrArgsProcessEvent{ + Context: utils.StringPointer(utils.MetaSessionS), + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "testAttributeSGetAttributeForEvent", + Event: map[string]interface{}{ + utils.AccountField: "1007", + utils.Destination: "+491511231234", + }, + }, + } + + eAttrPrf := &engine.AttributeProfile{ + Tenant: ev.Tenant, + ID: "ATTR_1", + FilterIDs: []string{"*string:~*req.Account:1007"}, + Contexts: []string{utils.MetaCDRs, utils.MetaSessionS}, + ActivationInterval: &utils.ActivationInterval{ + ActivationTime: time.Date(2014, 1, 14, 0, 0, 0, 0, time.UTC)}, + Attributes: []*engine.Attribute{ + { + Path: utils.MetaReq + utils.NestingSep + utils.AccountField, + Value: config.NewRSRParsersMustCompile("1001", utils.InfieldSep), + Type: utils.MetaConstant, + FilterIDs: []string{}, + }, + { + Path: utils.MetaReq + utils.NestingSep + utils.Subject, + Value: config.NewRSRParsersMustCompile("1001", utils.InfieldSep), + Type: utils.MetaConstant, + FilterIDs: []string{}, + }, + }, + Weight: 10.0, + } + if *encoding == utils.MetaGOB { + eAttrPrf.Attributes[0].FilterIDs = nil + eAttrPrf.Attributes[1].FilterIDs = nil + } + var result string + eAttrPrfApi := &engine.AttributeWithAPIOpts{ + APIAttributeProfile: &engine.APIAttributeProfile{ + Tenant: ev.Tenant, + ID: "ATTR_1", + FilterIDs: []string{"*string:~*req.Account:1007"}, + Contexts: []string{utils.MetaCDRs, utils.MetaSessionS}, + ActivationInterval: &utils.ActivationInterval{ + ActivationTime: time.Date(2014, 1, 14, 0, 0, 0, 0, time.UTC)}, + Attributes: []*engine.ExternalAttribute{ + { + Path: utils.MetaReq + utils.NestingSep + utils.AccountField, + Value: "1001", + Type: utils.MetaConstant, + FilterIDs: []string{}, + }, + { + Path: utils.MetaReq + utils.NestingSep + utils.Subject, + Value: "1001", + Type: utils.MetaConstant, + FilterIDs: []string{}, + }, + }, + Weight: 10.0, + }, + } + if err := attrSRPC.Call(context.Background(), utils.AdminSv1SetAttributeProfile, + eAttrPrfApi, &result); err != nil { + t.Error(err) + } else if result != utils.OK { + t.Error("Unexpected reply returned", result) + } + + var attrReply *engine.AttributeProfile + if err := attrSRPC.Call(context.Background(), utils.AttributeSv1GetAttributeForEvent, + ev, &attrReply); err != nil { + t.Fatal(err) + } + attrReply.Compile() + eAttrPrf.Compile() + sort.Strings(attrReply.Contexts) + if !reflect.DeepEqual(eAttrPrf, attrReply) { + t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(eAttrPrf), utils.ToJSON(attrReply)) + } + + ev.Tenant = utils.EmptyString + ev.ID = "randomID" + var attrPrf *engine.AttributeProfile + if err := attrSRPC.Call(context.Background(), utils.AttributeSv1GetAttributeForEvent, + ev, &attrPrf); err != nil { + t.Fatal(err) + } + + attrPrf.Compile() + // Populate private variables in RSRParsers + sort.Strings(attrReply.Contexts) + if !reflect.DeepEqual(eAttrPrf, attrPrf) { + t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(eAttrPrf), utils.ToJSON(attrPrf)) } } diff --git a/console/attributes_profile_ids.go b/console/attributes_profile_ids.go index 4fead1b70..9416f17cf 100644 --- a/console/attributes_profile_ids.go +++ b/console/attributes_profile_ids.go @@ -25,7 +25,7 @@ import ( func init() { c := &CmdGetAttributeIDs{ name: "attributes_profile_ids", - rpcMethod: utils.APIerSv1GetAttributeProfileIDs, + rpcMethod: utils.AdminSv1GetAttributeProfileIDs, rpcParams: &utils.PaginatorWithTenant{}, } commands[c.Name()] = c diff --git a/console/attributes_profile_rem.go b/console/attributes_profile_rem.go index 39d4ba5f8..91dcd1336 100644 --- a/console/attributes_profile_rem.go +++ b/console/attributes_profile_rem.go @@ -23,7 +23,7 @@ import "github.com/cgrates/cgrates/utils" func init() { c := &CmdRemoveAttributes{ name: "attributes_profile_remove", - rpcMethod: utils.APIerSv1RemoveAttributeProfile, + rpcMethod: utils.AdminSv1RemoveAttributeProfile, rpcParams: &utils.TenantIDWithAPIOpts{}, } commands[c.Name()] = c diff --git a/utils/consts.go b/utils/consts.go index ce4010d47..fa0ba3c13 100644 --- a/utils/consts.go +++ b/utils/consts.go @@ -1259,7 +1259,7 @@ const ( APIerSv1GetLoadHistory = "APIerSv1.GetLoadHistory" APIerSv1GetLoadIDs = "APIerSv1.GetLoadIDs" APIerSv1GetLoadTimes = "APIerSv1.GetLoadTimes" - APIerSv1GetAttributeProfileIDsCount = "APIerSv1.GetAttributeProfileIDsCount" + AdminSv1GetAttributeProfileIDsCount = "AdminSv1.GetAttributeProfileIDsCount" APIerSv1GetTPActionProfile = "APIerSv1.GetTPActionProfile" APIerSv1SetTPActionProfile = "APIerSv1.SetTPActionProfile" APIerSv1GetTPActionProfileIDs = "APIerSv1.GetTPActionProfileIDs" @@ -1349,8 +1349,8 @@ const ( const ( AdminSv1SetAttributeProfile = "AdminSv1.SetAttributeProfile" AdminSv1GetAttributeProfile = "AdminSv1.GetAttributeProfile" - APIerSv1GetAttributeProfileIDs = "APIerSv1.GetAttributeProfileIDs" - APIerSv1RemoveAttributeProfile = "APIerSv1.RemoveAttributeProfile" + AdminSv1GetAttributeProfileIDs = "AdminSv1.GetAttributeProfileIDs" + AdminSv1RemoveAttributeProfile = "AdminSv1.RemoveAttributeProfile" AttributeSv1GetAttributeForEvent = "AttributeSv1.GetAttributeForEvent" AttributeSv1ProcessEvent = "AttributeSv1.ProcessEvent" AttributeSv1Ping = "AttributeSv1.Ping"