Add integration test for routes with rateS subsystem

This commit is contained in:
TeoV
2020-11-18 18:03:37 +02:00
committed by Dan Christian Bogos
parent d10cc4b4c3
commit 4153bd9f9e
24 changed files with 597 additions and 223 deletions

View File

@@ -411,7 +411,7 @@ func testInternalRemoteITGetStatQueueProfile(t *testing.T) {
func testInternalRemoteITGetRoute(t *testing.T) {
var reply *engine.RouteProfile
splPrf := &engine.RouteProfile{
routePrf := &engine.RouteProfile{
Tenant: "cgrates.org",
ID: "ROUTE_ACNT_1001",
FilterIDs: []string{"FLTR_ACNT_1001"},
@@ -433,7 +433,7 @@ func testInternalRemoteITGetRoute(t *testing.T) {
Weight: 20,
}
// routeProfile in reverse order
splPrf2 := &engine.RouteProfile{
routePrf2 := &engine.RouteProfile{
Tenant: "cgrates.org",
ID: "ROUTE_ACNT_1001",
FilterIDs: []string{"FLTR_ACNT_1001"},
@@ -455,15 +455,15 @@ func testInternalRemoteITGetRoute(t *testing.T) {
Weight: 20,
}
if *encoding == utils.MetaGOB { // in gob emtpty slice is encoded as nil
splPrf.SortingParameters = nil
splPrf2.SortingParameters = nil
routePrf.SortingParameters = nil
routePrf2.SortingParameters = nil
}
if err := internalRPC.Call(utils.APIerSv1GetRouteProfile,
&utils.TenantID{Tenant: "cgrates.org", ID: "ROUTE_ACNT_1001"}, &reply); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(splPrf, reply) && !reflect.DeepEqual(splPrf2, reply) {
t.Errorf("Expecting: %+v, \n received: %+v", utils.ToJSON(splPrf), utils.ToJSON(reply))
} else if !reflect.DeepEqual(routePrf, reply) && !reflect.DeepEqual(routePrf2, reply) {
t.Errorf("Expecting: %+v, \n received: %+v", utils.ToJSON(routePrf), utils.ToJSON(reply))
}
}

View File

@@ -33,11 +33,11 @@ import (
)
var (
splSv1CfgPath string
splSv1Cfg *config.CGRConfig
splSv1Rpc *rpc.Client
splPrf *RouteWithCache
splSv1ConfDIR string //run tests for specific configuration
routeSv1CfgPath string
routeSv1Cfg *config.CGRConfig
routeSv1Rpc *rpc.Client
routePrf *RouteWithCache
routeSv1ConfDIR string //run tests for specific configuration
sTestsRouteSV1 = []func(t *testing.T){
testV1RouteLoadConfig,
@@ -49,33 +49,33 @@ var (
testV1RouteFromFolder,
testV1RouteGetWeightRoutes,
testV1RouteGetLeastCostRoutes,
//testV1RouteGetLeastCostRoutesWithoutUsage,
//testV1RouteGetLeastCostRoutesWithMaxCost,
//testV1RouteGetLeastCostRoutesWithMaxCost2,
//testV1RouteGetLeastCostRoutesWithMaxCostNotFound,
//testV1RouteGetHighestCostRoutes,
//testV1RouteGetLeastCostRoutesErr,
//testV1RoutePolulateStatsForQOS,
//testV1RouteGetQOSRoutes,
//testV1RouteGetQOSRoutes2,
//testV1RouteGetQOSRoutes3,
//testV1RouteGetQOSRoutesFiltred,
//testV1RouteGetQOSRoutesFiltred2,
//testV1RouteGetRouteWithoutFilter,
//testV1RouteSetRouteProfiles,
//testV1RouteGetRouteProfileIDs,
//testV1RouteUpdateRouteProfiles,
//testV1RouteRemRouteProfiles,
//testV1RouteGetRouteForEvent,
//testV1RouteSetRouteProfilesWithoutTenant,
//testV1RouteRemRouteProfilesWithoutTenant,
//// reset the database and load the TP again
//testV1RouteInitDataDb,
//testV1RouteFromFolder,
//testV1RoutesOneRouteWithoutDestination,
//testV1RouteRoutePing,
//testV1RouteMultipleRouteSameID,
//testV1RouteAccountWithRatingPlan,
testV1RouteGetLeastCostRoutesWithoutUsage,
testV1RouteGetLeastCostRoutesWithMaxCost,
testV1RouteGetLeastCostRoutesWithMaxCost2,
testV1RouteGetLeastCostRoutesWithMaxCostNotFound,
testV1RouteGetHighestCostRoutes,
testV1RouteGetLeastCostRoutesErr,
testV1RoutePolulateStatsForQOS,
testV1RouteGetQOSRoutes,
testV1RouteGetQOSRoutes2,
testV1RouteGetQOSRoutes3,
testV1RouteGetQOSRoutesFiltred,
testV1RouteGetQOSRoutesFiltred2,
testV1RouteGetRouteWithoutFilter,
testV1RouteSetRouteProfiles,
testV1RouteGetRouteProfileIDs,
testV1RouteUpdateRouteProfiles,
testV1RouteRemRouteProfiles,
testV1RouteGetRouteForEvent,
testV1RouteSetRouteProfilesWithoutTenant,
testV1RouteRemRouteProfilesWithoutTenant,
// reset the database and load the TP again
testV1RouteInitDataDb,
testV1RouteFromFolder,
testV1RoutesOneRouteWithoutDestination,
testV1RouteRoutePing,
testV1RouteMultipleRouteSameID,
testV1RouteAccountWithRatingPlan,
testV1RouteStopEngine,
}
)
@@ -84,51 +84,51 @@ var (
func TestRouteSV1IT(t *testing.T) {
switch *dbType {
case utils.MetaInternal:
splSv1ConfDIR = "tutinternal"
routeSv1ConfDIR = "tutinternal"
case utils.MetaMySQL:
splSv1ConfDIR = "tutmysql"
routeSv1ConfDIR = "tutmysql"
case utils.MetaMongo:
splSv1ConfDIR = "tutmongo"
routeSv1ConfDIR = "tutmongo"
case utils.MetaPostgres:
t.SkipNow()
default:
t.Fatal("Unknown Database type")
}
for _, stest := range sTestsRouteSV1 {
t.Run(splSv1ConfDIR, stest)
t.Run(routeSv1ConfDIR, stest)
}
}
func testV1RouteLoadConfig(t *testing.T) {
var err error
splSv1CfgPath = path.Join(*dataDir, "conf", "samples", splSv1ConfDIR)
if splSv1Cfg, err = config.NewCGRConfigFromPath(splSv1CfgPath); err != nil {
routeSv1CfgPath = path.Join(*dataDir, "conf", "samples", routeSv1ConfDIR)
if routeSv1Cfg, err = config.NewCGRConfigFromPath(routeSv1CfgPath); err != nil {
t.Error(err)
}
}
func testV1RouteInitDataDb(t *testing.T) {
if err := engine.InitDataDb(splSv1Cfg); err != nil {
if err := engine.InitDataDb(routeSv1Cfg); err != nil {
t.Fatal(err)
}
}
// Wipe out the cdr database
func testV1RouteResetStorDb(t *testing.T) {
if err := engine.InitStorDb(splSv1Cfg); err != nil {
if err := engine.InitStorDb(routeSv1Cfg); err != nil {
t.Fatal(err)
}
}
func testV1RouteStartEngine(t *testing.T) {
if _, err := engine.StopStartEngine(splSv1CfgPath, *waitRater); err != nil {
if _, err := engine.StopStartEngine(routeSv1CfgPath, *waitRater); err != nil {
t.Fatal(err)
}
}
func testV1RouteRpcConn(t *testing.T) {
var err error
splSv1Rpc, err = newRPCClient(splSv1Cfg.ListenCfg()) // We connect over JSON so we can also troubleshoot if needed
routeSv1Rpc, err = newRPCClient(routeSv1Cfg.ListenCfg()) // We connect over JSON so we can also troubleshoot if needed
if err != nil {
t.Fatal("Could not connect to rater: ", err.Error())
}
@@ -136,7 +136,7 @@ func testV1RouteRpcConn(t *testing.T) {
func testV1RouteGetBeforeDataLoad(t *testing.T) {
var suplsReply *engine.RouteProfile
if err := splSv1Rpc.Call(utils.APIerSv1GetRouteProfile,
if err := routeSv1Rpc.Call(utils.APIerSv1GetRouteProfile,
&utils.TenantID{
Tenant: "cgrates.org",
ID: "ROUTE_WEIGHT_1",
@@ -148,7 +148,7 @@ func testV1RouteGetBeforeDataLoad(t *testing.T) {
func testV1RouteFromFolder(t *testing.T) {
var reply string
attrs := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "testit")}
if err := splSv1Rpc.Call(utils.APIerSv1LoadTariffPlanFromFolder, attrs, &reply); err != nil {
if err := routeSv1Rpc.Call(utils.APIerSv1LoadTariffPlanFromFolder, attrs, &reply); err != nil {
t.Error(err)
}
time.Sleep(500 * time.Millisecond)
@@ -187,7 +187,7 @@ func testV1RouteGetWeightRoutes(t *testing.T) {
},
}
var suplsReply engine.SortedRoutes
if err := splSv1Rpc.Call(utils.RouteSv1GetRoutes,
if err := routeSv1Rpc.Call(utils.RouteSv1GetRoutes,
ev, &suplsReply); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(eSpls, suplsReply) {
@@ -196,7 +196,7 @@ func testV1RouteGetWeightRoutes(t *testing.T) {
}
ev.CGREvent.Tenant = utils.EmptyString
if err := splSv1Rpc.Call(utils.RouteSv1GetRoutes,
if err := routeSv1Rpc.Call(utils.RouteSv1GetRoutes,
ev, &suplsReply); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(eSpls, suplsReply) {
@@ -253,7 +253,7 @@ func testV1RouteGetLeastCostRoutes(t *testing.T) {
},
}
var suplsReply engine.SortedRoutes
if err := splSv1Rpc.Call(utils.RouteSv1GetRoutes,
if err := routeSv1Rpc.Call(utils.RouteSv1GetRoutes,
ev, &suplsReply); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(eSpls, suplsReply) {
@@ -309,7 +309,7 @@ func testV1RouteGetLeastCostRoutesWithoutUsage(t *testing.T) {
},
}
var suplsReply engine.SortedRoutes
if err := splSv1Rpc.Call(utils.RouteSv1GetRoutes,
if err := routeSv1Rpc.Call(utils.RouteSv1GetRoutes,
ev, &suplsReply); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(eSpls, suplsReply) {
@@ -359,7 +359,7 @@ func testV1RouteGetLeastCostRoutesWithMaxCost(t *testing.T) {
},
}
var suplsReply engine.SortedRoutes
if err := splSv1Rpc.Call(utils.RouteSv1GetRoutes,
if err := routeSv1Rpc.Call(utils.RouteSv1GetRoutes,
ev, &suplsReply); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(eSpls, suplsReply) {
@@ -386,7 +386,7 @@ func testV1RouteGetLeastCostRoutesWithMaxCostNotFound(t *testing.T) {
},
}
var suplsReply engine.SortedRoutes
if err := splSv1Rpc.Call(utils.RouteSv1GetRoutes,
if err := routeSv1Rpc.Call(utils.RouteSv1GetRoutes,
ev, &suplsReply); err != nil && err.Error() != utils.ErrNotFound.Error() {
t.Error(err)
}
@@ -434,7 +434,7 @@ func testV1RouteGetLeastCostRoutesWithMaxCost2(t *testing.T) {
},
}
var suplsReply engine.SortedRoutes
if err := splSv1Rpc.Call(utils.RouteSv1GetRoutes,
if err := routeSv1Rpc.Call(utils.RouteSv1GetRoutes,
ev, &suplsReply); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(eSpls, suplsReply) {
@@ -491,7 +491,7 @@ func testV1RouteGetHighestCostRoutes(t *testing.T) {
},
}
var suplsReply engine.SortedRoutes
if err := splSv1Rpc.Call(utils.RouteSv1GetRoutes,
if err := routeSv1Rpc.Call(utils.RouteSv1GetRoutes,
ev, &suplsReply); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(eSpls, suplsReply) {
@@ -517,7 +517,7 @@ func testV1RouteGetLeastCostRoutesErr(t *testing.T) {
},
}
var suplsReply engine.SortedRoutes
if err := splSv1Rpc.Call(utils.RouteSv1GetRoutes,
if err := routeSv1Rpc.Call(utils.RouteSv1GetRoutes,
ev, &suplsReply); err.Error() != utils.ErrNotFound.Error() {
t.Error(err)
}
@@ -540,7 +540,7 @@ func testV1RoutePolulateStatsForQOS(t *testing.T) {
},
},
}
if err := splSv1Rpc.Call(utils.StatSv1ProcessEvent, ev1, &reply); err != nil {
if err := routeSv1Rpc.Call(utils.StatSv1ProcessEvent, ev1, &reply); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(reply, expected) {
t.Errorf("Expecting: %+v, received: %+v", expected, reply)
@@ -561,7 +561,7 @@ func testV1RoutePolulateStatsForQOS(t *testing.T) {
},
},
}
if err := splSv1Rpc.Call(utils.StatSv1ProcessEvent, ev1, &reply); err != nil {
if err := routeSv1Rpc.Call(utils.StatSv1ProcessEvent, ev1, &reply); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(reply, expected) {
t.Errorf("Expecting: %+v, received: %+v", expected, reply)
@@ -582,7 +582,7 @@ func testV1RoutePolulateStatsForQOS(t *testing.T) {
},
},
}
if err := splSv1Rpc.Call(utils.StatSv1ProcessEvent, ev1, &reply); err != nil {
if err := routeSv1Rpc.Call(utils.StatSv1ProcessEvent, ev1, &reply); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(reply, expected) {
t.Errorf("Expecting: %+v, received: %+v", expected, reply)
@@ -603,7 +603,7 @@ func testV1RoutePolulateStatsForQOS(t *testing.T) {
},
},
}
if err := splSv1Rpc.Call(utils.StatSv1ProcessEvent, ev1, &reply); err != nil {
if err := routeSv1Rpc.Call(utils.StatSv1ProcessEvent, ev1, &reply); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(reply, expected) {
t.Errorf("Expecting: %+v, received: %+v", expected, reply)
@@ -624,7 +624,7 @@ func testV1RoutePolulateStatsForQOS(t *testing.T) {
},
},
}
if err := splSv1Rpc.Call(utils.StatSv1ProcessEvent, ev1, &reply); err != nil {
if err := routeSv1Rpc.Call(utils.StatSv1ProcessEvent, ev1, &reply); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(reply, expected) {
t.Errorf("Expecting: %+v, received: %+v", expected, reply)
@@ -646,7 +646,7 @@ func testV1RoutePolulateStatsForQOS(t *testing.T) {
},
},
}
if err := splSv1Rpc.Call(utils.StatSv1ProcessEvent, ev1, &reply); err != nil {
if err := routeSv1Rpc.Call(utils.StatSv1ProcessEvent, ev1, &reply); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(reply, expected) {
t.Errorf("Expecting: %+v, received: %+v", expected, reply)
@@ -668,7 +668,7 @@ func testV1RoutePolulateStatsForQOS(t *testing.T) {
},
},
}
if err := splSv1Rpc.Call(utils.StatSv1ProcessEvent, ev1, &reply); err != nil {
if err := routeSv1Rpc.Call(utils.StatSv1ProcessEvent, ev1, &reply); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(reply, expected) {
t.Errorf("Expecting: %+v, received: %+v", expected, reply)
@@ -689,7 +689,7 @@ func testV1RouteGetQOSRoutes(t *testing.T) {
}
expRouteIDs := []string{"route1", "route3", "route2"}
var suplsReply engine.SortedRoutes
if err := splSv1Rpc.Call(utils.RouteSv1GetRoutes,
if err := routeSv1Rpc.Call(utils.RouteSv1GetRoutes,
ev, &suplsReply); err != nil {
t.Error(err)
} else {
@@ -722,7 +722,7 @@ func testV1RouteGetQOSRoutes2(t *testing.T) {
}
expRouteIDs := []string{"route3", "route2", "route1"}
var suplsReply engine.SortedRoutes
if err := splSv1Rpc.Call(utils.RouteSv1GetRoutes,
if err := routeSv1Rpc.Call(utils.RouteSv1GetRoutes,
ev, &suplsReply); err != nil {
t.Error(err)
} else {
@@ -755,7 +755,7 @@ func testV1RouteGetQOSRoutes3(t *testing.T) {
}
expRouteIDs := []string{"route1", "route3", "route2"}
var suplsReply engine.SortedRoutes
if err := splSv1Rpc.Call(utils.RouteSv1GetRoutes,
if err := routeSv1Rpc.Call(utils.RouteSv1GetRoutes,
ev, &suplsReply); err != nil {
t.Error(err)
} else {
@@ -788,7 +788,7 @@ func testV1RouteGetQOSRoutesFiltred(t *testing.T) {
}
expRouteIDs := []string{"route1", "route3"}
var suplsReply engine.SortedRoutes
if err := splSv1Rpc.Call(utils.RouteSv1GetRoutes,
if err := routeSv1Rpc.Call(utils.RouteSv1GetRoutes,
ev, &suplsReply); err != nil {
t.Error(err)
} else {
@@ -825,7 +825,7 @@ func testV1RouteGetQOSRoutesFiltred2(t *testing.T) {
}
expRouteIDs := []string{"route3", "route2"}
var suplsReply engine.SortedRoutes
if err := splSv1Rpc.Call(utils.RouteSv1GetRoutes,
if err := routeSv1Rpc.Call(utils.RouteSv1GetRoutes,
ev, &suplsReply); err != nil {
t.Error(err)
} else {
@@ -871,7 +871,7 @@ func testV1RouteGetRouteWithoutFilter(t *testing.T) {
},
}
var suplsReply engine.SortedRoutes
if err := splSv1Rpc.Call(utils.RouteSv1GetRoutes,
if err := routeSv1Rpc.Call(utils.RouteSv1GetRoutes,
ev, &suplsReply); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(eSpls, suplsReply) {
@@ -881,7 +881,7 @@ func testV1RouteGetRouteWithoutFilter(t *testing.T) {
}
func testV1RouteSetRouteProfiles(t *testing.T) {
splPrf = &RouteWithCache{
routePrf = &RouteWithCache{
RouteProfile: &engine.RouteProfile{
Tenant: "cgrates.org",
ID: "TEST_PROFILE1",
@@ -907,27 +907,27 @@ func testV1RouteSetRouteProfiles(t *testing.T) {
var result string
expErr := "SERVER_ERROR: broken reference to filter: FLTR_NotFound for item with ID: cgrates.org:TEST_PROFILE1"
if err := splSv1Rpc.Call(utils.APIerSv1SetRouteProfile, splPrf, &result); err == nil || err.Error() != expErr {
if err := routeSv1Rpc.Call(utils.APIerSv1SetRouteProfile, routePrf, &result); err == nil || err.Error() != expErr {
t.Fatalf("Expected error: %q, received: %v", expErr, err)
}
var reply *engine.RouteProfile
if err := splSv1Rpc.Call(utils.APIerSv1GetRouteProfile,
if err := routeSv1Rpc.Call(utils.APIerSv1GetRouteProfile,
&utils.TenantID{Tenant: "cgrates.org", ID: "TEST_PROFILE1"}, &reply); err == nil ||
err.Error() != utils.ErrNotFound.Error() {
t.Error(err)
}
splPrf.FilterIDs = []string{"FLTR_1"}
if err := splSv1Rpc.Call(utils.APIerSv1SetRouteProfile, splPrf, &result); err != nil {
routePrf.FilterIDs = []string{"FLTR_1"}
if err := routeSv1Rpc.Call(utils.APIerSv1SetRouteProfile, routePrf, &result); err != nil {
t.Error(err)
} else if result != utils.OK {
t.Error("Unexpected reply returned", result)
}
if err := splSv1Rpc.Call(utils.APIerSv1GetRouteProfile,
if err := routeSv1Rpc.Call(utils.APIerSv1GetRouteProfile,
&utils.TenantID{Tenant: "cgrates.org", ID: "TEST_PROFILE1"}, &reply); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(splPrf.RouteProfile, reply) {
t.Errorf("Expecting: %+v, received: %+v", splPrf.RouteProfile, reply)
} else if !reflect.DeepEqual(routePrf.RouteProfile, reply) {
t.Errorf("Expecting: %+v, received: %+v", routePrf.RouteProfile, reply)
}
}
@@ -936,14 +936,14 @@ 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,
if err := routeSv1Rpc.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,
if err := routeSv1Rpc.Call(utils.APIerSv1GetRouteProfileIDs,
&utils.PaginatorWithTenant{Tenant: "cgrates.org"}, &result); err != nil {
t.Error(err)
} else if len(expected) != len(result) {
@@ -952,7 +952,7 @@ func testV1RouteGetRouteProfileIDs(t *testing.T) {
}
func testV1RouteUpdateRouteProfiles(t *testing.T) {
splPrf.Routes = []*engine.Route{
routePrf.Routes = []*engine.Route{
{
ID: "ROUTE1",
RatingPlanIDs: []string{"RP1"},
@@ -1001,35 +1001,35 @@ func testV1RouteUpdateRouteProfiles(t *testing.T) {
},
}
var result string
if err := splSv1Rpc.Call(utils.APIerSv1SetRouteProfile, splPrf, &result); err != nil {
if err := routeSv1Rpc.Call(utils.APIerSv1SetRouteProfile, routePrf, &result); err != nil {
t.Error(err)
} else if result != utils.OK {
t.Error("Unexpected reply returned", result)
}
var reply *engine.RouteProfile
if err := splSv1Rpc.Call(utils.APIerSv1GetRouteProfile,
if err := routeSv1Rpc.Call(utils.APIerSv1GetRouteProfile,
&utils.TenantID{Tenant: "cgrates.org", ID: "TEST_PROFILE1"}, &reply); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(splPrf.Routes, reply.Routes) && !reflect.DeepEqual(reverseRoutes, reply.Routes) {
t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(splPrf), utils.ToJSON(reply))
} else if !reflect.DeepEqual(routePrf.Routes, reply.Routes) && !reflect.DeepEqual(reverseRoutes, reply.Routes) {
t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(routePrf), utils.ToJSON(reply))
}
}
func testV1RouteRemRouteProfiles(t *testing.T) {
var resp string
if err := splSv1Rpc.Call(utils.APIerSv1RemoveRouteProfile,
if err := routeSv1Rpc.Call(utils.APIerSv1RemoveRouteProfile,
&utils.TenantIDWithCache{Tenant: "cgrates.org", ID: "TEST_PROFILE1"}, &resp); err != nil {
t.Error(err)
} else if resp != utils.OK {
t.Error("Unexpected reply returned", resp)
}
var reply *engine.RouteProfile
if err := splSv1Rpc.Call(utils.APIerSv1GetRouteProfile,
if err := routeSv1Rpc.Call(utils.APIerSv1GetRouteProfile,
&utils.TenantID{Tenant: "cgrates.org", ID: "TEST_PROFILE1"}, &reply); err == nil ||
err.Error() != utils.ErrNotFound.Error() {
t.Error(err)
}
if err := splSv1Rpc.Call(utils.APIerSv1RemoveRouteProfile,
if err := routeSv1Rpc.Call(utils.APIerSv1RemoveRouteProfile,
&utils.TenantIDWithCache{Tenant: "cgrates.org", ID: "TEST_PROFILE1"}, &resp); err.Error() != utils.ErrNotFound.Error() {
t.Errorf("Expected error: %v received: %v", utils.ErrNotFound, err)
}
@@ -1037,7 +1037,7 @@ func testV1RouteRemRouteProfiles(t *testing.T) {
func testV1RouteRoutePing(t *testing.T) {
var resp string
if err := splSv1Rpc.Call(utils.RouteSv1Ping, new(utils.CGREvent), &resp); err != nil {
if err := routeSv1Rpc.Call(utils.RouteSv1Ping, new(utils.CGREvent), &resp); err != nil {
t.Error(err)
} else if resp != utils.Pong {
t.Error("Unexpected reply returned", resp)
@@ -1096,7 +1096,7 @@ func testV1RouteGetRouteForEvent(t *testing.T) {
expected.SortingParameters = nil
}
var supProf []*engine.RouteProfile
if err := splSv1Rpc.Call(utils.RouteSv1GetRouteProfilesForEvent,
if err := routeSv1Rpc.Call(utils.RouteSv1GetRouteProfilesForEvent,
ev, &supProf); err != nil {
t.Fatal(err)
}
@@ -1111,7 +1111,7 @@ func testV1RouteGetRouteForEvent(t *testing.T) {
}
ev.CGREvent.Tenant = utils.EmptyString
if err := splSv1Rpc.Call(utils.RouteSv1GetRouteProfilesForEvent,
if err := routeSv1Rpc.Call(utils.RouteSv1GetRouteProfilesForEvent,
ev, &supProf); err != nil {
t.Fatal(err)
}
@@ -1133,12 +1133,12 @@ func testV1RouteGetRouteForEvent(t *testing.T) {
// route1 have attached RP_LOCAL and route2 have attach RP_MOBILE
func testV1RoutesOneRouteWithoutDestination(t *testing.T) {
var reply *engine.RouteProfile
if err := splSv1Rpc.Call(utils.APIerSv1GetRouteProfile,
if err := routeSv1Rpc.Call(utils.APIerSv1GetRouteProfile,
&utils.TenantID{Tenant: "cgrates.org", ID: "ROUTE_DESTINATION"}, &reply); err == nil ||
err.Error() != utils.ErrNotFound.Error() {
t.Error(err)
}
splPrf = &RouteWithCache{
routePrf = &RouteWithCache{
RouteProfile: &engine.RouteProfile{
Tenant: "cgrates.org",
ID: "ROUTE_DESTINATION",
@@ -1162,7 +1162,7 @@ func testV1RoutesOneRouteWithoutDestination(t *testing.T) {
}
var result string
if err := splSv1Rpc.Call(utils.APIerSv1SetRouteProfile, splPrf, &result); err != nil {
if err := routeSv1Rpc.Call(utils.APIerSv1SetRouteProfile, routePrf, &result); err != nil {
t.Error(err)
} else if result != utils.OK {
t.Error("Unexpected reply returned", result)
@@ -1198,7 +1198,7 @@ func testV1RoutesOneRouteWithoutDestination(t *testing.T) {
},
}
var suplsReply engine.SortedRoutes
if err := splSv1Rpc.Call(utils.RouteSv1GetRoutes,
if err := routeSv1Rpc.Call(utils.RouteSv1GetRoutes,
ev, &suplsReply); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(eSpls, suplsReply) {
@@ -1209,12 +1209,12 @@ func testV1RoutesOneRouteWithoutDestination(t *testing.T) {
func testV1RouteMultipleRouteSameID(t *testing.T) {
var reply *engine.RouteProfile
if err := splSv1Rpc.Call(utils.APIerSv1GetRouteProfile,
if err := routeSv1Rpc.Call(utils.APIerSv1GetRouteProfile,
&utils.TenantID{Tenant: "cgrates.org", ID: "MULTIPLE_ROUTES"}, &reply); err == nil ||
err.Error() != utils.ErrNotFound.Error() {
t.Error(err)
}
splPrf = &RouteWithCache{
routePrf = &RouteWithCache{
RouteProfile: &engine.RouteProfile{
Tenant: "cgrates.org",
ID: "MULTIPLE_ROUTES",
@@ -1239,7 +1239,7 @@ func testV1RouteMultipleRouteSameID(t *testing.T) {
}
var result string
if err := splSv1Rpc.Call(utils.APIerSv1SetRouteProfile, splPrf, &result); err != nil {
if err := routeSv1Rpc.Call(utils.APIerSv1SetRouteProfile, routePrf, &result); err != nil {
t.Error(err)
} else if result != utils.OK {
t.Error("Unexpected reply returned", result)
@@ -1277,7 +1277,7 @@ func testV1RouteMultipleRouteSameID(t *testing.T) {
},
}
var suplsReply engine.SortedRoutes
if err := splSv1Rpc.Call(utils.RouteSv1GetRoutes,
if err := routeSv1Rpc.Call(utils.RouteSv1GetRoutes,
ev, &suplsReply); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(eSpls, suplsReply) {
@@ -1316,7 +1316,7 @@ func testV1RouteMultipleRouteSameID(t *testing.T) {
},
},
}
if err := splSv1Rpc.Call(utils.RouteSv1GetRoutes,
if err := routeSv1Rpc.Call(utils.RouteSv1GetRoutes,
ev, &suplsReply); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(eSpls, suplsReply) {
@@ -1326,7 +1326,7 @@ func testV1RouteMultipleRouteSameID(t *testing.T) {
}
func testV1RouteAccountWithRatingPlan(t *testing.T) {
splPrf = &RouteWithCache{
routePrf = &RouteWithCache{
RouteProfile: &engine.RouteProfile{
Tenant: "cgrates.org",
ID: "RouteWithAccAndRP",
@@ -1350,7 +1350,7 @@ func testV1RouteAccountWithRatingPlan(t *testing.T) {
}
var result string
if err := splSv1Rpc.Call(utils.APIerSv1SetRouteProfile, splPrf, &result); err != nil {
if err := routeSv1Rpc.Call(utils.APIerSv1SetRouteProfile, routePrf, &result); err != nil {
t.Error(err)
} else if result != utils.OK {
t.Error("Unexpected reply returned", result)
@@ -1366,7 +1366,7 @@ func testV1RouteAccountWithRatingPlan(t *testing.T) {
},
}
var reply string
if err := splSv1Rpc.Call(utils.APIerSv2SetBalance, &attrSetBalance, &reply); err != nil {
if err := routeSv1Rpc.Call(utils.APIerSv2SetBalance, &attrSetBalance, &reply); err != nil {
t.Error(err)
} else if reply != utils.OK {
t.Errorf("Received: %s", reply)
@@ -1376,7 +1376,7 @@ func testV1RouteAccountWithRatingPlan(t *testing.T) {
Tenant: "cgrates.org",
Account: "AccWithVoice",
}
if err := splSv1Rpc.Call(utils.APIerSv2GetAccount, attrAcc, &acnt); err != nil {
if err := routeSv1Rpc.Call(utils.APIerSv2GetAccount, attrAcc, &acnt); err != nil {
t.Error(err)
} else if acnt.BalanceMap[utils.VOICE].GetTotalValue() != 30*float64(time.Second) {
t.Errorf("Unexpected balance received : %+v", acnt.BalanceMap[utils.VOICE].GetTotalValue())
@@ -1426,7 +1426,7 @@ func testV1RouteAccountWithRatingPlan(t *testing.T) {
},
}
var suplsReply *engine.SortedRoutes
if err := splSv1Rpc.Call(utils.RouteSv1GetRoutes,
if err := routeSv1Rpc.Call(utils.RouteSv1GetRoutes,
ev, &suplsReply); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(eSpls, suplsReply) {
@@ -1478,7 +1478,7 @@ func testV1RouteAccountWithRatingPlan(t *testing.T) {
},
}
var routeRply *engine.SortedRoutes
if err := splSv1Rpc.Call(utils.RouteSv1GetRoutes,
if err := routeSv1Rpc.Call(utils.RouteSv1GetRoutes,
ev, &routeRply); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(eSpls, routeRply) {
@@ -1530,7 +1530,7 @@ func testV1RouteAccountWithRatingPlan(t *testing.T) {
},
}
var routeRply2 *engine.SortedRoutes
if err := splSv1Rpc.Call(utils.RouteSv1GetRoutes,
if err := routeSv1Rpc.Call(utils.RouteSv1GetRoutes,
ev, &routeRply2); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(eSpls, routeRply2) {
@@ -1547,7 +1547,7 @@ func testV1RouteStopEngine(t *testing.T) {
}
func testV1RouteSetRouteProfilesWithoutTenant(t *testing.T) {
splPrf = &RouteWithCache{
routePrf = &RouteWithCache{
RouteProfile: &engine.RouteProfile{
Tenant: "cgrates.org",
ID: "TEST_PROFILE10",
@@ -1571,31 +1571,31 @@ func testV1RouteSetRouteProfilesWithoutTenant(t *testing.T) {
},
}
var reply string
if err := splSv1Rpc.Call(utils.APIerSv1SetRouteProfile, splPrf, &reply); err != nil {
if err := routeSv1Rpc.Call(utils.APIerSv1SetRouteProfile, routePrf, &reply); err != nil {
t.Error(err)
} else if reply != utils.OK {
t.Error("Unexpected reply returned", reply)
}
splPrf.Tenant = "cgrates.org"
routePrf.Tenant = "cgrates.org"
var result *engine.RouteProfile
if err := splSv1Rpc.Call(utils.APIerSv1GetRouteProfile,
if err := routeSv1Rpc.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))
} else if !reflect.DeepEqual(result, routePrf.RouteProfile) {
t.Errorf("Expected %+v, received %+v", utils.ToJSON(routePrf.RouteProfile), utils.ToJSON(result))
}
}
func testV1RouteRemRouteProfilesWithoutTenant(t *testing.T) {
var reply string
if err := splSv1Rpc.Call(utils.APIerSv1RemoveRouteProfile,
if err := routeSv1Rpc.Call(utils.APIerSv1RemoveRouteProfile,
&utils.TenantIDWithCache{ID: "TEST_PROFILE10"},
&reply); err != nil {
t.Error(err)
}
var result *engine.RouteProfile
if err := splSv1Rpc.Call(utils.APIerSv1GetRouteProfile,
if err := routeSv1Rpc.Call(utils.APIerSv1GetRouteProfile,
&utils.TenantID{ID: "TEST_PROFILE10"},
&result); err == nil || err.Error() != utils.ErrNotFound.Error() {
t.Error(err)

View File

@@ -0,0 +1,171 @@
// +build integration
/*
Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments
Copyright (C) ITsysCOM GmbH
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package v1
import (
"path"
"reflect"
"testing"
"time"
"github.com/cgrates/cgrates/config"
"github.com/cgrates/cgrates/engine"
"github.com/cgrates/cgrates/utils"
)
var (
sTestsRouteSWithRateSV1 = []func(t *testing.T){
testV1RouteSWithRateSLoadConfig,
testV1RouteSWithRateSInitDataDb,
testV1RouteSWithRateSResetStorDb,
testV1RouteSWithRateSStartEngine,
testV1RouteSWithRateSRpcConn,
testV1RouteSWithRateSFromFolder,
testV1RouteSWithRateSGetRoutes,
testV1RouteSWithRateSStopEngine,
}
)
// Test start here
func TestRouteSWithRateSV1IT(t *testing.T) {
switch *dbType {
case utils.MetaInternal:
routeSv1ConfDIR = "routes_with_rates_internal"
case utils.MetaMySQL:
routeSv1ConfDIR = "routes_with_rates_redis"
case utils.MetaMongo:
routeSv1ConfDIR = "routes_with_rates_mongo"
case utils.MetaPostgres:
t.SkipNow()
default:
t.Fatal("Unknown Database type")
}
for _, stest := range sTestsRouteSWithRateSV1 {
t.Run(routeSv1ConfDIR, stest)
}
}
func testV1RouteSWithRateSLoadConfig(t *testing.T) {
var err error
routeSv1CfgPath = path.Join(*dataDir, "conf", "samples", routeSv1ConfDIR)
if routeSv1Cfg, err = config.NewCGRConfigFromPath(routeSv1CfgPath); err != nil {
t.Error(err)
}
}
func testV1RouteSWithRateSInitDataDb(t *testing.T) {
if err := engine.InitDataDb(routeSv1Cfg); err != nil {
t.Fatal(err)
}
}
// Wipe out the cdr database
func testV1RouteSWithRateSResetStorDb(t *testing.T) {
if err := engine.InitStorDb(routeSv1Cfg); err != nil {
t.Fatal(err)
}
}
func testV1RouteSWithRateSStartEngine(t *testing.T) {
if _, err := engine.StopStartEngine(routeSv1CfgPath, *waitRater); err != nil {
t.Fatal(err)
}
}
func testV1RouteSWithRateSRpcConn(t *testing.T) {
var err error
routeSv1Rpc, err = newRPCClient(routeSv1Cfg.ListenCfg()) // We connect over JSON so we can also troubleshoot if needed
if err != nil {
t.Fatal("Could not connect to rater: ", err.Error())
}
}
func testV1RouteSWithRateSFromFolder(t *testing.T) {
var reply string
attrs := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "routes_with_rates")}
if err := routeSv1Rpc.Call(utils.APIerSv1LoadTariffPlanFromFolder, attrs, &reply); err != nil {
t.Error(err)
}
time.Sleep(500 * time.Millisecond)
}
func testV1RouteSWithRateSGetRoutes(t *testing.T) {
ev := &engine.ArgsGetRoutes{
CGREventWithOpts: &utils.CGREventWithOpts{
CGREvent: &utils.CGREvent{
Tenant: "cgrates.org",
ID: "testV1RouteSWithRateSGetRoutes",
Event: map[string]interface{}{
utils.Account: "1003",
utils.Subject: "1003",
utils.Destination: "1002",
utils.SetupTime: time.Date(2017, 12, 1, 14, 25, 0, 0, time.UTC),
utils.Usage: "1m20s",
"EventName": "RouteWithRateS",
},
},
},
}
expRoutes := engine.SortedRoutes{
ProfileID: "ROUTE_LC",
Sorting: utils.MetaLC,
Count: 3,
SortedRoutes: []*engine.SortedRoute{
{
RouteID: "route3",
SortingData: map[string]interface{}{
utils.Cost: 0.01333333333333334,
utils.RateProfileMatched: "RT_SPECIAL_1002",
utils.Weight: 15.0,
},
},
{
RouteID: "route1",
SortingData: map[string]interface{}{
utils.Cost: 0.01333333333333334,
utils.RateProfileMatched: "RT_SPECIAL_1002",
utils.Weight: 10.0,
},
},
{
RouteID: "route2",
SortingData: map[string]interface{}{
utils.Cost: 0.4666666666666667,
utils.RateProfileMatched: "RT_RETAIL1",
utils.Weight: 20.0,
},
},
},
}
var routesReply engine.SortedRoutes
if err := routeSv1Rpc.Call(utils.RouteSv1GetRoutes,
ev, &routesReply); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(expRoutes, routesReply) {
t.Errorf("Expecting: %s, \n received: %s",
utils.ToJSON(expRoutes), utils.ToJSON(routesReply))
}
}
func testV1RouteSWithRateSStopEngine(t *testing.T) {
if err := engine.KillEngine(100); err != nil {
t.Error(err)
}
}

View File

@@ -0,0 +1,55 @@
{
"general": {
"log_level": 7,
"reply_timeout": "50s",
},
"listen": {
"rpc_json": ":2012",
"rpc_gob": ":2013",
"http": ":2080",
},
"data_db": {
"db_type": "*internal",
},
"stor_db": {
"db_type": "*internal",
},
"rals": {
"enabled": true,
"max_increments":3000000,
},
"schedulers": {
"enabled": true,
},
"routes": {
"enabled": true,
"rates_conns": ["*internal"],
},
"apiers": {
"enabled": true,
"scheduler_conns": ["*internal"],
},
"rates": {
"enabled": true
},
}

View File

@@ -0,0 +1,57 @@
{
"general": {
"log_level": 7,
"reply_timeout": "50s",
},
"listen": {
"rpc_json": ":2012",
"rpc_gob": ":2013",
"http": ":2080",
},
"data_db": {
"db_type": "mongo",
"db_name": "10",
"db_port": 27017
},
"stor_db": {
"db_type": "*internal",
},
"rals": {
"enabled": true,
"max_increments":3000000,
},
"schedulers": {
"enabled": true,
},
"routes": {
"enabled": true,
"rates_conns": ["*internal"],
},
"apiers": {
"enabled": true,
"scheduler_conns": ["*internal"],
},
"rates": {
"enabled": true
},
}

View File

@@ -0,0 +1,57 @@
{
"general": {
"log_level": 7,
"reply_timeout": "50s",
},
"listen": {
"rpc_json": ":2012",
"rpc_gob": ":2013",
"http": ":2080",
},
"data_db": {
"db_type": "redis",
"db_port": 6379,
"db_name": "10",
},
"stor_db": {
"db_type": "*internal",
},
"rals": {
"enabled": true,
"max_increments":3000000,
},
"schedulers": {
"enabled": true,
},
"routes": {
"enabled": true,
"rates_conns": ["*internal"]
},
"apiers": {
"enabled": true,
"scheduler_conns": ["*internal"],
},
"rates": {
"enabled": true
},
}

View File

@@ -85,7 +85,6 @@
"stats_conns": ["*internal"],
"resources_conns": ["*internal"],
"rals_conns": ["*internal"],
"rates_conns": ["*localhost"],
},

View File

@@ -79,7 +79,6 @@
"stats_conns": ["*localhost"],
"resources_conns": ["*localhost"],
"rals_conns": ["*internal"],
"rates_conns": ["*localhost"],
},

View File

@@ -85,7 +85,6 @@
"stats_conns": ["*internal"],
"resources_conns": ["*internal"],
"rals_conns": ["*internal"],
"rates_conns": ["*localhost"],
},

View File

@@ -1,4 +1,4 @@
#Tenant,ID,FilterIDs,ActivationInterval,Sorting,SortingParameters,RouteID,RouteFilterIDs,RouteAccountIDs,RouteRatingPlanIDs,RouteResourceIDs,RouteStatIDs,RouteWeight,RouteBlocker,RouteParameters,Weight
cgrates.org,ROUTE_CLUELRN_INTER,*string:~*req.Account:9174269000;*string:~*req.LRNJurisdiction:INTER,2017-11-27T00:00:00Z,*lc,,LEVEL3,,,RP_LEVEL3_INTER,,,,false,,10
cgrates.org,ROUTE_CLUELRN_INTER,,,,,TMOBILE,,,RP_TMOBILE_INTER,,,,false,,
cgrates.org,ROUTE_CLUELRN_INTER,,,,,COMCAST,,,RP_COMCAST_INTER,,,,false,,
#Tenant,ID,FilterIDs,ActivationInterval,Sorting,SortingParameters,RouteID,RouteFilterIDs,RouteAccountIDs,RouteRatingPlanIDs,RouteRateProfileIDs,RouteResourceIDs,RouteStatIDs,RouteWeight,RouteBlocker,RouteParameters,Weight
cgrates.org,ROUTE_CLUELRN_INTER,*string:~*req.Account:9174269000;*string:~*req.LRNJurisdiction:INTER,2017-11-27T00:00:00Z,*lc,,LEVEL3,,,RP_LEVEL3_INTER,,,,,false,,10
cgrates.org,ROUTE_CLUELRN_INTER,,,,,TMOBILE,,,RP_TMOBILE_INTER,,,,,false,,
cgrates.org,ROUTE_CLUELRN_INTER,,,,,COMCAST,,,RP_COMCAST_INTER,,,,,false,,
1 #Tenant ID FilterIDs ActivationInterval Sorting SortingParameters RouteID RouteFilterIDs RouteAccountIDs RouteRatingPlanIDs RouteRateProfileIDs RouteResourceIDs RouteStatIDs RouteWeight RouteBlocker RouteParameters Weight
2 cgrates.org ROUTE_CLUELRN_INTER *string:~*req.Account:9174269000;*string:~*req.LRNJurisdiction:INTER 2017-11-27T00:00:00Z *lc LEVEL3 RP_LEVEL3_INTER false 10
3 cgrates.org ROUTE_CLUELRN_INTER TMOBILE RP_TMOBILE_INTER false
4 cgrates.org ROUTE_CLUELRN_INTER COMCAST RP_COMCAST_INTER false

View File

@@ -1,4 +1,4 @@
#Tenant,ID,FilterIDs,ActivationInterval,Sorting,SortingParameters,RouteID,RouteFilterIDs,RouteAccountIDs,RouteRatingPlanIDs,RouteResourceIDs,RouteStatIDs,RouteWeight,RouteBlocker,RouteParameters,Weight
cgrates.org,ROUTE_ACNT_1001,*string:~*req.Account:1001,,*weight,,route1,,,,,,10,,!^(.*)$!sip:\1@172.16.1.11!,10
cgrates.org,ROUTE_ACNT_1001,,,,,route2,,,,,,5,,!^(.*)$!sip:\1@172.16.1.12!,10
#Tenant,ID,FilterIDs,ActivationInterval,Sorting,SortingParameters,RouteID,RouteFilterIDs,RouteAccountIDs,RouteRatingPlanIDs,RouteRateProfileIDs,RouteResourceIDs,RouteStatIDs,RouteWeight,RouteBlocker,RouteParameters,Weight
cgrates.org,ROUTE_ACNT_1001,*string:~*req.Account:1001,,*weight,,route1,,,,,,,10,,!^(.*)$!sip:\1@172.16.1.11!,10
cgrates.org,ROUTE_ACNT_1001,,,,,route2,,,,,,,5,,!^(.*)$!sip:\1@172.16.1.12!,10
1 #Tenant ID FilterIDs ActivationInterval Sorting SortingParameters RouteID RouteFilterIDs RouteAccountIDs RouteRatingPlanIDs RouteRateProfileIDs RouteResourceIDs RouteStatIDs RouteWeight RouteBlocker RouteParameters Weight
2 cgrates.org ROUTE_ACNT_1001 *string:~*req.Account:1001 *weight route1 10 !^(.*)$!sip:\1@172.16.1.11! 10
3 cgrates.org ROUTE_ACNT_1001 route2 5 !^(.*)$!sip:\1@172.16.1.12! 10
4

View File

@@ -1,8 +1,8 @@
#Tenant,ID,FilterIDs,ActivationInterval,Sorting,SortingParameters,RouteID,RouteFilterIDs,RouteAccountIDs,RouteRatingPlanIDs,RouteResourceIDs,RouteStatIDs,RouteWeight,RouteBlocker,RouteParameters,Weight
cgrates.org,ROUTE_WEIGHT_2,,2017-11-27T00:00:00Z,*weight,,route1,,,,,,10,,,5
cgrates.org,ROUTE_WEIGHT_1,FLTR_DST_DE;FLTR_ACNT_1007,2017-11-27T00:00:00Z,*weight,,route1,,,,,,10,,,10
cgrates.org,ROUTE_WEIGHT_1,FLTR_DST_DE,,,,route2,,,,,,20,,,
cgrates.org,ROUTE_WEIGHT_1,FLTR_ACNT_1007,,,,route3,FLTR_ACNT_dan,,,,,15,,,
cgrates.org,ROUTE_LEASTCOST_1,FLTR_1,2017-11-27T00:00:00Z,*lc,,route1,,,RP_SPECIAL_1002,,,10,false,,10
cgrates.org,ROUTE_LEASTCOST_1,,,,,route2,,,RP_RETAIL1,,,20,,,
cgrates.org,ROUTE_LEASTCOST_1,,,,,route3,,,RP_SPECIAL_1002,,,15,,,
#Tenant,ID,FilterIDs,ActivationInterval,Sorting,SortingParameters,RouteID,RouteFilterIDs,RouteAccountIDs,RouteRatingPlanIDs,RouteRateProfileIDs,RouteResourceIDs,RouteStatIDs,RouteWeight,RouteBlocker,RouteParameters,Weight
cgrates.org,ROUTE_WEIGHT_2,,2017-11-27T00:00:00Z,*weight,,route1,,,,,,,10,,,5
cgrates.org,ROUTE_WEIGHT_1,FLTR_DST_DE;FLTR_ACNT_1007,2017-11-27T00:00:00Z,*weight,,route1,,,,,,,10,,,10
cgrates.org,ROUTE_WEIGHT_1,FLTR_DST_DE,,,,route2,,,,,,,20,,,
cgrates.org,ROUTE_WEIGHT_1,FLTR_ACNT_1007,,,,route3,FLTR_ACNT_dan,,,,,,15,,,
cgrates.org,ROUTE_LEASTCOST_1,FLTR_1,2017-11-27T00:00:00Z,*lc,,route1,,,RP_SPECIAL_1002,,,,10,false,,10
cgrates.org,ROUTE_LEASTCOST_1,,,,,route2,,,RP_RETAIL1,,,,20,,,
cgrates.org,ROUTE_LEASTCOST_1,,,,,route3,,,RP_SPECIAL_1002,,,,15,,,
1 #Tenant ID FilterIDs ActivationInterval Sorting SortingParameters RouteID RouteFilterIDs RouteAccountIDs RouteRatingPlanIDs RouteRateProfileIDs RouteResourceIDs RouteStatIDs RouteWeight RouteBlocker RouteParameters Weight
2 cgrates.org ROUTE_WEIGHT_2 2017-11-27T00:00:00Z *weight route1 10 5
3 cgrates.org ROUTE_WEIGHT_1 FLTR_DST_DE;FLTR_ACNT_1007 2017-11-27T00:00:00Z *weight route1 10 10
4 cgrates.org ROUTE_WEIGHT_1 FLTR_DST_DE route2 20
5 cgrates.org ROUTE_WEIGHT_1 FLTR_ACNT_1007 route3 FLTR_ACNT_dan 15
6 cgrates.org ROUTE_LEASTCOST_1 FLTR_1 2017-11-27T00:00:00Z *lc route1 RP_SPECIAL_1002 10 false 10
7 cgrates.org ROUTE_LEASTCOST_1 route2 RP_RETAIL1 20
8 cgrates.org ROUTE_LEASTCOST_1 route3 RP_SPECIAL_1002 15

View File

@@ -1,8 +1,8 @@
#Tenant,ID,FilterIDs,ActivationInterval,Sorting,SortingParameters,RouteID,RouteFilterIDs,RouteAccountIDs,RouteRatingPlanIDs,RouteResourceIDs,RouteStatIDs,RouteWeight,RouteBlocker,RouteParameters,Weight
cgrates.org,ROUTE_WEIGHT_2,,2017-11-27T00:00:00Z,*weight,,route1,,,,,,10,,,5
cgrates.org,ROUTE_WEIGHT_1,FLTR_DST_DE;FLTR_ACNT_1007,2017-11-27T00:00:00Z,*weight,,route1,,,,,,10,,,10
cgrates.org,ROUTE_WEIGHT_1,FLTR_DST_DE,,,,route2,,,,,,20,,,
cgrates.org,ROUTE_WEIGHT_1,FLTR_ACNT_1007,,,,route3,FLTR_ACNT_dan,,,,,15,,,
cgrates.org,ROUTE_LEASTCOST_1,FLTR_1,2017-11-27T00:00:00Z,*lc,,route1,,,RP_SPECIAL_1002,,,10,false,,10
cgrates.org,ROUTE_LEASTCOST_1,,,,,route2,,,RP_RETAIL1,,,20,,,
cgrates.org,ROUTE_LEASTCOST_1,,,,,route3,,,RP_SPECIAL_1002,,,15,,,
#Tenant,ID,FilterIDs,ActivationInterval,Sorting,SortingParameters,RouteID,RouteFilterIDs,RouteAccountIDs,RouteRatingPlanIDs,RouteRateProfileIDs,RouteResourceIDs,RouteStatIDs,RouteWeight,RouteBlocker,RouteParameters,Weight
cgrates.org,ROUTE_WEIGHT_2,,2017-11-27T00:00:00Z,*weight,,route1,,,,,,,10,,,5
cgrates.org,ROUTE_WEIGHT_1,FLTR_DST_DE;FLTR_ACNT_1007,2017-11-27T00:00:00Z,*weight,,route1,,,,,,,10,,,10
cgrates.org,ROUTE_WEIGHT_1,FLTR_DST_DE,,,,route2,,,,,,,20,,,
cgrates.org,ROUTE_WEIGHT_1,FLTR_ACNT_1007,,,,route3,FLTR_ACNT_dan,,,,,,15,,,
cgrates.org,ROUTE_LEASTCOST_1,FLTR_1,2017-11-27T00:00:00Z,*lc,,route1,,,RP_SPECIAL_1002,,,,10,false,,10
cgrates.org,ROUTE_LEASTCOST_1,,,,,route2,,,RP_RETAIL1,,,,20,,,
cgrates.org,ROUTE_LEASTCOST_1,,,,,route3,,,RP_SPECIAL_1002,,,,15,,,
1 #Tenant ID FilterIDs ActivationInterval Sorting SortingParameters RouteID RouteFilterIDs RouteAccountIDs RouteRatingPlanIDs RouteRateProfileIDs RouteResourceIDs RouteStatIDs RouteWeight RouteBlocker RouteParameters Weight
2 cgrates.org ROUTE_WEIGHT_2 2017-11-27T00:00:00Z *weight route1 10 5
3 cgrates.org ROUTE_WEIGHT_1 FLTR_DST_DE;FLTR_ACNT_1007 2017-11-27T00:00:00Z *weight route1 10 10
4 cgrates.org ROUTE_WEIGHT_1 FLTR_DST_DE route2 20
5 cgrates.org ROUTE_WEIGHT_1 FLTR_ACNT_1007 route3 FLTR_ACNT_dan 15
6 cgrates.org ROUTE_LEASTCOST_1 FLTR_1 2017-11-27T00:00:00Z *lc route1 RP_SPECIAL_1002 10 false 10
7 cgrates.org ROUTE_LEASTCOST_1 route2 RP_RETAIL1 20
8 cgrates.org ROUTE_LEASTCOST_1 route3 RP_SPECIAL_1002 15

View File

@@ -0,0 +1,5 @@
#Tenant,ID,FilterIDs,ActivationInterval,Weight,ConnectFee,RoundingMethod,RoundingDecimals,MinCost,MaxCost,MaxCostStrategy,RateID,RateFilterIDs,RateActivationStart,RateWeight,RateBlocker,RateIntervalStart,RateValue,RateUnit,RateIncrement
cgrates.org,RT_SPECIAL_1002,,,0,0,*up,4,0,0,*free,RT_ALWAYS,,"* * * * *",0,false,0s,0.01,1m,1s
cgrates.org,RT_RETAIL1,,,0,0,*up,4,0,0,*free,RT_ALWAYS,,"* * * * *",0,false,0s,0.4,1m,30s
cgrates.org,RT_RETAIL1,,,,,,,,,,RT_ALWAYS,,"* * * * *",0,false,1m,0.2,1m,10s
1 #Tenant ID FilterIDs ActivationInterval Weight ConnectFee RoundingMethod RoundingDecimals MinCost MaxCost MaxCostStrategy RateID RateFilterIDs RateActivationStart RateWeight RateBlocker RateIntervalStart RateValue RateUnit RateIncrement
2 cgrates.org RT_SPECIAL_1002 0 0 *up 4 0 0 *free RT_ALWAYS * * * * * 0 false 0s 0.01 1m 1s
3 cgrates.org RT_RETAIL1 0 0 *up 4 0 0 *free RT_ALWAYS * * * * * 0 false 0s 0.4 1m 30s
4 cgrates.org RT_RETAIL1 RT_ALWAYS * * * * * 0 false 1m 0.2 1m 10s

View File

@@ -0,0 +1,4 @@
#Tenant,ID,FilterIDs,ActivationInterval,Sorting,SortingParameters,RouteID,RouteFilterIDs,RouteAccountIDs,RouteRatingPlanIDs,RouteRateProfileIDs,RouteResourceIDs,RouteStatIDs,RouteWeight,RouteBlocker,RouteParameters,Weight
cgrates.org,ROUTE_LC,*string:~*req.EventName:RouteWithRateS,2017-11-27T00:00:00Z,*lc,,route1,,,,RT_SPECIAL_1002,,,10,false,,10
cgrates.org,ROUTE_LC,,,,,route2,,,,RT_RETAIL1,,,20,,,
cgrates.org,ROUTE_LC,,,,,route3,,,,RT_SPECIAL_1002,,,15,,,
1 #Tenant ID FilterIDs ActivationInterval Sorting SortingParameters RouteID RouteFilterIDs RouteAccountIDs RouteRatingPlanIDs RouteRateProfileIDs RouteResourceIDs RouteStatIDs RouteWeight RouteBlocker RouteParameters Weight
2 cgrates.org ROUTE_LC *string:~*req.EventName:RouteWithRateS 2017-11-27T00:00:00Z *lc route1 RT_SPECIAL_1002 10 false 10
3 cgrates.org ROUTE_LC route2 RT_RETAIL1 20
4 cgrates.org ROUTE_LC route3 RT_SPECIAL_1002 15

View File

@@ -1,33 +1,33 @@
#Tenant,ID,FilterIDs,ActivationInterval,Sorting,SortingParameters,RouteID,RouteFilterIDs,RouteAccountIDs,RouteRatingPlanIDs,RouteRateProfileIDs,RouteResourceIDs,RouteStatIDs,RouteWeight,RouteBlocker,RouteParameters,Weight
cgrates.org,ROUTE_ACNT_1001,FLTR_ACCOUNT_1001,,*weight,,route1,,,,,,20,,,10
cgrates.org,ROUTE_ACNT_1001,,,,,route2,,,,,,10,,,
cgrates.org,ROUTE_WEIGHT_2,,2017-11-27T00:00:00Z,*weight,,route1,,,,,,10,,,5
cgrates.org,ROUTE_WEIGHT_1,FLTR_DST_DE;FLTR_ACNT_1007,2017-11-27T00:00:00Z,*weight,,route1,,,,,,10,,,10
cgrates.org,ROUTE_WEIGHT_1,FLTR_DST_DE,,,,route2,,,,,,20,,,
cgrates.org,ROUTE_WEIGHT_1,FLTR_ACNT_1007,,,,route3,FLTR_SPP_ACNT_dan,,,,,15,,,
cgrates.org,ROUTE_LEASTCOST_1,FLTR_1,2017-11-27T00:00:00Z,*lc,,route1,,,RP_SPECIAL_1002,RT_SPECIAL_1002,,,10,false,,10
cgrates.org,ROUTE_LEASTCOST_1,,,,,route2,,,RP_RETAIL1,RT_RETAIL1,,,20,,,
cgrates.org,ROUTE_LEASTCOST_1,,,,,route3,,,RP_SPECIAL_1002,RT_SPECIAL_1002,,,15,,,
cgrates.org,ROUTE_HIGHESTCOST_1,FLTR_SPP_2,2017-11-27T00:00:00Z,*hc,,route1,,,RP_SPECIAL_1002,,,10,false,,20
cgrates.org,ROUTE_HIGHESTCOST_1,,,,,route2,,,RP_RETAIL1,,,20,,,
cgrates.org,ROUTE_HIGHESTCOST_1,,,,,route3,,,RP_SPECIAL_1002,,,15,,,
cgrates.org,ROUTE_QOS_1,FLTR_SPP_3,2017-11-27T00:00:00Z,*qos,*acd;*tcd;*asr,route1,,,,,Stat_1;Stat_1_1,10,false,,20
cgrates.org,ROUTE_QOS_1,,,,,route2,,,,,Stat_2,20,,,
cgrates.org,ROUTE_QOS_1,,,,,route3,,,,,Stat_3,35,,,
cgrates.org,ROUTE_QOS_2,FLTR_SPP_4,2017-11-27T00:00:00Z,*qos,*dcc,route1,,,,,Stat_1;Stat_1_1,10,false,,20
cgrates.org,ROUTE_QOS_2,,,,,route2,,,,,Stat_2,20,,,
cgrates.org,ROUTE_QOS_2,,,,,route3,,,,,Stat_3,35,,,
cgrates.org,ROUTE_QOS_3,FLTR_SPP_5,2017-11-27T00:00:00Z,*qos,*pdd,route1,,,,,Stat_1;Stat_1_1,10,false,,20
cgrates.org,ROUTE_QOS_3,,,,,route2,,,,,Stat_2,20,,,
cgrates.org,ROUTE_QOS_3,,,,,route3,,,,,Stat_3,35,,,
cgrates.org,ROUTE_QOS_FILTRED,FLTR_SPP_6,2017-11-27T00:00:00Z,*qos,*pdd,route1,FLTR_QOS_SP1,,,,Stat_1;Stat_1_1,10,false,,20
cgrates.org,ROUTE_QOS_FILTRED,,,,,route2,FLTR_QOS_SP2,,,,Stat_2,20,,,
cgrates.org,ROUTE_QOS_FILTRED,,,,,route3,,,,,Stat_3,35,,,
cgrates.org,ROUTE_QOS_FILTRED2,FLTR_SPP_QOS_2,2017-11-27T00:00:00Z,*qos,*acd;*tcd;*asr,route1,FLTR_QOS_SP1_2,,RP_SPECIAL_1002,,Stat_1;Stat_1_1,10,false,,20
cgrates.org,ROUTE_QOS_FILTRED2,,,,,route2,FLTR_QOS_SP2_2,,RP_RETAIL1,,Stat_2,20,,,
cgrates.org,ROUTE_QOS_FILTRED2,,,,,route3,,,,,Stat_3,35,,,
cgrates.org,ROUTE_LCR,FLTR_TEST,2017-11-27T00:00:00Z,*lc,,route_1,,,RP_TEST_1,,,10,,,50
cgrates.org,ROUTE_LCR,,,,,route_2,,,RP_TEST_2,,,,,,
cgrates.org,ROUTE_LOAD_DIST,FLTR_SPP_LOAD_DIST,,*load,route1:2;route2:7;*default:5,route1,,,,,Stat_Supplier1:*sum#~*req.LoadReq,10,false,,20
cgrates.org,ROUTE_LOAD_DIST,,,,,route2,,,,,Stat_Supplier2:*sum#~*req.LoadReq,20,,,
cgrates.org,ROUTE_LOAD_DIST,,,,,route3,,,,,Stat_Supplier3:*sum#~*req.LoadReq,35,,,
cgrates.org,ROUTE_ACNT_1001,FLTR_ACCOUNT_1001,,*weight,,route1,,,,,,,20,,,10
cgrates.org,ROUTE_ACNT_1001,,,,,route2,,,,,,,10,,,
cgrates.org,ROUTE_WEIGHT_2,,2017-11-27T00:00:00Z,*weight,,route1,,,,,,,10,,,5
cgrates.org,ROUTE_WEIGHT_1,FLTR_DST_DE;FLTR_ACNT_1007,2017-11-27T00:00:00Z,*weight,,route1,,,,,,,10,,,10
cgrates.org,ROUTE_WEIGHT_1,FLTR_DST_DE,,,,route2,,,,,,,20,,,
cgrates.org,ROUTE_WEIGHT_1,FLTR_ACNT_1007,,,,route3,FLTR_SPP_ACNT_dan,,,,,,15,,,
cgrates.org,ROUTE_LEASTCOST_1,FLTR_1,2017-11-27T00:00:00Z,*lc,,route1,,,RP_SPECIAL_1002,,,,10,false,,10
cgrates.org,ROUTE_LEASTCOST_1,,,,,route2,,,RP_RETAIL1,,,,20,,,
cgrates.org,ROUTE_LEASTCOST_1,,,,,route3,,,RP_SPECIAL_1002,,,,15,,,
cgrates.org,ROUTE_HIGHESTCOST_1,FLTR_SPP_2,2017-11-27T00:00:00Z,*hc,,route1,,,RP_SPECIAL_1002,,,,10,false,,20
cgrates.org,ROUTE_HIGHESTCOST_1,,,,,route2,,,RP_RETAIL1,,,,20,,,
cgrates.org,ROUTE_HIGHESTCOST_1,,,,,route3,,,RP_SPECIAL_1002,,,,15,,,
cgrates.org,ROUTE_QOS_1,FLTR_SPP_3,2017-11-27T00:00:00Z,*qos,*acd;*tcd;*asr,route1,,,,,,Stat_1;Stat_1_1,10,false,,20
cgrates.org,ROUTE_QOS_1,,,,,route2,,,,,,Stat_2,20,,,
cgrates.org,ROUTE_QOS_1,,,,,route3,,,,,,Stat_3,35,,,
cgrates.org,ROUTE_QOS_2,FLTR_SPP_4,2017-11-27T00:00:00Z,*qos,*dcc,route1,,,,,,Stat_1;Stat_1_1,10,false,,20
cgrates.org,ROUTE_QOS_2,,,,,route2,,,,,,Stat_2,20,,,
cgrates.org,ROUTE_QOS_2,,,,,route3,,,,,,Stat_3,35,,,
cgrates.org,ROUTE_QOS_3,FLTR_SPP_5,2017-11-27T00:00:00Z,*qos,*pdd,route1,,,,,,Stat_1;Stat_1_1,10,false,,20
cgrates.org,ROUTE_QOS_3,,,,,route2,,,,,,Stat_2,20,,,
cgrates.org,ROUTE_QOS_3,,,,,route3,,,,,,Stat_3,35,,,
cgrates.org,ROUTE_QOS_FILTRED,FLTR_SPP_6,2017-11-27T00:00:00Z,*qos,*pdd,route1,FLTR_QOS_SP1,,,,,Stat_1;Stat_1_1,10,false,,20
cgrates.org,ROUTE_QOS_FILTRED,,,,,route2,FLTR_QOS_SP2,,,,,Stat_2,20,,,
cgrates.org,ROUTE_QOS_FILTRED,,,,,route3,,,,,,Stat_3,35,,,
cgrates.org,ROUTE_QOS_FILTRED2,FLTR_SPP_QOS_2,2017-11-27T00:00:00Z,*qos,*acd;*tcd;*asr,route1,FLTR_QOS_SP1_2,,RP_SPECIAL_1002,,,Stat_1;Stat_1_1,10,false,,20
cgrates.org,ROUTE_QOS_FILTRED2,,,,,route2,FLTR_QOS_SP2_2,,RP_RETAIL1,,,Stat_2,20,,,
cgrates.org,ROUTE_QOS_FILTRED2,,,,,route3,,,,,,Stat_3,35,,,
cgrates.org,ROUTE_LCR,FLTR_TEST,2017-11-27T00:00:00Z,*lc,,route_1,,,RP_TEST_1,,,,10,,,50
cgrates.org,ROUTE_LCR,,,,,route_2,,,RP_TEST_2,,,,,,,
cgrates.org,ROUTE_LOAD_DIST,FLTR_SPP_LOAD_DIST,,*load,route1:2;route2:7;*default:5,route1,,,,,,Stat_Supplier1:*sum#~*req.LoadReq,10,false,,20
cgrates.org,ROUTE_LOAD_DIST,,,,,route2,,,,,,Stat_Supplier2:*sum#~*req.LoadReq,20,,,
cgrates.org,ROUTE_LOAD_DIST,,,,,route3,,,,,,Stat_Supplier3:*sum#~*req.LoadReq,35,,,
1 #Tenant,ID,FilterIDs,ActivationInterval,Sorting,SortingParameters,RouteID,RouteFilterIDs,RouteAccountIDs,RouteRatingPlanIDs,RouteRateProfileIDs,RouteResourceIDs,RouteStatIDs,RouteWeight,RouteBlocker,RouteParameters,Weight #Tenant ID FilterIDs ActivationInterval Sorting SortingParameters RouteID RouteFilterIDs RouteAccountIDs RouteRatingPlanIDs RouteRateProfileIDs RouteResourceIDs RouteStatIDs RouteWeight RouteBlocker RouteParameters Weight
2 cgrates.org,ROUTE_ACNT_1001,FLTR_ACCOUNT_1001,,*weight,,route1,,,,,,20,,,10 cgrates.org ROUTE_ACNT_1001 FLTR_ACCOUNT_1001 *weight route1 20 10
3 cgrates.org,ROUTE_ACNT_1001,,,,,route2,,,,,,10,,, cgrates.org ROUTE_ACNT_1001 route2 10
4 cgrates.org,ROUTE_WEIGHT_2,,2017-11-27T00:00:00Z,*weight,,route1,,,,,,10,,,5 cgrates.org ROUTE_WEIGHT_2 2017-11-27T00:00:00Z *weight route1 10 5
5 cgrates.org,ROUTE_WEIGHT_1,FLTR_DST_DE;FLTR_ACNT_1007,2017-11-27T00:00:00Z,*weight,,route1,,,,,,10,,,10 cgrates.org ROUTE_WEIGHT_1 FLTR_DST_DE;FLTR_ACNT_1007 2017-11-27T00:00:00Z *weight route1 10 10
6 cgrates.org,ROUTE_WEIGHT_1,FLTR_DST_DE,,,,route2,,,,,,20,,, cgrates.org ROUTE_WEIGHT_1 FLTR_DST_DE route2 20
7 cgrates.org,ROUTE_WEIGHT_1,FLTR_ACNT_1007,,,,route3,FLTR_SPP_ACNT_dan,,,,,15,,, cgrates.org ROUTE_WEIGHT_1 FLTR_ACNT_1007 route3 FLTR_SPP_ACNT_dan 15
8 cgrates.org,ROUTE_LEASTCOST_1,FLTR_1,2017-11-27T00:00:00Z,*lc,,route1,,,RP_SPECIAL_1002,RT_SPECIAL_1002,,,10,false,,10 cgrates.org ROUTE_LEASTCOST_1 FLTR_1 2017-11-27T00:00:00Z *lc route1 RP_SPECIAL_1002 10 false 10
9 cgrates.org,ROUTE_LEASTCOST_1,,,,,route2,,,RP_RETAIL1,RT_RETAIL1,,,20,,, cgrates.org ROUTE_LEASTCOST_1 route2 RP_RETAIL1 20
10 cgrates.org,ROUTE_LEASTCOST_1,,,,,route3,,,RP_SPECIAL_1002,RT_SPECIAL_1002,,,15,,, cgrates.org ROUTE_LEASTCOST_1 route3 RP_SPECIAL_1002 15
11 cgrates.org,ROUTE_HIGHESTCOST_1,FLTR_SPP_2,2017-11-27T00:00:00Z,*hc,,route1,,,RP_SPECIAL_1002,,,10,false,,20 cgrates.org ROUTE_HIGHESTCOST_1 FLTR_SPP_2 2017-11-27T00:00:00Z *hc route1 RP_SPECIAL_1002 10 false 20
12 cgrates.org,ROUTE_HIGHESTCOST_1,,,,,route2,,,RP_RETAIL1,,,20,,, cgrates.org ROUTE_HIGHESTCOST_1 route2 RP_RETAIL1 20
13 cgrates.org,ROUTE_HIGHESTCOST_1,,,,,route3,,,RP_SPECIAL_1002,,,15,,, cgrates.org ROUTE_HIGHESTCOST_1 route3 RP_SPECIAL_1002 15
14 cgrates.org,ROUTE_QOS_1,FLTR_SPP_3,2017-11-27T00:00:00Z,*qos,*acd;*tcd;*asr,route1,,,,,Stat_1;Stat_1_1,10,false,,20 cgrates.org ROUTE_QOS_1 FLTR_SPP_3 2017-11-27T00:00:00Z *qos *acd;*tcd;*asr route1 Stat_1;Stat_1_1 10 false 20
15 cgrates.org,ROUTE_QOS_1,,,,,route2,,,,,Stat_2,20,,, cgrates.org ROUTE_QOS_1 route2 Stat_2 20
16 cgrates.org,ROUTE_QOS_1,,,,,route3,,,,,Stat_3,35,,, cgrates.org ROUTE_QOS_1 route3 Stat_3 35
17 cgrates.org,ROUTE_QOS_2,FLTR_SPP_4,2017-11-27T00:00:00Z,*qos,*dcc,route1,,,,,Stat_1;Stat_1_1,10,false,,20 cgrates.org ROUTE_QOS_2 FLTR_SPP_4 2017-11-27T00:00:00Z *qos *dcc route1 Stat_1;Stat_1_1 10 false 20
18 cgrates.org,ROUTE_QOS_2,,,,,route2,,,,,Stat_2,20,,, cgrates.org ROUTE_QOS_2 route2 Stat_2 20
19 cgrates.org,ROUTE_QOS_2,,,,,route3,,,,,Stat_3,35,,, cgrates.org ROUTE_QOS_2 route3 Stat_3 35
20 cgrates.org,ROUTE_QOS_3,FLTR_SPP_5,2017-11-27T00:00:00Z,*qos,*pdd,route1,,,,,Stat_1;Stat_1_1,10,false,,20 cgrates.org ROUTE_QOS_3 FLTR_SPP_5 2017-11-27T00:00:00Z *qos *pdd route1 Stat_1;Stat_1_1 10 false 20
21 cgrates.org,ROUTE_QOS_3,,,,,route2,,,,,Stat_2,20,,, cgrates.org ROUTE_QOS_3 route2 Stat_2 20
22 cgrates.org,ROUTE_QOS_3,,,,,route3,,,,,Stat_3,35,,, cgrates.org ROUTE_QOS_3 route3 Stat_3 35
23 cgrates.org,ROUTE_QOS_FILTRED,FLTR_SPP_6,2017-11-27T00:00:00Z,*qos,*pdd,route1,FLTR_QOS_SP1,,,,Stat_1;Stat_1_1,10,false,,20 cgrates.org ROUTE_QOS_FILTRED FLTR_SPP_6 2017-11-27T00:00:00Z *qos *pdd route1 FLTR_QOS_SP1 Stat_1;Stat_1_1 10 false 20
24 cgrates.org,ROUTE_QOS_FILTRED,,,,,route2,FLTR_QOS_SP2,,,,Stat_2,20,,, cgrates.org ROUTE_QOS_FILTRED route2 FLTR_QOS_SP2 Stat_2 20
25 cgrates.org,ROUTE_QOS_FILTRED,,,,,route3,,,,,Stat_3,35,,, cgrates.org ROUTE_QOS_FILTRED route3 Stat_3 35
26 cgrates.org,ROUTE_QOS_FILTRED2,FLTR_SPP_QOS_2,2017-11-27T00:00:00Z,*qos,*acd;*tcd;*asr,route1,FLTR_QOS_SP1_2,,RP_SPECIAL_1002,,Stat_1;Stat_1_1,10,false,,20 cgrates.org ROUTE_QOS_FILTRED2 FLTR_SPP_QOS_2 2017-11-27T00:00:00Z *qos *acd;*tcd;*asr route1 FLTR_QOS_SP1_2 RP_SPECIAL_1002 Stat_1;Stat_1_1 10 false 20
27 cgrates.org,ROUTE_QOS_FILTRED2,,,,,route2,FLTR_QOS_SP2_2,,RP_RETAIL1,,Stat_2,20,,, cgrates.org ROUTE_QOS_FILTRED2 route2 FLTR_QOS_SP2_2 RP_RETAIL1 Stat_2 20
28 cgrates.org,ROUTE_QOS_FILTRED2,,,,,route3,,,,,Stat_3,35,,, cgrates.org ROUTE_QOS_FILTRED2 route3 Stat_3 35
29 cgrates.org,ROUTE_LCR,FLTR_TEST,2017-11-27T00:00:00Z,*lc,,route_1,,,RP_TEST_1,,,10,,,50 cgrates.org ROUTE_LCR FLTR_TEST 2017-11-27T00:00:00Z *lc route_1 RP_TEST_1 10 50
30 cgrates.org,ROUTE_LCR,,,,,route_2,,,RP_TEST_2,,,,,, cgrates.org ROUTE_LCR route_2 RP_TEST_2
31 cgrates.org,ROUTE_LOAD_DIST,FLTR_SPP_LOAD_DIST,,*load,route1:2;route2:7;*default:5,route1,,,,,Stat_Supplier1:*sum#~*req.LoadReq,10,false,,20 cgrates.org ROUTE_LOAD_DIST FLTR_SPP_LOAD_DIST *load route1:2;route2:7;*default:5 route1 Stat_Supplier1:*sum#~*req.LoadReq 10 false 20
32 cgrates.org,ROUTE_LOAD_DIST,,,,,route2,,,,,Stat_Supplier2:*sum#~*req.LoadReq,20,,, cgrates.org ROUTE_LOAD_DIST route2 Stat_Supplier2:*sum#~*req.LoadReq 20
33 cgrates.org,ROUTE_LOAD_DIST,,,,,route3,,,,,Stat_Supplier3:*sum#~*req.LoadReq,35,,, cgrates.org ROUTE_LOAD_DIST route3 Stat_Supplier3:*sum#~*req.LoadReq 35

View File

@@ -1,5 +1,5 @@
#Tenant,ID,FilterIDs,ActivationInterval,Sorting,SortingParameters,RouteID,RouteFilterIDs,RouteAccountIDs,RouteRatingPlanIDs,RouteResourceIDs,RouteStatIDs,RouteWeight,RouteBlocker,RouteParameters,Weight
cgrates.org,ROUTE_1,FLTR_ACNT_dan;FLTR_DST_DE,2017-07-29T15:00:00Z,*lc,,route1,FLTR_ACNT_dan,,RPL_1,ResGroup1,Stat1,10,false,SortingParameter1,10
cgrates.org,ROUTE_WEIGHT_1,FLTR_DST_DE;FLTR_ACNT_1007,2017-11-27T00:00:00Z,*weight,,route1,,,,,,10,,,10
cgrates.org,ROUTE_WEIGHT_1,FLTR_DST_DE,,,,route2,,,,,,20,,,
cgrates.org,ROUTE_WEIGHT_1,FLTR_ACNT_1007,,,,route3,FLTR_ACNT_dan,,,,,15,,,
#Tenant,ID,FilterIDs,ActivationInterval,Sorting,SortingParameters,RouteID,RouteFilterIDs,RouteAccountIDs,RouteRatingPlanIDs,RouteRateProfileIDs,RouteResourceIDs,RouteStatIDs,RouteWeight,RouteBlocker,RouteParameters,Weight
cgrates.org,ROUTE_1,FLTR_ACNT_dan;FLTR_DST_DE,2017-07-29T15:00:00Z,*lc,,route1,FLTR_ACNT_dan,,RPL_1,,ResGroup1,Stat1,10,false,SortingParameter1,10
cgrates.org,ROUTE_WEIGHT_1,FLTR_DST_DE;FLTR_ACNT_1007,2017-11-27T00:00:00Z,*weight,,route1,,,,,,,10,,,10
cgrates.org,ROUTE_WEIGHT_1,FLTR_DST_DE,,,,route2,,,,,,,20,,,
cgrates.org,ROUTE_WEIGHT_1,FLTR_ACNT_1007,,,,route3,FLTR_ACNT_dan,,,,,,15,,,
1 #Tenant ID FilterIDs ActivationInterval Sorting SortingParameters RouteID RouteFilterIDs RouteAccountIDs RouteRatingPlanIDs RouteRateProfileIDs RouteResourceIDs RouteStatIDs RouteWeight RouteBlocker RouteParameters Weight
2 cgrates.org ROUTE_1 FLTR_ACNT_dan;FLTR_DST_DE 2017-07-29T15:00:00Z *lc route1 FLTR_ACNT_dan RPL_1 ResGroup1 Stat1 10 false SortingParameter1 10
3 cgrates.org ROUTE_WEIGHT_1 FLTR_DST_DE;FLTR_ACNT_1007 2017-11-27T00:00:00Z *weight route1 10 10
4 cgrates.org ROUTE_WEIGHT_1 FLTR_DST_DE route2 20
5 cgrates.org ROUTE_WEIGHT_1 FLTR_ACNT_1007 route3 FLTR_ACNT_dan 15

View File

@@ -1,7 +1,7 @@
#Tenant,ID,FilterIDs,ActivationInterval,Sorting,SortingParameters,RouteID,RouteFilterIDs,RouteAccountIDs,RouteRatingPlanIDs,RouteResourceIDs,RouteStatIDs,RouteWeight,RouteBlocker,RouteParameters,Weight
cgrates.org,ROUTE_ACNT_1001,*string:~*req.Account:1001,2017-11-27T00:00:00Z,*weight,,route1,,1001,RP_10CNT,,,20,,cgrates.org,20
cgrates.org,ROUTE_ACNT_1001,,,,,route2,,1001,RP_20CNT,,,10,,cgrates.net,10
cgrates.org,ROUTE_ACNT_1001,,,,,route3,,1001,RP_1CNT,,,5,,cgrates.com,5
cgrates.org,ROUTE_ACNT_1002,*string:~*req.Account:1002,2017-11-27T00:00:00Z,*weight,,route1,,1002,RP_10CNT,,,20,,1003@192.168.56.203,20
cgrates.org,ROUTE_ACNT_1002,,,,,route2,,1002,RP_20CNT,,,10,,1004@192.168.57.203,10
cgrates.org,ROUTE_ACNT_1002,,,,,route3,,1002,RP_1CNT,,,5,,1005@192.168.58.203,5
#Tenant,ID,FilterIDs,ActivationInterval,Sorting,SortingParameters,RouteID,RouteFilterIDs,RouteAccountIDs,RouteRatingPlanIDs,RouteRateProfileIDs,RouteResourceIDs,RouteStatIDs,RouteWeight,RouteBlocker,RouteParameters,Weight
cgrates.org,ROUTE_ACNT_1001,*string:~*req.Account:1001,2017-11-27T00:00:00Z,*weight,,route1,,1001,RP_10CNT,,,,20,,cgrates.org,20
cgrates.org,ROUTE_ACNT_1001,,,,,route2,,1001,RP_20CNT,,,,10,,cgrates.net,10
cgrates.org,ROUTE_ACNT_1001,,,,,route3,,1001,RP_1CNT,,,,5,,cgrates.com,5
cgrates.org,ROUTE_ACNT_1002,*string:~*req.Account:1002,2017-11-27T00:00:00Z,*weight,,route1,,1002,RP_10CNT,,,,20,,1003@192.168.56.203,20
cgrates.org,ROUTE_ACNT_1002,,,,,route2,,1002,RP_20CNT,,,,10,,1004@192.168.57.203,10
cgrates.org,ROUTE_ACNT_1002,,,,,route3,,1002,RP_1CNT,,,,5,,1005@192.168.58.203,5
1 #Tenant ID FilterIDs ActivationInterval Sorting SortingParameters RouteID RouteFilterIDs RouteAccountIDs RouteRatingPlanIDs RouteRateProfileIDs RouteResourceIDs RouteStatIDs RouteWeight RouteBlocker RouteParameters Weight
2 cgrates.org ROUTE_ACNT_1001 *string:~*req.Account:1001 2017-11-27T00:00:00Z *weight route1 1001 RP_10CNT 20 cgrates.org 20
3 cgrates.org ROUTE_ACNT_1001 route2 1001 RP_20CNT 10 cgrates.net 10
4 cgrates.org ROUTE_ACNT_1001 route3 1001 RP_1CNT 5 cgrates.com 5
5 cgrates.org ROUTE_ACNT_1002 *string:~*req.Account:1002 2017-11-27T00:00:00Z *weight route1 1002 RP_10CNT 20 1003@192.168.56.203 20
6 cgrates.org ROUTE_ACNT_1002 route2 1002 RP_20CNT 10 1004@192.168.57.203 10
7 cgrates.org ROUTE_ACNT_1002 route3 1002 RP_1CNT 5 1005@192.168.58.203 5

View File

@@ -1,8 +1,8 @@
#Tenant,ID,FilterIDs,ActivationInterval,Sorting,SortingParameters,RouteID,RouteFilterIDs,RouteAccountIDs,RouteRatingPlanIDs,RouteResourceIDs,RouteStatIDs,RouteWeight,RouteBlocker,RouteParameters,Weight
cgrates.org,ROUTE_ACNT_1001,FLTR_ACNT_1001,2017-11-27T00:00:00Z,*weight,,route1,,,,,,10,,,10
cgrates.org,ROUTE_ACNT_1001,,,,,route2,,,,,,20,,,20
cgrates.org,ROUTE_ACNT_1002,FLTR_ACNT_1002,2017-11-27T00:00:00Z,*lc,,route1,,,RP_1002_LOW,,,10,false,,10
cgrates.org,ROUTE_ACNT_1002,,,,,route2,,,RP_1002,,,20,,,
cgrates.org,ROUTE_ACNT_1003,FLTR_ACNT_1003,2017-11-27T00:00:00Z,*qos,*tcc;*tcd,route1,,,,,Stats2,10,false,,10
cgrates.org,ROUTE_ACNT_1003,,,,,route2,,,,,Stats2_1,20,,,
#Tenant,ID,FilterIDs,ActivationInterval,Sorting,SortingParameters,RouteID,RouteFilterIDs,RouteAccountIDs,RouteRatingPlanIDs,RouteRateProfileIDs,RouteResourceIDs,RouteStatIDs,RouteWeight,RouteBlocker,RouteParameters,Weight
cgrates.org,ROUTE_ACNT_1001,FLTR_ACNT_1001,2017-11-27T00:00:00Z,*weight,,route1,,,,,,,10,,,10
cgrates.org,ROUTE_ACNT_1001,,,,,route2,,,,,,,20,,,20
cgrates.org,ROUTE_ACNT_1002,FLTR_ACNT_1002,2017-11-27T00:00:00Z,*lc,,route1,,,RP_1002_LOW,,,,10,false,,10
cgrates.org,ROUTE_ACNT_1002,,,,,route2,,,RP_1002,,,,20,,,
cgrates.org,ROUTE_ACNT_1003,FLTR_ACNT_1003,2017-11-27T00:00:00Z,*qos,*tcc;*tcd,route1,,,,,,Stats2,10,false,,10
cgrates.org,ROUTE_ACNT_1003,,,,,route2,,,,,,Stats2_1,20,,,
1 #Tenant ID FilterIDs ActivationInterval Sorting SortingParameters RouteID RouteFilterIDs RouteAccountIDs RouteRatingPlanIDs RouteRateProfileIDs RouteResourceIDs RouteStatIDs RouteWeight RouteBlocker RouteParameters Weight
2 cgrates.org ROUTE_ACNT_1001 FLTR_ACNT_1001 2017-11-27T00:00:00Z *weight route1 10 10
3 cgrates.org ROUTE_ACNT_1001 route2 20 20
4 cgrates.org ROUTE_ACNT_1002 FLTR_ACNT_1002 2017-11-27T00:00:00Z *lc route1 RP_1002_LOW 10 false 10
5 cgrates.org ROUTE_ACNT_1002 route2 RP_1002 20
6 cgrates.org ROUTE_ACNT_1003 FLTR_ACNT_1003 2017-11-27T00:00:00Z *qos *tcc;*tcd route1 Stats2 10 false 10
7 cgrates.org ROUTE_ACNT_1003 route2 Stats2_1 20
8

View File

@@ -41,11 +41,11 @@ func (hcs *HightCostSorter) SortRoutes(prflID string, routes []*Route,
Sorting: hcs.sorting,
SortedRoutes: make([]*SortedRoute, 0)}
for _, route := range routes {
if len(route.RatingPlanIDs) == 0 && len(route.AccountIDs) == 0 {
if len(route.RatingPlanIDs) == 0 && len(route.AccountIDs) == 0 && len(route.RateProfileIDs) == 0 {
utils.Logger.Warning(
fmt.Sprintf("<%s> supplier: <%s> - empty RatingPlanIDs or AccountIDs",
fmt.Sprintf("<%s> supplier: <%s> - empty RatingPlanIDs or AccountIDs or RateProfileIDs",
utils.RouteS, route.ID))
return nil, utils.NewErrMandatoryIeMissing("RatingPlanIDs or AccountIDs")
return nil, utils.NewErrMandatoryIeMissing("RatingPlanIDs or AccountIDs or RateProfileIDs")
}
if srtSpl, pass, err := hcs.rS.populateSortingData(ev, route, extraOpts); err != nil {
return nil, err

View File

@@ -41,11 +41,11 @@ func (lcs *LeastCostSorter) SortRoutes(prflID string, routes []*Route,
Sorting: lcs.sorting,
SortedRoutes: make([]*SortedRoute, 0)}
for _, s := range routes {
if len(s.RatingPlanIDs) == 0 && len(s.AccountIDs) == 0 {
if len(s.RatingPlanIDs) == 0 && len(s.AccountIDs) == 0 && len(s.RateProfileIDs) == 0 {
utils.Logger.Warning(
fmt.Sprintf("<%s> supplier: <%s> - empty RatingPlanIDs or AccountIDs",
fmt.Sprintf("<%s> supplier: <%s> - empty RatingPlanIDs or AccountIDs or RateProfileIDs",
utils.RouteS, s.ID))
return nil, utils.NewErrMandatoryIeMissing("RatingPlanIDs or AccountIDs")
return nil, utils.NewErrMandatoryIeMissing("RatingPlanIDs or AccountIDs or RateProfileIDs")
}
if srtSpl, pass, err := lcs.rS.populateSortingData(ev, s, extraOpts); err != nil {
return nil, err

View File

@@ -209,7 +209,7 @@ func (rpS *RouteService) matchingRouteProfilesForEvent(tnt string, ev *utils.CGR
// costForEvent will compute cost out of accounts and rating plans for event
// returns map[string]interface{} with cost and relevant matching information inside
func (rpS *RouteService) costForEvent(ev *utils.CGREvent,
acntIDs, rpIDs []string) (costData map[string]interface{}, err error) {
acntIDs, rpIDs, rtPrfIDs []string) (costData map[string]interface{}, err error) {
costData = make(map[string]interface{})
if err = ev.CheckMandatoryFields([]string{utils.Account,
utils.Destination, utils.SetupTime}); err != nil {
@@ -277,10 +277,11 @@ func (rpS *RouteService) costForEvent(ev *utils.CGREvent,
}
if accountMaxUsage == 0 || accountMaxUsage < initialUsage {
var rateRply *RateProfileCost
if len(rpS.cgrcfg.RouteSCfg().RateSConns) != 0 {
var rateRply RateProfileCost
if len(rpS.cgrcfg.RouteSCfg().RateSConns) != 0 && len(rtPrfIDs) != 0 {
if err := rpS.connMgr.Call(rpS.cgrcfg.RouteSCfg().RateSConns, nil, utils.RateSv1CostForEvent,
&utils.ArgsCostForEvent{
RateProfileIDs: rtPrfIDs,
CGREventWithOpts: &utils.CGREventWithOpts{
Opts: map[string]interface{}{ // add the setup time and usage in opts
utils.OptsRatesStartTime: sTime,
@@ -419,8 +420,8 @@ func (rpS *RouteService) populateSortingData(ev *utils.CGREvent, route *Route,
RouteParameters: route.RouteParameters,
}
//calculate costData if we have fields
if len(route.AccountIDs) != 0 || len(route.RatingPlanIDs) != 0 {
costData, err := rpS.costForEvent(ev, route.AccountIDs, route.RatingPlanIDs)
if len(route.AccountIDs) != 0 || len(route.RatingPlanIDs) != 0 || len(route.RateProfileIDs) != 0 {
costData, err := rpS.costForEvent(ev, route.AccountIDs, route.RatingPlanIDs, route.RateProfileIDs)
if err != nil {
if extraOpts.ignoreErrors {
utils.Logger.Warning(

View File

@@ -946,6 +946,9 @@ func (iDB *InternalDB) GetRateProfileDrv(tenant, id string) (rpp *RateProfile, e
}
func (iDB *InternalDB) SetRateProfileDrv(rpp *RateProfile) (err error) {
if err = rpp.Compile(); err != nil {
return
}
Cache.SetWithoutReplicate(utils.CacheRateProfiles, rpp.TenantID(), rpp, nil,
cacheCommit(utils.NonTransactional), utils.NonTransactional)
return

View File

@@ -1411,10 +1411,14 @@ func TestLoaderProcessRateProfile(t *testing.T) {
},
},
}
if rcv, err := ldr.dm.GetRateProfile("cgrates.org", "RP1",
true, false, utils.NonTransactional); err != nil {
rcv, err := ldr.dm.GetRateProfile("cgrates.org", "RP1",
true, false, utils.NonTransactional)
if err != nil {
t.Error(err)
} else if !reflect.DeepEqual(rcv, eRatePrf) {
}
rcv.Compile()
eRatePrf.Compile()
if !reflect.DeepEqual(rcv, eRatePrf) {
t.Errorf("expecting: %+v,\n received: %+v", utils.ToJSON(eRatePrf), utils.ToJSON(rcv))
}
@@ -1572,10 +1576,14 @@ cgrates.org,RP1,,,,,,,,,,RT_CHRISTMAS,,* * 24 12 *,30,false,0s,0.06,1m,1s
},
},
}
if rcv, err := ldr.dm.GetRateProfile("cgrates.org", "RP1",
true, false, utils.NonTransactional); err != nil {
rcv, err := ldr.dm.GetRateProfile("cgrates.org", "RP1",
true, false, utils.NonTransactional)
if err != nil {
t.Error(err)
} else if !reflect.DeepEqual(rcv, eRatePrf) {
}
rcv.Compile()
eRatePrf.Compile()
if !reflect.DeepEqual(rcv, eRatePrf) {
t.Errorf("expecting: %+v,\n received: %+v", utils.ToJSON(eRatePrf), utils.ToJSON(rcv))
}
@@ -1653,10 +1661,14 @@ cgrates.org,RP1,,,,,,,,,,RT_CHRISTMAS,,* * 24 12 *,30,false,0s,0.06,1m,1s
},
},
}
if rcv, err := ldr.dm.GetRateProfile("cgrates.org", "RP1",
true, false, utils.NonTransactional); err != nil {
rcv, err = ldr.dm.GetRateProfile("cgrates.org", "RP1",
true, false, utils.NonTransactional)
if err != nil {
t.Error(err)
} else if !reflect.DeepEqual(rcv, eRatePrf) {
}
rcv.Compile()
eRatePrf.Compile()
if !reflect.DeepEqual(rcv, eRatePrf) {
t.Errorf("expecting: %+v,\n received: %+v", utils.ToJSON(eRatePrf), utils.ToJSON(rcv))
}
@@ -1886,10 +1898,14 @@ cgrates.org,RP1,
},
},
}
if rcv, err := ldr.dm.GetRateProfile("cgrates.org", "RP1",
true, false, utils.NonTransactional); err != nil {
rcv, err := ldr.dm.GetRateProfile("cgrates.org", "RP1",
true, false, utils.NonTransactional)
if err != nil {
t.Error(err)
} else if !reflect.DeepEqual(rcv, eRatePrf) {
}
rcv.Compile()
eRatePrf.Compile()
if !reflect.DeepEqual(rcv, eRatePrf) {
t.Errorf("expecting: %+v,\n received: %+v", utils.ToJSON(eRatePrf), utils.ToJSON(rcv))
}
@@ -1942,10 +1958,14 @@ cgrates.org,RP1,
},
},
}
if rcv, err := ldr.dm.GetRateProfile("cgrates.org", "RP2",
true, false, utils.NonTransactional); err != nil {
rcv, err = ldr.dm.GetRateProfile("cgrates.org", "RP2",
true, false, utils.NonTransactional)
if err != nil {
t.Error(err)
} else if !reflect.DeepEqual(rcv, eRatePrf2) {
}
rcv.Compile()
eRatePrf2.Compile()
if !reflect.DeepEqual(rcv, eRatePrf2) {
t.Errorf("expecting: %+v,\n received: %+v", utils.ToJSON(eRatePrf2), utils.ToJSON(rcv))
}
@@ -1962,10 +1982,14 @@ cgrates.org,RP1,
MaxCostStrategy: "*free",
Rates: map[string]*engine.Rate{},
}
if rcv, err := ldr.dm.GetRateProfile("cgrates.org", "RP1",
true, false, utils.NonTransactional); err != nil {
rcv, err = ldr.dm.GetRateProfile("cgrates.org", "RP1",
true, false, utils.NonTransactional)
if err != nil {
t.Error(err)
} else if !reflect.DeepEqual(rcv, eRatePrf3) {
}
rcv.Compile()
eRatePrf3.Compile()
if !reflect.DeepEqual(rcv, eRatePrf3) {
t.Errorf("expecting: %+v,\n received: %+v", utils.ToJSON(eRatePrf3), utils.ToJSON(rcv))
}
}