diff --git a/apier/v1/routes.go b/apier/v1/routes.go index dfe2c8ed3..03a7be272 100644 --- a/apier/v1/routes.go +++ b/apier/v1/routes.go @@ -27,10 +27,14 @@ import ( // GetRouteProfile returns a Route configuration func (apierSv1 *APIerSv1) GetRouteProfile(arg *utils.TenantID, reply *engine.RouteProfile) error { - if missing := utils.MissingStructFields(arg, []string{"Tenant", "ID"}); len(missing) != 0 { //Params missing + if missing := utils.MissingStructFields(arg, []string{utils.ID}); len(missing) != 0 { //Params missing return utils.NewErrMandatoryIeMissing(missing...) } - if rp, err := apierSv1.DataManager.GetRouteProfile(arg.Tenant, arg.ID, true, true, utils.NonTransactional); err != nil { + tnt := arg.Tenant + if tnt == utils.EmptyString { + tnt = apierSv1.Config.GeneralCfg().DefaultTenant + } + if rp, err := apierSv1.DataManager.GetRouteProfile(tnt, arg.ID, true, true, utils.NonTransactional); err != nil { return utils.APIErrorHandler(err) } else { *reply = *rp @@ -40,10 +44,11 @@ func (apierSv1 *APIerSv1) GetRouteProfile(arg *utils.TenantID, reply *engine.Rou // GetRouteProfileIDs returns list of routeProfile IDs registered for a tenant func (apierSv1 *APIerSv1) GetRouteProfileIDs(args *utils.PaginatorWithTenant, sppPrfIDs *[]string) error { - if missing := utils.MissingStructFields(args, []string{utils.Tenant}); len(missing) != 0 { //Params missing - return utils.NewErrMandatoryIeMissing(missing...) + tnt := args.Tenant + if tnt == utils.EmptyString { + tnt = apierSv1.Config.GeneralCfg().DefaultTenant } - prfx := utils.RouteProfilePrefix + args.Tenant + ":" + prfx := utils.RouteProfilePrefix + tnt + ":" keys, err := apierSv1.DataManager.DataDB().GetKeysForPrefix(prfx) if err != nil { return err @@ -67,9 +72,12 @@ type RouteWithCache struct { //SetRouteProfile add a new Route configuration func (apierSv1 *APIerSv1) SetRouteProfile(args *RouteWithCache, reply *string) error { - if missing := utils.MissingStructFields(args.RouteProfile, []string{"Tenant", "ID"}); len(missing) != 0 { + if missing := utils.MissingStructFields(args.RouteProfile, []string{utils.ID}); len(missing) != 0 { return utils.NewErrMandatoryIeMissing(missing...) } + if args.Tenant == utils.EmptyString { + args.Tenant = apierSv1.Config.GeneralCfg().DefaultTenant + } if err := apierSv1.DataManager.SetRouteProfile(args.RouteProfile, true); err != nil { return utils.APIErrorHandler(err) } @@ -88,10 +96,14 @@ func (apierSv1 *APIerSv1) SetRouteProfile(args *RouteWithCache, reply *string) e //RemoveRouteProfile remove a specific Route configuration func (apierSv1 *APIerSv1) RemoveRouteProfile(args *utils.TenantIDWithCache, reply *string) error { - if missing := utils.MissingStructFields(args, []string{"Tenant", "ID"}); len(missing) != 0 { //Params missing + if missing := utils.MissingStructFields(args, []string{utils.ID}); len(missing) != 0 { //Params missing return utils.NewErrMandatoryIeMissing(missing...) } - if err := apierSv1.DataManager.RemoveRouteProfile(args.Tenant, args.ID, utils.NonTransactional, true); err != nil { + tnt := args.Tenant + if tnt == utils.EmptyString { + tnt = apierSv1.Config.GeneralCfg().DefaultTenant + } + if err := apierSv1.DataManager.RemoveRouteProfile(tnt, args.ID, utils.NonTransactional, true); err != nil { return utils.APIErrorHandler(err) } //generate a loadID for CacheRouteProfiles and store it in database @@ -99,8 +111,8 @@ func (apierSv1 *APIerSv1) RemoveRouteProfile(args *utils.TenantIDWithCache, repl return utils.APIErrorHandler(err) } //handle caching for SupplierProfile - if err := apierSv1.CallCache(args.Cache, args.Tenant, utils.CacheRouteProfiles, - args.TenantID(), nil, nil, args.Opts); err != nil { + if err := apierSv1.CallCache(args.Cache, tnt, utils.CacheRouteProfiles, + utils.ConcatenatedKey(tnt, args.ID), nil, nil, args.Opts); err != nil { return utils.APIErrorHandler(err) } *reply = utils.OK diff --git a/apier/v1/routes_it_test.go b/apier/v1/routes_it_test.go index 2bc5394b9..6770c18f9 100644 --- a/apier/v1/routes_it_test.go +++ b/apier/v1/routes_it_test.go @@ -67,6 +67,8 @@ var ( testV1RouteUpdateRouteProfiles, testV1RouteRemRouteProfiles, testV1RouteGetRouteForEvent, + testV1RouteSetRouteProfilesWithoutTenant, + testV1RouteRemRouteProfilesWithoutTenant, // reset the database and load the TP again testV1RouteInitDataDb, testV1RouteFromFolder, @@ -925,6 +927,13 @@ func testV1RouteGetRouteProfileIDs(t *testing.T) { "ROUTE_ACNT_1001", "ROUTE_LEASTCOST_1", "ROUTE_WEIGHT_2", "ROUTE_WEIGHT_1", "ROUTE_QOS_3", "TEST_PROFILE1", "ROUTE_LOAD_DIST", "ROUTE_LCR"} var result []string + if err := splSv1Rpc.Call(utils.APIerSv1GetRouteProfileIDs, + &utils.PaginatorWithTenant{}, &result); err != nil { + t.Error(err) + } else if len(expected) != len(result) { + t.Errorf("Expecting : %+v, received: %+v", expected, result) + } + if err := splSv1Rpc.Call(utils.APIerSv1GetRouteProfileIDs, &utils.PaginatorWithTenant{Tenant: "cgrates.org"}, &result); err != nil { t.Error(err) @@ -1091,6 +1100,19 @@ func testV1RouteGetRouteForEvent(t *testing.T) { if !reflect.DeepEqual(expected, *supProf[0]) { t.Errorf("Expected: %s ,received: %s", utils.ToJSON(expected), utils.ToJSON(supProf)) } + /* + ev.Tenant = utils.EmptyString + ev.ID = "randomID" + expected.ID = "randomID" + if err := splSv1Rpc.Call(utils.RouteSv1GetRouteProfilesForEvent, + ev, &supProf); err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(expected, *supProf[0]) { + t.Errorf("Expected: %s ,received: %s", utils.ToJSON(expected), utils.ToJSON(supProf)) + } + + */ } // Scenario: We create two rating plans RP_MOBILE and RP_LOCAL @@ -1512,3 +1534,59 @@ func testV1RouteStopEngine(t *testing.T) { t.Error(err) } } + +func testV1RouteSetRouteProfilesWithoutTenant(t *testing.T) { + splPrf = &RouteWithCache{ + RouteProfile: &engine.RouteProfile{ + Tenant: "cgrates.org", + ID: "TEST_PROFILE10", + FilterIDs: []string{"FLTR_1"}, + Sorting: "Sort1", + SortingParameters: []string{"Param1", "Param2"}, + Routes: []*engine.Route{ + { + ID: "ROUTE1", + RatingPlanIDs: []string{"RP1"}, + FilterIDs: []string{"FLTR_1"}, + AccountIDs: []string{"Acc"}, + ResourceIDs: []string{"Res1", "ResGroup2"}, + StatIDs: []string{"Stat1"}, + Weight: 20, + Blocker: false, + RouteParameters: "SortingParameter1", + }, + }, + Weight: 10, + }, + } + var reply string + if err := splSv1Rpc.Call(utils.APIerSv1SetRouteProfile, splPrf, &reply); err != nil { + t.Error(err) + } else if reply != utils.OK { + t.Error("Unexpected reply returned", reply) + } + splPrf.Tenant = "cgrates.org" + var result *engine.RouteProfile + if err := splSv1Rpc.Call(utils.APIerSv1GetRouteProfile, + &utils.TenantID{ID: "TEST_PROFILE10"}, + &result); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(result, splPrf.RouteProfile) { + t.Errorf("Expected %+v, received %+v", utils.ToJSON(splPrf.RouteProfile), utils.ToJSON(result)) + } +} + +func testV1RouteRemRouteProfilesWithoutTenant(t *testing.T) { + var reply string + if err := splSv1Rpc.Call(utils.APIerSv1RemoveRouteProfile, + &utils.TenantIDWithCache{ID: "TEST_PROFILE10"}, + &reply); err != nil { + t.Error(err) + } + var result *engine.RouteProfile + if err := splSv1Rpc.Call(utils.APIerSv1GetRouteProfile, + &utils.TenantID{ID: "TEST_PROFILE10"}, + &result); err == nil || err.Error() != utils.ErrNotFound.Error() { + t.Error(err) + } +}