diff --git a/apier/v1/apier.go b/apier/v1/apier.go index 8466bcc1b..0592de918 100644 --- a/apier/v1/apier.go +++ b/apier/v1/apier.go @@ -1585,7 +1585,7 @@ func (apierSv1 *APIerSv1) ExportToFolder(ctx *context.Context, arg *utils.ArgExp if len(arg.Items) == 0 { arg.Items = []string{utils.MetaAttributes, utils.MetaChargers, utils.MetaDispatchers, utils.MetaDispatcherHosts, utils.MetaFilters, utils.MetaResources, utils.MetaStats, - utils.MetaRoutes, utils.MetaThresholds, utils.MetaSags, utils.MetaSars} + utils.MetaRoutes, utils.MetaThresholds, utils.MetaSags, utils.MetaTrends} } if _, err := os.Stat(arg.Path); os.IsNotExist(err) { os.Mkdir(arg.Path, os.ModeDir) @@ -1890,8 +1890,8 @@ func (apierSv1 *APIerSv1) ExportToFolder(ctx *context.Context, arg *utils.ArgExp csvWriter.Write(record) } csvWriter.Flush() - case utils.MetaSars: - prfx := utils.SarsProfilePrefix + case utils.MetaTrends: + prfx := utils.TrendsProfilePrefix keys, err := apierSv1.DataManager.DataDB().GetKeysForPrefix(prfx) if err != nil { return err @@ -1899,7 +1899,7 @@ func (apierSv1 *APIerSv1) ExportToFolder(ctx *context.Context, arg *utils.ArgExp if len(keys) == 0 { continue } - f, err := os.Create(path.Join(arg.Path, utils.SarsCsv)) + f, err := os.Create(path.Join(arg.Path, utils.TrendsCsv)) if err != nil { return err } @@ -1907,16 +1907,16 @@ func (apierSv1 *APIerSv1) ExportToFolder(ctx *context.Context, arg *utils.ArgExp csvWriter := csv.NewWriter(f) csvWriter.Comma = utils.CSVSep - if err := csvWriter.Write(engine.SarsMdls{}.CSVHeader()); err != nil { + if err := csvWriter.Write(engine.TrendsMdls{}.CSVHeader()); err != nil { return err } for _, key := range keys { tntID := strings.SplitN(key[len(prfx):], utils.InInFieldSep, 2) - srsPrf, err := apierSv1.DataManager.GetSarProfile(tntID[0], tntID[1]) + srsPrf, err := apierSv1.DataManager.GetTrendProfile(tntID[0], tntID[1]) if err != nil { return err } - mdl := engine.APItoModelSars(engine.SarProfileToAPI(srsPrf)) + mdl := engine.APItoModelTrends(engine.TrendProfileToAPI(srsPrf)) record, err := engine.CsvDump(mdl) if err != nil { return err diff --git a/apier/v1/replicator.go b/apier/v1/replicator.go index e8aba3e00..27614d408 100644 --- a/apier/v1/replicator.go +++ b/apier/v1/replicator.go @@ -147,10 +147,10 @@ func (rplSv1 *ReplicatorSv1) GetSagProfile(ctx *context.Context, tntID *utils.Te return nil } -// GetSarProfile is the remote method coresponding to the dataDb driver method -func (rplSv1 *ReplicatorSv1) GetSarProfile(ctx *context.Context, tntID *utils.TenantIDWithAPIOpts, reply *engine.SarProfile) error { - engine.UpdateReplicationFilters(utils.SarsProfilePrefix, tntID.TenantID.TenantID(), utils.IfaceAsString(tntID.APIOpts[utils.RemoteHostOpt])) - rcv, err := rplSv1.dm.DataDB().GetSarProfileDrv(tntID.Tenant, tntID.ID) +// GetTrendProfile is the remote method coresponding to the dataDb driver method +func (rplSv1 *ReplicatorSv1) GetTrendProfile(ctx *context.Context, tntID *utils.TenantIDWithAPIOpts, reply *engine.TrendProfile) error { + engine.UpdateReplicationFilters(utils.TrendsProfilePrefix, tntID.TenantID.TenantID(), utils.IfaceAsString(tntID.APIOpts[utils.RemoteHostOpt])) + rcv, err := rplSv1.dm.DataDB().GetTrendProfileDrv(tntID.Tenant, tntID.ID) if err != nil { return err } @@ -456,9 +456,9 @@ func (rplSv1 *ReplicatorSv1) SetSagProfile(ctx *context.Context, sg *engine.SagP return } -// SetSarProfile is the replication method coresponding to the dataDb driver method -func (rplSv1 *ReplicatorSv1) SetSarProfile(ctx *context.Context, sg *engine.SarProfileWithAPIOpts, reply *string) (err error) { - if err = rplSv1.dm.DataDB().SetSarProfileDrv(sg.SarProfile); err != nil { +// SetTrendProfile is the replication method coresponding to the dataDb driver method +func (rplSv1 *ReplicatorSv1) SetTrendProfile(ctx *context.Context, sg *engine.TrendProfileWithAPIOpts, reply *string) (err error) { + if err = rplSv1.dm.DataDB().SetTrendProfileDrv(sg.TrendProfile); err != nil { return } *reply = utils.OK @@ -880,9 +880,9 @@ func (rplSv1 *ReplicatorSv1) RemoveSagProfile(ctx *context.Context, args *utils. return } -// RemoveSarProfile is the replication method coresponding to the dataDb driver method -func (rplSv1 *ReplicatorSv1) RemoveSarProfile(ctx *context.Context, args *utils.TenantIDWithAPIOpts, reply *string) (err error) { - if err = rplSv1.dm.DataDB().RemSarProfileDrv(args.Tenant, args.ID); err != nil { +// RemoveTrendProfile is the replication method coresponding to the dataDb driver method +func (rplSv1 *ReplicatorSv1) RemoveTrendProfile(ctx *context.Context, args *utils.TenantIDWithAPIOpts, reply *string) (err error) { + if err = rplSv1.dm.DataDB().RemTrendProfileDrv(args.Tenant, args.ID); err != nil { return } diff --git a/apier/v1/sags.go b/apier/v1/sags.go index c3dfbe205..2ce73253a 100644 --- a/apier/v1/sags.go +++ b/apier/v1/sags.go @@ -19,6 +19,7 @@ along with this program. If not, see package v1 import ( + "fmt" "time" "github.com/cgrates/birpc/context" @@ -26,17 +27,7 @@ import ( "github.com/cgrates/cgrates/utils" ) -func NewSagSv1() *SagSv1 { - return &SagSv1{} -} - -type SagSv1 struct{} - -func (sa *SagSv1) Ping(ctx *context.Context, ign *utils.CGREvent, reply *string) error { - *reply = utils.Pong - return nil -} - +// GetSagProfile returns a StatAggregator profile func (apierSv1 *APIerSv1) GetSagProfile(ctx *context.Context, arg *utils.TenantID, reply *engine.SagProfile) (err error) { if missing := utils.MissingStructFields(arg, []string{utils.ID}); len(missing) != 0 { return utils.NewErrMandatoryIeMissing(missing...) @@ -53,6 +44,7 @@ func (apierSv1 *APIerSv1) GetSagProfile(ctx *context.Context, arg *utils.TenantI return } +// GetSagProfileIDs returns list of sagProfile IDs registered for a tenant func (apierSv1 *APIerSv1) GetSagProfileIDs(ctx *context.Context, args *utils.PaginatorWithTenant, sgPrfIDs *[]string) (err error) { tnt := args.Tenant if tnt == utils.EmptyString { @@ -74,6 +66,7 @@ func (apierSv1 *APIerSv1) GetSagProfileIDs(ctx *context.Context, args *utils.Pag return } +// SetSagProfile alters/creates a SagProfile func (apierSv1 *APIerSv1) SetSagProfile(ctx *context.Context, arg *engine.SagProfileWithAPIOpts, reply *string) error { if missing := utils.MissingStructFields(arg.SagProfile, []string{utils.ID}); len(missing) != 0 { return utils.NewErrMandatoryIeMissing(missing...) @@ -84,18 +77,26 @@ func (apierSv1 *APIerSv1) SetSagProfile(ctx *context.Context, arg *engine.SagPro if err := apierSv1.DataManager.SetSagProfile(arg.SagProfile); err != nil { return utils.APIErrorHandler(err) } - if err := apierSv1.CallCache(utils.IfaceAsString(arg.APIOpts[utils.CacheOpt]), arg.Tenant, utils.CacheSagProfiles, - arg.TenantID(), utils.EmptyString, nil, nil, arg.APIOpts); err != nil { - return utils.APIErrorHandler(err) - } + //generate a loadID for CacheSagProfiles and store it in database loadID := time.Now().UnixNano() if err := apierSv1.DataManager.SetLoadIDs(map[string]int64{utils.CacheSagProfiles: loadID}); err != nil { return utils.APIErrorHandler(err) } + // delay if needed before cache call + if apierSv1.Config.GeneralCfg().CachingDelay != 0 { + utils.Logger.Info(fmt.Sprintf(" Delaying cache call for %v", apierSv1.Config.GeneralCfg().CachingDelay)) + time.Sleep(apierSv1.Config.GeneralCfg().CachingDelay) + } + //handle caching for SagProfile + if err := apierSv1.CallCache(utils.IfaceAsString(arg.APIOpts[utils.CacheOpt]), arg.Tenant, utils.CacheSagProfiles, + arg.TenantID(), utils.EmptyString, nil, nil, arg.APIOpts); err != nil { + return utils.APIErrorHandler(err) + } *reply = utils.OK return nil } +// RemoveSagProfile remove a specific sag configuration func (apierSv1 *APIerSv1) RemoveSagProfile(ctx *context.Context, args *utils.TenantIDWithAPIOpts, reply *string) error { if missing := utils.MissingStructFields(args, []string{utils.ID}); len(missing) != 0 { //Params missing return utils.NewErrMandatoryIeMissing(missing...) @@ -107,12 +108,17 @@ func (apierSv1 *APIerSv1) RemoveSagProfile(ctx *context.Context, args *utils.Ten if err := apierSv1.DataManager.RemoveSagProfile(tnt, args.ID); err != nil { return utils.APIErrorHandler(err) } - + // delay if needed before cache call + if apierSv1.Config.GeneralCfg().CachingDelay != 0 { + utils.Logger.Info(fmt.Sprintf(" Delaying cache call for %v", apierSv1.Config.GeneralCfg().CachingDelay)) + time.Sleep(apierSv1.Config.GeneralCfg().CachingDelay) + } + //handle caching for SagProfile if err := apierSv1.CallCache(utils.IfaceAsString(args.APIOpts[utils.CacheOpt]), tnt, utils.CacheSagProfiles, utils.ConcatenatedKey(tnt, args.ID), utils.EmptyString, nil, nil, args.APIOpts); err != nil { return utils.APIErrorHandler(err) } - + //generate a loadID for CacheSagProfiles and store it in database loadID := time.Now().UnixNano() if err := apierSv1.DataManager.SetLoadIDs(map[string]int64{utils.CacheSagProfiles: loadID}); err != nil { return utils.APIErrorHandler(err) @@ -120,3 +126,15 @@ func (apierSv1 *APIerSv1) RemoveSagProfile(ctx *context.Context, args *utils.Ten *reply = utils.OK return nil } + +// NewSagSv1 initializes SagSV1 +func NewSagSv1() *SagSv1 { + return &SagSv1{} +} + +type SagSv1 struct{} + +func (sa *SagSv1) Ping(ctx *context.Context, ign *utils.CGREvent, reply *string) error { + *reply = utils.Pong + return nil +} diff --git a/apier/v1/sars_it_test.go b/apier/v1/sars_it_test.go deleted file mode 100644 index 26a5aef32..000000000 --- a/apier/v1/sars_it_test.go +++ /dev/null @@ -1,209 +0,0 @@ -//go:build integration -// +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 -*/ -package v1 - -import ( - "path" - "testing" - "time" - - "github.com/cgrates/birpc" - "github.com/cgrates/birpc/context" - "github.com/cgrates/cgrates/config" - "github.com/cgrates/cgrates/engine" - "github.com/cgrates/cgrates/utils" - "github.com/google/go-cmp/cmp" - "github.com/google/go-cmp/cmp/cmpopts" -) - -var ( - sarCfgPath string - sarCfg *config.CGRConfig - sarRPC *birpc.Client - sarProfile *engine.SarProfileWithAPIOpts - sarConfigDIR string - - sTestsSar = []func(t *testing.T){ - testSarSInitCfg, - testSarSInitDataDb, - testSarSResetStorDb, - testSarSStartEngine, - testSarSRPCConn, - testSarSLoadAdd, - testSarSetSarProfile, - testSarSGetSarProfileIDs, - testSarSUpdateSarProfile, - testSarSRemSarProfile, - testSarSKillEngine, - } -) - -func TestSarSIT(t *testing.T) { - switch *utils.DBType { - case utils.MetaInternal: - sarConfigDIR = "tutinternal" - case utils.MetaMySQL: - sarConfigDIR = "tutmysql" - case utils.MetaMongo: - sarConfigDIR = "tutmongo" - case utils.MetaPostgres: - t.SkipNow() - default: - t.Fatal("Unknown Database type") - } - for _, stest := range sTestsSar { - t.Run(sarConfigDIR, stest) - } -} - -func testSarSInitCfg(t *testing.T) { - var err error - sarCfgPath = path.Join(*utils.DataDir, "conf", "samples", sarConfigDIR) - sarCfg, err = config.NewCGRConfigFromPath(sarCfgPath) - if err != nil { - t.Error(err) - } -} - -func testSarSInitDataDb(t *testing.T) { - if err := engine.InitDataDb(sarCfg); err != nil { - t.Fatal(err) - } -} - -// Wipe out the cdr database -func testSarSResetStorDb(t *testing.T) { - if err := engine.InitStorDb(sarCfg); err != nil { - t.Fatal(err) - } -} - -// Start CGR Engine -func testSarSStartEngine(t *testing.T) { - if _, err := engine.StopStartEngine(sarCfgPath, *utils.WaitRater); err != nil { - t.Fatal(err) - } -} - -// Connect rpc client to rater -func testSarSRPCConn(t *testing.T) { - var err error - sarRPC, err = newRPCClient(sarCfg.ListenCfg()) // We connect over JSON so we can also troubleshoot if needed - if err != nil { - t.Fatal(err) - } -} -func testSarSLoadAdd(t *testing.T) { - sarProfile := &engine.SarProfileWithAPIOpts{ - SarProfile: &engine.SarProfile{ - Tenant: "cgrates.org", - ID: "SR_AVG", - QueryInterval: 2 * time.Minute, - StatID: "Stat1", - Trend: "*average", - }, - } - - var result string - if err := sarRPC.Call(context.Background(), utils.APIerSv1SetSarProfile, sarProfile, &result); err != nil { - t.Error(err) - } else if result != utils.OK { - t.Error("Unexpected reply returned", result) - } - -} - -func testSarSetSarProfile(t *testing.T) { - var ( - reply *engine.SarProfileWithAPIOpts - result string - ) - sarProfile = &engine.SarProfileWithAPIOpts{ - SarProfile: &engine.SarProfile{ - Tenant: "cgrates.org", - ID: "Sar1", - QueryInterval: time.Second * 15, - ThresholdIDs: []string{"THD1", "THD2"}}, - } - if err := sarRPC.Call(context.Background(), utils.APIerSv1GetSarProfile, - &utils.TenantID{Tenant: "cgrates.org", ID: "Sar1"}, &reply); err == nil || - err.Error() != utils.ErrNotFound.Error() { - t.Fatal(err) - } - if err := sarRPC.Call(context.Background(), utils.APIerSv1SetSarProfile, sarProfile, &result); err != nil { - t.Error(err) - } else if result != utils.OK { - t.Errorf("Expected: %v,Received: %v", utils.OK, result) - } - if err := sarRPC.Call(context.Background(), utils.APIerSv1GetSarProfile, &utils.TenantID{Tenant: "cgrates.org", ID: "Sar1"}, &reply); err != nil { - t.Error(err) - } else if diff := cmp.Diff(sarProfile, reply, cmpopts.SortSlices(func(a, b string) bool { return a < b })); diff != utils.EmptyString { - t.Errorf("Unnexpected profile (-expected +got):\n%s", diff) - } -} -func testSarSGetSarProfileIDs(t *testing.T) { - expected := []string{"Sag1", "SG_Sum"} - var result []string - if err := sarRPC.Call(context.Background(), utils.APIerSv1GetSarProfileIDs, utils.PaginatorWithTenant{}, &result); err != nil { - t.Error(err) - } else if len(expected) != len(result) { - t.Errorf("Expecting : %+v, received: %+v", expected, result) - } -} - -func testSarSUpdateSarProfile(t *testing.T) { - var ( - reply *engine.SarProfileWithAPIOpts - result string - ) - if err := sarRPC.Call(context.Background(), utils.APIerSv1SetSarProfile, sarProfile, &result); err != nil { - t.Error(err) - } - if err := sarRPC.Call(context.Background(), utils.APIerSv1GetSarProfile, &utils.TenantID{Tenant: "cgrates.org", ID: "Sar1"}, &reply); err != nil { - t.Error(err) - } else if diff := cmp.Diff(sarProfile, reply, cmpopts.SortSlices(func(a, b string) bool { return a < b })); diff != utils.EmptyString { - t.Errorf("Unnexpected profile (-expected +got):\n%s", diff) - } -} -func testSarSRemSarProfile(t *testing.T) { - var ( - resp string - reply *engine.SarProfile - ) - if err := sarRPC.Call(context.Background(), utils.APIerSv1RemoveSarProfile, - &utils.TenantID{Tenant: "cgrates.org", ID: "Sar1"}, &resp); err != nil { - t.Error(err) - } else if resp != utils.OK { - t.Error("Unexpected reply returned", resp) - } - - if err := sarRPC.Call(context.Background(), utils.APIerSv1GetSarProfile, - &utils.TenantID{Tenant: "cgrates.org", ID: "Sar1"}, - &reply); err == nil || err.Error() != utils.ErrNotFound.Error() { - t.Error(err) - } -} - -func testSarSKillEngine(t *testing.T) { - if err := engine.KillEngine(*utils.WaitRater); err != nil { - t.Error(err) - } -} diff --git a/apier/v1/tpsags.go b/apier/v1/tpsags.go index 569c72dc8..f2de6f947 100644 --- a/apier/v1/tpsags.go +++ b/apier/v1/tpsags.go @@ -23,7 +23,7 @@ import ( "github.com/cgrates/cgrates/utils" ) -// SetTPSags creates a new stat within a tariff plan +// SetTPSags creates a new stataggregator within a tariff plan func (apierSv1 *APIerSv1) SetTPSag(ctx *context.Context, sag *utils.TPSagsProfile, reply *string) error { if missing := utils.MissingStructFields(sag, []string{utils.TPid, utils.ID}); len(missing) != 0 { return utils.NewErrMandatoryIeMissing(missing...) @@ -38,7 +38,7 @@ func (apierSv1 *APIerSv1) SetTPSag(ctx *context.Context, sag *utils.TPSagsProfil return nil } -// GetTPSag queries specific Stat on Tariff plan +// GetTPSag queries specific Sag on Tariff plan func (apierSv1 *APIerSv1) GetTPSag(ctx *context.Context, sag *utils.TPTntID, reply *utils.TPSagsProfile) error { if missing := utils.MissingStructFields(sag, []string{utils.TPid, utils.ID}); len(missing) != 0 { //Params missing return utils.NewErrMandatoryIeMissing(missing...) @@ -63,7 +63,7 @@ type AttrGetTPSagIds struct { utils.PaginatorWithSearch } -// GetTPSagIDs queries Stat identities on specific tariff plan. +// GetTPSagIDs queries Sag identities on specific tariff plan. func (apierSv1 *APIerSv1) GetTPSagIDs(ctx *context.Context, attrs *AttrGetTPSagIds, reply *[]string) error { if missing := utils.MissingStructFields(&attrs, []string{utils.TPid}); len(missing) != 0 { //Params missing return utils.NewErrMandatoryIeMissing(missing...) @@ -83,7 +83,7 @@ func (apierSv1 *APIerSv1) GetTPSagIDs(ctx *context.Context, attrs *AttrGetTPSagI return nil } -// RemoveTPStat removes specific Stat on Tariff plan +// RemoveTPSag removes specific Sag on Tariff plan func (apierSv1 *APIerSv1) RemoveTPSag(ctx *context.Context, sag *utils.TPTntID, reply *string) error { if missing := utils.MissingStructFields(sag, []string{utils.TPid, utils.ID}); len(missing) != 0 { //Params missing return utils.NewErrMandatoryIeMissing(missing...) diff --git a/apier/v1/tpsars_it_test.go b/apier/v1/tpsars_it_test.go deleted file mode 100644 index 08fc2df9e..000000000 --- a/apier/v1/tpsars_it_test.go +++ /dev/null @@ -1,196 +0,0 @@ -//go:build offline -// +build offline - -/* -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 -*/ - -package v1 - -import ( - "path" - "reflect" - "sort" - "testing" - - "github.com/cgrates/birpc" - "github.com/cgrates/birpc/context" - "github.com/cgrates/birpc/jsonrpc" - "github.com/cgrates/cgrates/config" - "github.com/cgrates/cgrates/engine" - "github.com/cgrates/cgrates/utils" -) - -var ( - tpSarCfgPath string - tpSarCfg *config.CGRConfig - tpSarRPC *birpc.Client - tpSar *utils.TPSarsProfile - tpSarDelay int - tpSarConfigDIR string //run tests for specific configuration -) - -var sTestsTPSars = []func(t *testing.T){ - testTPSarsInitCfg, - testTPSarsResetStorDb, - testTPSarsStartEngine, - testTPSarsRpcConn, - testTPSarsGetTPSarBeforeSet, - testTPSarsSetTPSar, - testTPSarsGetTPSarAfterSet, - testTPSarsUpdateTPSar, - testTPSarsGetTPSarAfterUpdate, - testTPSarsRemoveTPSar, - testTPSarsGetTPSarAfterRemove, - testTPSarsKillEngine, -} - -// Test start here -func TestTPSarIT(t *testing.T) { - switch *utils.DBType { - case utils.MetaInternal: - tpSarConfigDIR = "tutinternal" - case utils.MetaMySQL: - tpSarConfigDIR = "tutmysql" - case utils.MetaMongo: - tpSarConfigDIR = "tutmongo" - case utils.MetaPostgres: - tpSarConfigDIR = "tutpostgres" - default: - t.Fatal("Unknown Database type") - } - for _, stest := range sTestsTPSars { - t.Run(tpSarConfigDIR, stest) - } -} - -func testTPSarsInitCfg(t *testing.T) { - var err error - tpSarCfgPath = path.Join(*utils.DataDir, "conf", "samples", tpSarConfigDIR) - tpSarCfg, err = config.NewCGRConfigFromPath(tpSarCfgPath) - if err != nil { - t.Error(err) - } - tpSarDelay = 1000 -} - -// Wipe out the cdr database -func testTPSarsResetStorDb(t *testing.T) { - if err := engine.InitStorDb(tpSarCfg); err != nil { - t.Fatal(err) - } -} - -// Start CGR Engine -func testTPSarsStartEngine(t *testing.T) { - if _, err := engine.StopStartEngine(tpSarCfgPath, tpSarDelay); err != nil { - t.Fatal(err) - } -} - -// Connect rpc client to rater -func testTPSarsRpcConn(t *testing.T) { - var err error - tpSarRPC, err = jsonrpc.Dial(utils.TCP, tpSarCfg.ListenCfg().RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed - if err != nil { - t.Fatal(err) - } -} - -func testTPSarsGetTPSarBeforeSet(t *testing.T) { - var reply *utils.TPSarsProfile - if err := tpSarRPC.Call(context.Background(), utils.APIerSv1GetTPSag, - &utils.TPTntID{TPid: "TPS1", Tenant: "cgrates.org", ID: "Sar1"}, - &reply); err == nil || err.Error() != utils.ErrNotFound.Error() { - t.Error(err) - } -} - -func testTPSarsSetTPSar(t *testing.T) { - tpSar = &utils.TPSarsProfile{ - Tenant: "cgrates.org", - TPid: "TPS1", - ID: "Sar1", - QueryInterval: "1m", - ThresholdIDs: []string{"ThreshValue", "ThreshValueTwo"}, - } - sort.Strings(tpSar.ThresholdIDs) - var result string - if err := tpSarRPC.Call(context.Background(), utils.APIerSv1SetTPSar, tpSar, &result); err != nil { - t.Error(err) - } else if result != utils.OK { - t.Error("Unexpected reply returned", result) - } -} - -func testTPSarsGetTPSarAfterSet(t *testing.T) { - var respond *utils.TPSarsProfile - if err := tpSarRPC.Call(context.Background(), utils.APIerSv1GetTPSar, - &utils.TPTntID{TPid: "TPS1", Tenant: "cgrates.org", ID: "Sar1"}, &respond); err != nil { - t.Fatal(err) - } - sort.Strings(respond.ThresholdIDs) - if !reflect.DeepEqual(tpSar, respond) { - t.Errorf("Expecting: %+v, received: %+v", tpSar, respond) - } -} - -func testTPSarsUpdateTPSar(t *testing.T) { - var result string - if err := tpSarRPC.Call(context.Background(), utils.APIerSv1SetTPSar, tpSar, &result); err != nil { - t.Error(err) - } else if result != utils.OK { - t.Error("Unexpected reply returned", result) - } -} - -func testTPSarsGetTPSarAfterUpdate(t *testing.T) { - var expectedTPS *utils.TPSarsProfile - if err := tpSarRPC.Call(context.Background(), utils.APIerSv1GetTPSar, - &utils.TPTntID{TPid: "TPS1", Tenant: "cgrates.org", ID: "Sar1"}, &expectedTPS); err != nil { - t.Fatal(err) - } - sort.Strings(expectedTPS.ThresholdIDs) - if !reflect.DeepEqual(tpSar, expectedTPS) { - t.Errorf("Expecting: %+v, received: %+v", tpSar, expectedTPS) - } -} - -func testTPSarsRemoveTPSar(t *testing.T) { - var resp string - if err := tpSarRPC.Call(context.Background(), utils.APIerSv1RemoveTPSar, - &utils.TPTntID{TPid: "TPS1", Tenant: "cgrates.org", ID: "Sar1"}, &resp); err != nil { - t.Error(err) - } else if resp != utils.OK { - t.Error("Unexpected reply returned", resp) - } -} - -func testTPSarsGetTPSarAfterRemove(t *testing.T) { - var respond *utils.TPSarsProfile - if err := tpSarRPC.Call(context.Background(), utils.APIerSv1GetTPSar, - &utils.TPTntID{TPid: "TPS1", Tenant: "cgrates.org", ID: "Sar1"}, - &respond); err == nil || err.Error() != utils.ErrNotFound.Error() { - t.Error(err) - } -} - -func testTPSarsKillEngine(t *testing.T) { - if err := engine.KillEngine(tpSarDelay); err != nil { - t.Error(err) - } -} diff --git a/apier/v1/tpsars.go b/apier/v1/tptrends.go similarity index 53% rename from apier/v1/tpsars.go rename to apier/v1/tptrends.go index d0226d1f9..2d270738d 100644 --- a/apier/v1/tpsars.go +++ b/apier/v1/tptrends.go @@ -23,55 +23,55 @@ import ( "github.com/cgrates/cgrates/utils" ) -// SetTPSags creates a new stat within a tariff plan -func (apierSv1 *APIerSv1) SetTPSar(ctx *context.Context, sar *utils.TPSarsProfile, reply *string) error { - if missing := utils.MissingStructFields(sar, []string{utils.TPid, utils.ID}); len(missing) != 0 { +// SetTPTrends creates a new trend within a tariff plan +func (apierSv1 *APIerSv1) SetTPTrend(ctx *context.Context, trend *utils.TPTrendsProfile, reply *string) error { + if missing := utils.MissingStructFields(trend, []string{utils.TPid, utils.ID}); len(missing) != 0 { return utils.NewErrMandatoryIeMissing(missing...) } - if sar.Tenant == utils.EmptyString { - sar.Tenant = apierSv1.Config.GeneralCfg().DefaultTenant + if trend.Tenant == utils.EmptyString { + trend.Tenant = apierSv1.Config.GeneralCfg().DefaultTenant } - if err := apierSv1.StorDb.SetTPSars([]*utils.TPSarsProfile{sar}); err != nil { + if err := apierSv1.StorDb.SetTPTrends([]*utils.TPTrendsProfile{trend}); err != nil { return utils.APIErrorHandler(err) } *reply = utils.OK return nil } -// GetTPSag queries specific Stat on Tariff plan -func (apierSv1 *APIerSv1) GetTPSar(ctx *context.Context, sar *utils.TPTntID, reply *utils.TPSarsProfile) error { - if missing := utils.MissingStructFields(sar, []string{utils.TPid, utils.ID}); len(missing) != 0 { //Params missing +// GetTPTrend queries specific Trend on Tariff plan +func (apierSv1 *APIerSv1) GetTPTrend(ctx *context.Context, trend *utils.TPTntID, reply *utils.TPTrendsProfile) error { + if missing := utils.MissingStructFields(trend, []string{utils.TPid, utils.ID}); len(missing) != 0 { //Params missing return utils.NewErrMandatoryIeMissing(missing...) } - if sar.Tenant == utils.EmptyString { - sar.Tenant = apierSv1.Config.GeneralCfg().DefaultTenant + if trend.Tenant == utils.EmptyString { + trend.Tenant = apierSv1.Config.GeneralCfg().DefaultTenant } - srs, err := apierSv1.StorDb.GetTPSars(sar.TPid, sar.Tenant, sar.ID) + trs, err := apierSv1.StorDb.GetTPTrends(trend.TPid, trend.Tenant, trend.ID) if err != nil { if err.Error() != utils.ErrNotFound.Error() { err = utils.NewErrServerError(err) } return err } - *reply = *srs[0] + *reply = *trs[0] return nil } -type AttrGetTPSarIds struct { +type AttrGetTPTrendIds struct { TPid string // Tariff plan id Tenant string utils.PaginatorWithSearch } -// GetTPSagIDs queries Stat identities on specific tariff plan. -func (apierSv1 *APIerSv1) GetTPSarIDs(ctx *context.Context, attrs *AttrGetTPSarIds, reply *[]string) error { +// GetTPTrendIDs queries Trend indetities on specific tariff plan. +func (apierSv1 *APIerSv1) GetTPTrendIDs(ctx *context.Context, attrs *AttrGetTPTrendIds, reply *[]string) error { if missing := utils.MissingStructFields(&attrs, []string{utils.TPid}); len(missing) != 0 { //Params missing return utils.NewErrMandatoryIeMissing(missing...) } if attrs.Tenant == utils.EmptyString { attrs.Tenant = apierSv1.Config.GeneralCfg().DefaultTenant } - ids, err := apierSv1.StorDb.GetTpTableIds(attrs.TPid, utils.TBLTPSars, + ids, err := apierSv1.StorDb.GetTpTableIds(attrs.TPid, utils.TBLTPTrends, utils.TPDistinctIds{utils.TenantCfg, utils.IDCfg}, nil, &attrs.PaginatorWithSearch) if err != nil { if err.Error() != utils.ErrNotFound.Error() { @@ -83,16 +83,16 @@ func (apierSv1 *APIerSv1) GetTPSarIDs(ctx *context.Context, attrs *AttrGetTPSarI return nil } -// RemoveTPSar removes specific Sar on Tariff plan -func (apierSv1 *APIerSv1) RemoveTPSar(ctx *context.Context, sar *utils.TPTntID, reply *string) error { - if missing := utils.MissingStructFields(sar, []string{utils.TPid, utils.ID}); len(missing) != 0 { //Params missing +// RemoveTPTrend removes specific Trend on Tariff plan +func (apierSv1 *APIerSv1) RemoveTPTrend(ctx *context.Context, trend *utils.TPTntID, reply *string) error { + if missing := utils.MissingStructFields(trend, []string{utils.TPid, utils.ID}); len(missing) != 0 { //Params missing return utils.NewErrMandatoryIeMissing(missing...) } - if sar.Tenant == utils.EmptyString { - sar.Tenant = apierSv1.Config.GeneralCfg().DefaultTenant + if trend.Tenant == utils.EmptyString { + trend.Tenant = apierSv1.Config.GeneralCfg().DefaultTenant } - if err := apierSv1.StorDb.RemTpData(utils.TBLTPSars, sar.TPid, - map[string]string{utils.TenantCfg: sar.Tenant, utils.IDCfg: sar.ID}); err != nil { + if err := apierSv1.StorDb.RemTpData(utils.TBLTPTrends, trend.TPid, + map[string]string{utils.TenantCfg: trend.Tenant, utils.IDCfg: trend.ID}); err != nil { return utils.NewErrServerError(err) } *reply = utils.OK diff --git a/apier/v1/tptrends_it_test.go b/apier/v1/tptrends_it_test.go new file mode 100644 index 000000000..fc40ead00 --- /dev/null +++ b/apier/v1/tptrends_it_test.go @@ -0,0 +1,196 @@ +//go:build offline +// +build offline + +/* +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 +*/ + +package v1 + +import ( + "path" + "reflect" + "sort" + "testing" + + "github.com/cgrates/birpc" + "github.com/cgrates/birpc/context" + "github.com/cgrates/birpc/jsonrpc" + "github.com/cgrates/cgrates/config" + "github.com/cgrates/cgrates/engine" + "github.com/cgrates/cgrates/utils" +) + +var ( + tpTrendCfgPath string + tpTrendCfg *config.CGRConfig + tpTrendRPC *birpc.Client + tpTrend *utils.TPTrendsProfile + tpTrendDelay int + tpTrendConfigDIR string //run tests for specific configuration +) + +var sTestsTPTrends = []func(t *testing.T){ + testTPTrendsInitCfg, + testTPTrendsResetStorDb, + testTPTrendsStartEngine, + testTPTrendsRpcConn, + testTPTrendsGetTPTrendBeforeSet, + testTPTrendsSetTPTrend, + testTPTrendsGetTPTrendAfterSet, + testTPTrendsUpdateTPTrend, + testTPTrendsGetTPTrendAfterUpdate, + testTPTrendsRemoveTPTrend, + testTPTrendsGetTPTrendAfterRemove, + testTPTrendsKillEngine, +} + +// Test start here +func TestTPTrendIT(t *testing.T) { + switch *utils.DBType { + case utils.MetaInternal: + tpTrendConfigDIR = "tutinternal" + case utils.MetaMySQL: + tpTrendConfigDIR = "tutmysql" + case utils.MetaMongo: + tpTrendConfigDIR = "tutmongo" + case utils.MetaPostgres: + tpTrendConfigDIR = "tutpostgres" + default: + t.Fatal("Unknown Database type") + } + for _, stest := range sTestsTPTrends { + t.Run(tpTrendConfigDIR, stest) + } +} + +func testTPTrendsInitCfg(t *testing.T) { + var err error + tpTrendCfgPath = path.Join(*utils.DataDir, "conf", "samples", tpTrendConfigDIR) + tpTrendCfg, err = config.NewCGRConfigFromPath(tpTrendCfgPath) + if err != nil { + t.Error(err) + } + tpTrendDelay = 1000 +} + +// Wipe out the cdr database +func testTPTrendsResetStorDb(t *testing.T) { + if err := engine.InitStorDb(tpTrendCfg); err != nil { + t.Fatal(err) + } +} + +// Start CGR Engine +func testTPTrendsStartEngine(t *testing.T) { + if _, err := engine.StopStartEngine(tpTrendCfgPath, tpTrendDelay); err != nil { + t.Fatal(err) + } +} + +// Connect rpc client +func testTPTrendsRpcConn(t *testing.T) { + var err error + tpTrendRPC, err = jsonrpc.Dial(utils.TCP, tpTrendCfg.ListenCfg().RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed + if err != nil { + t.Fatal(err) + } +} + +func testTPTrendsGetTPTrendBeforeSet(t *testing.T) { + var reply *utils.TPTrendsProfile + if err := tpTrendRPC.Call(context.Background(), utils.APIerSv1GetTPSag, + &utils.TPTntID{TPid: "TPS1", Tenant: "cgrates.org", ID: "Trend1"}, + &reply); err == nil || err.Error() != utils.ErrNotFound.Error() { + t.Error(err) + } +} + +func testTPTrendsSetTPTrend(t *testing.T) { + tpTrend = &utils.TPTrendsProfile{ + Tenant: "cgrates.org", + TPid: "TPS1", + ID: "Trend1", + QueryInterval: "1m", + ThresholdIDs: []string{"ThreshValue", "ThreshValueTwo"}, + } + sort.Strings(tpTrend.ThresholdIDs) + var result string + if err := tpTrendRPC.Call(context.Background(), utils.APIerSv1SetTPTrend, tpTrend, &result); err != nil { + t.Error(err) + } else if result != utils.OK { + t.Error("Unexpected reply returned", result) + } +} + +func testTPTrendsGetTPTrendAfterSet(t *testing.T) { + var respond *utils.TPTrendsProfile + if err := tpTrendRPC.Call(context.Background(), utils.APIerSv1GetTPTrend, + &utils.TPTntID{TPid: "TPS1", Tenant: "cgrates.org", ID: "Trend1"}, &respond); err != nil { + t.Fatal(err) + } + sort.Strings(respond.ThresholdIDs) + if !reflect.DeepEqual(tpTrend, respond) { + t.Errorf("Expecting: %+v, received: %+v", tpTrend, respond) + } +} + +func testTPTrendsUpdateTPTrend(t *testing.T) { + var result string + if err := tpTrendRPC.Call(context.Background(), utils.APIerSv1SetTPTrend, tpTrend, &result); err != nil { + t.Error(err) + } else if result != utils.OK { + t.Error("Unexpected reply returned", result) + } +} + +func testTPTrendsGetTPTrendAfterUpdate(t *testing.T) { + var expectedTPS *utils.TPTrendsProfile + if err := tpTrendRPC.Call(context.Background(), utils.APIerSv1GetTPTrend, + &utils.TPTntID{TPid: "TPS1", Tenant: "cgrates.org", ID: "Trend1"}, &expectedTPS); err != nil { + t.Fatal(err) + } + sort.Strings(expectedTPS.ThresholdIDs) + if !reflect.DeepEqual(tpTrend, expectedTPS) { + t.Errorf("Expecting: %+v, received: %+v", tpTrend, expectedTPS) + } +} + +func testTPTrendsRemoveTPTrend(t *testing.T) { + var resp string + if err := tpTrendRPC.Call(context.Background(), utils.APIerSv1RemoveTPTrend, + &utils.TPTntID{TPid: "TPS1", Tenant: "cgrates.org", ID: "Trend1"}, &resp); err != nil { + t.Error(err) + } else if resp != utils.OK { + t.Error("Unexpected reply returned", resp) + } +} + +func testTPTrendsGetTPTrendAfterRemove(t *testing.T) { + var respond *utils.TPTrendsProfile + if err := tpTrendRPC.Call(context.Background(), utils.APIerSv1GetTPTrend, + &utils.TPTntID{TPid: "TPS1", Tenant: "cgrates.org", ID: "Trend1"}, + &respond); err == nil || err.Error() != utils.ErrNotFound.Error() { + t.Error(err) + } +} + +func testTPTrendsKillEngine(t *testing.T) { + if err := engine.KillEngine(tpTrendDelay); err != nil { + t.Error(err) + } +} diff --git a/apier/v1/sars.go b/apier/v1/trends.go similarity index 59% rename from apier/v1/sars.go rename to apier/v1/trends.go index 0193bf509..beeb326ef 100644 --- a/apier/v1/sars.go +++ b/apier/v1/trends.go @@ -24,18 +24,8 @@ import ( "github.com/cgrates/cgrates/utils" ) -func NewSarSv1() *SarSv1 { - return &SarSv1{} -} - -type SarSv1 struct{} - -func (sa *SarSv1) Ping(ctx *context.Context, ign *utils.CGREvent, reply *string) error { - *reply = utils.Pong - return nil -} - -func (apierSv1 *APIerSv1) GetSarProfile(ctx *context.Context, arg *utils.TenantID, reply *engine.SarProfile) (err error) { +// GetTrendProfile returns a Trend profile +func (apierSv1 *APIerSv1) GetTrendProfile(ctx *context.Context, arg *utils.TenantID, reply *engine.TrendProfile) (err error) { if missing := utils.MissingStructFields(arg, []string{utils.ID}); len(missing) != 0 { return utils.NewErrMandatoryIeMissing(missing...) } @@ -43,7 +33,7 @@ func (apierSv1 *APIerSv1) GetSarProfile(ctx *context.Context, arg *utils.TenantI if tnt == utils.EmptyString { tnt = apierSv1.Config.GeneralCfg().DefaultTenant } - sg, err := apierSv1.DataManager.GetSarProfile(tnt, arg.ID) + sg, err := apierSv1.DataManager.GetTrendProfile(tnt, arg.ID) if err != nil { return utils.APIErrorHandler(err) } @@ -51,12 +41,13 @@ func (apierSv1 *APIerSv1) GetSarProfile(ctx *context.Context, arg *utils.TenantI return } -func (apierSv1 *APIerSv1) GetSarProfileIDs(ctx *context.Context, args *utils.PaginatorWithTenant, sgPrfIDs *[]string) (err error) { +// GetTrendProfileIDs returns list of trendProfile IDs registered for a tenant +func (apierSv1 *APIerSv1) GetTrendProfileIDs(ctx *context.Context, args *utils.PaginatorWithTenant, trPrfIDs *[]string) (err error) { tnt := args.Tenant if tnt == utils.EmptyString { tnt = apierSv1.Config.GeneralCfg().DefaultTenant } - prfx := utils.SarsProfilePrefix + tnt + utils.ConcatenatedKeySep + prfx := utils.TrendsProfilePrefix + tnt + utils.ConcatenatedKeySep keys, err := apierSv1.DataManager.DataDB().GetKeysForPrefix(prfx) if err != nil { return err @@ -64,29 +55,31 @@ func (apierSv1 *APIerSv1) GetSarProfileIDs(ctx *context.Context, args *utils.Pag if len(keys) == 0 { return utils.ErrNotFound } - sgIDs := make([]string, len(keys)) + trIDs := make([]string, len(keys)) for i, key := range keys { - sgIDs[i] = key[len(prfx):] + trIDs[i] = key[len(prfx):] } - *sgPrfIDs = args.PaginateStringSlice(sgIDs) + *trPrfIDs = args.PaginateStringSlice(trIDs) return } -func (apierSv1 *APIerSv1) SetSarProfile(ctx *context.Context, arg *engine.SarProfileWithAPIOpts, reply *string) error { - if missing := utils.MissingStructFields(arg.SarProfile, []string{utils.ID}); len(missing) != 0 { +// SetTrendProfile alters/creates a TrendProfile +func (apierSv1 *APIerSv1) SetTrendProfile(ctx *context.Context, arg *engine.TrendProfileWithAPIOpts, reply *string) error { + if missing := utils.MissingStructFields(arg.TrendProfile, []string{utils.ID}); len(missing) != 0 { return utils.NewErrMandatoryIeMissing(missing...) } if arg.Tenant == utils.EmptyString { arg.Tenant = apierSv1.Config.GeneralCfg().DefaultTenant } - if err := apierSv1.DataManager.SetSarProfile(arg.SarProfile); err != nil { + if err := apierSv1.DataManager.SetTrendProfile(arg.TrendProfile); err != nil { return utils.APIErrorHandler(err) } *reply = utils.OK return nil } -func (apierSv1 *APIerSv1) RemoveSarProfile(ctx *context.Context, args *utils.TenantIDWithAPIOpts, reply *string) error { +// RemoveTrendProfile remove a specific trend configuration +func (apierSv1 *APIerSv1) RemoveTrendProfile(ctx *context.Context, args *utils.TenantIDWithAPIOpts, reply *string) error { if missing := utils.MissingStructFields(args, []string{utils.ID}); len(missing) != 0 { //Params missing return utils.NewErrMandatoryIeMissing(missing...) } @@ -94,9 +87,21 @@ func (apierSv1 *APIerSv1) RemoveSarProfile(ctx *context.Context, args *utils.Ten if tnt == utils.EmptyString { tnt = apierSv1.Config.GeneralCfg().DefaultTenant } - if err := apierSv1.DataManager.RemoveSagProfile(tnt, args.ID); err != nil { + if err := apierSv1.DataManager.RemoveTrendProfile(tnt, args.ID); err != nil { return utils.APIErrorHandler(err) } *reply = utils.OK return nil } + +// NewTrendSv1 initializes TrendSV1 +func NewTrendSv1() *TrendSv1 { + return &TrendSv1{} +} + +type TrendSv1 struct{} + +func (sa *TrendSv1) Ping(ctx *context.Context, ign *utils.CGREvent, reply *string) error { + *reply = utils.Pong + return nil +} diff --git a/apier/v1/trends_it_test.go b/apier/v1/trends_it_test.go new file mode 100644 index 000000000..bfd111492 --- /dev/null +++ b/apier/v1/trends_it_test.go @@ -0,0 +1,209 @@ +//go:build integration +// +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 +*/ +package v1 + +import ( + "path" + "testing" + "time" + + "github.com/cgrates/birpc" + "github.com/cgrates/birpc/context" + "github.com/cgrates/cgrates/config" + "github.com/cgrates/cgrates/engine" + "github.com/cgrates/cgrates/utils" + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" +) + +var ( + trendCfgPath string + trendCfg *config.CGRConfig + trendRPC *birpc.Client + trendProfile *engine.TrendProfileWithAPIOpts + trendConfigDIR string + + sTestsTrend = []func(t *testing.T){ + testTrendSInitCfg, + testTrendSInitDataDb, + testTrendSResetStorDb, + testTrendSStartEngine, + testTrendSRPCConn, + testTrendSLoadAdd, + testTrendSetTrendProfile, + testTrendSGetTrendProfileIDs, + testTrendSUpdateTrendProfile, + testTrendSRemTrendProfile, + testTrendSKillEngine, + } +) + +func TestTrendSIT(t *testing.T) { + switch *utils.DBType { + case utils.MetaInternal: + trendConfigDIR = "tutinternal" + case utils.MetaMySQL: + trendConfigDIR = "tutmysql" + case utils.MetaMongo: + trendConfigDIR = "tutmongo" + case utils.MetaPostgres: + t.SkipNow() + default: + t.Fatal("Unknown Database type") + } + for _, stest := range sTestsTrend { + t.Run(trendConfigDIR, stest) + } +} + +func testTrendSInitCfg(t *testing.T) { + var err error + trendCfgPath = path.Join(*utils.DataDir, "conf", "samples", trendConfigDIR) + trendCfg, err = config.NewCGRConfigFromPath(trendCfgPath) + if err != nil { + t.Error(err) + } +} + +func testTrendSInitDataDb(t *testing.T) { + if err := engine.InitDataDb(trendCfg); err != nil { + t.Fatal(err) + } +} + +// Wipe out the cdr database +func testTrendSResetStorDb(t *testing.T) { + if err := engine.InitStorDb(trendCfg); err != nil { + t.Fatal(err) + } +} + +// Start CGR Engine +func testTrendSStartEngine(t *testing.T) { + if _, err := engine.StopStartEngine(trendCfgPath, *utils.WaitRater); err != nil { + t.Fatal(err) + } +} + +// Connect rpc client to rater +func testTrendSRPCConn(t *testing.T) { + var err error + trendRPC, err = newRPCClient(trendCfg.ListenCfg()) // We connect over JSON so we can also troubleshoot if needed + if err != nil { + t.Fatal(err) + } +} +func testTrendSLoadAdd(t *testing.T) { + trendProfile := &engine.TrendProfileWithAPIOpts{ + TrendProfile: &engine.TrendProfile{ + Tenant: "cgrates.org", + ID: "TR_AVG", + QueryInterval: 2 * time.Minute, + StatID: "Stat1", + Trend: "*average", + }, + } + + var result string + if err := trendRPC.Call(context.Background(), utils.APIerSv1SetTrendProfile, trendProfile, &result); err != nil { + t.Error(err) + } else if result != utils.OK { + t.Error("Unexpected reply returned", result) + } + +} + +func testTrendSetTrendProfile(t *testing.T) { + var ( + reply *engine.TrendProfileWithAPIOpts + result string + ) + trendProfile = &engine.TrendProfileWithAPIOpts{ + TrendProfile: &engine.TrendProfile{ + Tenant: "cgrates.org", + ID: "Trend1", + QueryInterval: time.Second * 15, + ThresholdIDs: []string{"THD1", "THD2"}}, + } + if err := trendRPC.Call(context.Background(), utils.APIerSv1GetTrendProfile, + &utils.TenantID{Tenant: "cgrates.org", ID: "Trend1"}, &reply); err == nil || + err.Error() != utils.ErrNotFound.Error() { + t.Fatal(err) + } + if err := trendRPC.Call(context.Background(), utils.APIerSv1SetTrendProfile, trendProfile, &result); err != nil { + t.Error(err) + } else if result != utils.OK { + t.Errorf("Expected: %v,Received: %v", utils.OK, result) + } + if err := trendRPC.Call(context.Background(), utils.APIerSv1GetTrendProfile, &utils.TenantID{Tenant: "cgrates.org", ID: "Trend1"}, &reply); err != nil { + t.Error(err) + } else if diff := cmp.Diff(trendProfile, reply, cmpopts.SortSlices(func(a, b string) bool { return a < b })); diff != utils.EmptyString { + t.Errorf("Unnexpected profile (-expected +got):\n%s", diff) + } +} +func testTrendSGetTrendProfileIDs(t *testing.T) { + expected := []string{"Trend1", "TR_AVG"} + var result []string + if err := trendRPC.Call(context.Background(), utils.APIerSv1GetTrendProfileIDs, utils.PaginatorWithTenant{}, &result); err != nil { + t.Error(err) + } else if len(expected) != len(result) { + t.Errorf("Expecting : %+v, received: %+v", expected, result) + } +} + +func testTrendSUpdateTrendProfile(t *testing.T) { + var ( + reply *engine.TrendProfileWithAPIOpts + result string + ) + if err := trendRPC.Call(context.Background(), utils.APIerSv1SetTrendProfile, trendProfile, &result); err != nil { + t.Error(err) + } + if err := trendRPC.Call(context.Background(), utils.APIerSv1GetTrendProfile, &utils.TenantID{Tenant: "cgrates.org", ID: "Trend1"}, &reply); err != nil { + t.Error(err) + } else if diff := cmp.Diff(trendProfile, reply, cmpopts.SortSlices(func(a, b string) bool { return a < b })); diff != utils.EmptyString { + t.Errorf("Unnexpected profile (-expected +got):\n%s", diff) + } +} +func testTrendSRemTrendProfile(t *testing.T) { + var ( + resp string + reply *engine.TrendProfile + ) + if err := trendRPC.Call(context.Background(), utils.APIerSv1RemoveTrendProfile, + &utils.TenantID{Tenant: "cgrates.org", ID: "Trend1"}, &resp); err != nil { + t.Error(err) + } else if resp != utils.OK { + t.Error("Unexpected reply returned", resp) + } + + if err := trendRPC.Call(context.Background(), utils.APIerSv1GetTrendProfile, + &utils.TenantID{Tenant: "cgrates.org", ID: "Trend1"}, + &reply); err == nil || err.Error() != utils.ErrNotFound.Error() { + t.Error(err) + } +} + +func testTrendSKillEngine(t *testing.T) { + if err := engine.KillEngine(*utils.WaitRater); err != nil { + t.Error(err) + } +} diff --git a/cmd/cgr-engine/cgr-engine.go b/cmd/cgr-engine/cgr-engine.go index bd0d9835b..697514085 100644 --- a/cmd/cgr-engine/cgr-engine.go +++ b/cmd/cgr-engine/cgr-engine.go @@ -455,7 +455,7 @@ func main() { internalChargerSChan := make(chan birpc.ClientConnector, 1) internalThresholdSChan := make(chan birpc.ClientConnector, 1) internalStatSChan := make(chan birpc.ClientConnector, 1) - internalSarSChan := make(chan birpc.ClientConnector, 1) + internalTrendSChan := make(chan birpc.ClientConnector, 1) internalSagSChan := make(chan birpc.ClientConnector, 1) internalResourceSChan := make(chan birpc.ClientConnector, 1) internalRouteSChan := make(chan birpc.ClientConnector, 1) @@ -485,7 +485,7 @@ func main() { utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS): internalSessionSChan, utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats): internalStatSChan, utils.ConcatenatedKey(utils.MetaInternal, utils.MetaRoutes): internalRouteSChan, - utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSars): internalSarSChan, + utils.ConcatenatedKey(utils.MetaInternal, utils.MetaTrends): internalTrendSChan, utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSags): internalSagSChan, utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds): internalThresholdSChan, utils.ConcatenatedKey(utils.MetaInternal, utils.MetaServiceManager): internalServeManagerChan, @@ -528,7 +528,7 @@ func main() { utils.SessionS: new(sync.WaitGroup), utils.SIPAgent: new(sync.WaitGroup), utils.StatS: new(sync.WaitGroup), - utils.SarS: new(sync.WaitGroup), + utils.TrendS: new(sync.WaitGroup), utils.SagS: new(sync.WaitGroup), utils.StorDB: new(sync.WaitGroup), utils.ThresholdS: new(sync.WaitGroup), @@ -611,8 +611,8 @@ func main() { tS := services.NewThresholdService(cfg, dmService, cacheS, filterSChan, server, internalThresholdSChan, anz, srvDep) stS := services.NewStatService(cfg, dmService, cacheS, filterSChan, server, internalStatSChan, connManager, anz, srvDep) - srS := services.NewSarService(cfg, dmService, cacheS, filterSChan, server, - internalSarSChan, connManager, anz, srvDep) + srS := services.NewTrendService(cfg, dmService, cacheS, filterSChan, server, + internalTrendSChan, connManager, anz, srvDep) sgS := services.NewSagService(cfg, dmService, cacheS, filterSChan, server, internalSagSChan, connManager, anz, srvDep) reS := services.NewResourceService(cfg, dmService, cacheS, filterSChan, server, diff --git a/config/config.go b/config/config.go index 5b9a6a38f..90dda9cb6 100644 --- a/config/config.go +++ b/config/config.go @@ -154,7 +154,7 @@ func newCGRConfig(config []byte) (cfg *CGRConfig, err error) { cfg.chargerSCfg = new(ChargerSCfg) cfg.resourceSCfg = &ResourceSConfig{Opts: &ResourcesOpts{}} cfg.statsCfg = &StatSCfg{Opts: &StatsOpts{}} - cfg.sarsCfg = new(SarSCfg) + cfg.trendsCfg = new(TrendSCfg) cfg.sagsCfg = new(SagSCfg) cfg.thresholdSCfg = &ThresholdSCfg{Opts: &ThresholdsOpts{}} cfg.routeSCfg = &RouteSCfg{Opts: &RoutesOpts{}} @@ -315,7 +315,7 @@ type CGRConfig struct { chargerSCfg *ChargerSCfg // ChargerS config resourceSCfg *ResourceSConfig // ResourceS config statsCfg *StatSCfg // StatS config - sarsCfg *SarSCfg // SarS config + trendsCfg *TrendSCfg // TrendS config sagsCfg *SagSCfg // Sags config thresholdSCfg *ThresholdSCfg // ThresholdS config routeSCfg *RouteSCfg // RouteS config @@ -367,7 +367,7 @@ func (cfg *CGRConfig) loadFromJSONCfg(jsnCfg *CgrJsonCfg) (err error) { cfg.loadFreeswitchAgentCfg, cfg.loadKamAgentCfg, cfg.loadAsteriskAgentCfg, cfg.loadDiameterAgentCfg, cfg.loadRadiusAgentCfg, cfg.loadDNSAgentCfg, cfg.loadHTTPAgentCfg, cfg.loadAttributeSCfg, - cfg.loadChargerSCfg, cfg.loadResourceSCfg, cfg.loadStatSCfg, cfg.loadSarSCfg, + cfg.loadChargerSCfg, cfg.loadResourceSCfg, cfg.loadStatSCfg, cfg.loadTrendSCfg, cfg.loadSagSCfg, cfg.loadThresholdSCfg, cfg.loadRouteSCfg, cfg.loadLoaderSCfg, cfg.loadMailerCfg, cfg.loadSureTaxCfg, cfg.loadDispatcherSCfg, cfg.loadLoaderCgrCfg, cfg.loadMigratorCgrCfg, cfg.loadTLSCgrCfg, @@ -637,13 +637,13 @@ func (cfg *CGRConfig) loadStatSCfg(jsnCfg *CgrJsonCfg) (err error) { return cfg.statsCfg.loadFromJSONCfg(jsnStatSCfg) } -// loadSarSCfg loads the SarS section of the configuration -func (cfg *CGRConfig) loadSarSCfg(jsnCfg *CgrJsonCfg) (err error) { - var jsnSarSCfg *SarsJsonCfg - if jsnSarSCfg, err = jsnCfg.SarsJsonCfg(); err != nil { +// loadTrendSCfg loads the TrendS section of the configuration +func (cfg *CGRConfig) loadTrendSCfg(jsnCfg *CgrJsonCfg) (err error) { + var jsnTrendSCfg *TrendsJsonCfg + if jsnTrendSCfg, err = jsnCfg.TrendsJsonCfg(); err != nil { return } - return cfg.sarsCfg.loadFromJSONCfg(jsnSarSCfg) + return cfg.trendsCfg.loadFromJSONCfg(jsnTrendSCfg) } // loadSagSCfg loads the SagS section of the configuration @@ -909,11 +909,11 @@ func (cfg *CGRConfig) StatSCfg() *StatSCfg { // not done return cfg.statsCfg } -// SarSCfg returns the config for SarS -func (cfg *CGRConfig) SarSCfg() *SarSCfg { - cfg.lks[SARS_JSON].Lock() - defer cfg.lks[SARS_JSON].Unlock() - return cfg.sarsCfg +// TrendSCfg returns the config for TrendS +func (cfg *CGRConfig) TrendSCfg() *TrendSCfg { + cfg.lks[TRENDS_JSON].Lock() + defer cfg.lks[TRENDS_JSON].Unlock() + return cfg.trendsCfg } // SagSCfg returns the config for SagS @@ -1272,7 +1272,7 @@ func (cfg *CGRConfig) getLoadFunctions() map[string]func(*CgrJsonCfg) error { ChargerSCfgJson: cfg.loadChargerSCfg, RESOURCES_JSON: cfg.loadResourceSCfg, STATS_JSON: cfg.loadStatSCfg, - SARS_JSON: cfg.loadSarSCfg, + TRENDS_JSON: cfg.loadTrendSCfg, SAGS_JSON: cfg.loadSagSCfg, THRESHOLDS_JSON: cfg.loadThresholdSCfg, RouteSJson: cfg.loadRouteSCfg, @@ -1524,8 +1524,8 @@ func (cfg *CGRConfig) reloadSections(sections ...string) { cfg.rldChans[RESOURCES_JSON] <- struct{}{} case STATS_JSON: cfg.rldChans[STATS_JSON] <- struct{}{} - case SARS_JSON: - cfg.rldChans[SARS_JSON] <- struct{}{} + case TRENDS_JSON: + cfg.rldChans[TRENDS_JSON] <- struct{}{} case SAGS_JSON: cfg.rldChans[SAGS_JSON] <- struct{}{} case THRESHOLDS_JSON: @@ -1580,7 +1580,7 @@ func (cfg *CGRConfig) AsMapInterface(separator string) (mp map[string]any) { ChargerSCfgJson: cfg.chargerSCfg.AsMapInterface(), RESOURCES_JSON: cfg.resourceSCfg.AsMapInterface(), STATS_JSON: cfg.statsCfg.AsMapInterface(), - SARS_JSON: cfg.sarsCfg.AsMapInterface(), + TRENDS_JSON: cfg.trendsCfg.AsMapInterface(), SAGS_JSON: cfg.sagsCfg.AsMapInterface(), THRESHOLDS_JSON: cfg.thresholdSCfg.AsMapInterface(), RouteSJson: cfg.routeSCfg.AsMapInterface(), @@ -1720,8 +1720,8 @@ func (cfg *CGRConfig) V1GetConfig(ctx *context.Context, args *SectionWithAPIOpts mp = cfg.ResourceSCfg().AsMapInterface() case STATS_JSON: mp = cfg.StatSCfg().AsMapInterface() - case SARS_JSON: - mp = cfg.SarSCfg().AsMapInterface() + case TRENDS_JSON: + mp = cfg.TrendSCfg().AsMapInterface() case SAGS_JSON: mp = cfg.SagSCfg().AsMapInterface() case THRESHOLDS_JSON: @@ -1892,8 +1892,8 @@ func (cfg *CGRConfig) V1GetConfigAsJSON(ctx *context.Context, args *SectionWithA mp = cfg.ResourceSCfg().AsMapInterface() case STATS_JSON: mp = cfg.StatSCfg().AsMapInterface() - case SARS_JSON: - mp = cfg.SarSCfg().AsMapInterface() + case TRENDS_JSON: + mp = cfg.TrendSCfg().AsMapInterface() case SAGS_JSON: mp = cfg.SagSCfg().AsMapInterface() case THRESHOLDS_JSON: @@ -2019,7 +2019,7 @@ func (cfg *CGRConfig) Clone() (cln *CGRConfig) { chargerSCfg: cfg.chargerSCfg.Clone(), resourceSCfg: cfg.resourceSCfg.Clone(), statsCfg: cfg.statsCfg.Clone(), - sarsCfg: cfg.sarsCfg.Clone(), + trendsCfg: cfg.trendsCfg.Clone(), sagsCfg: cfg.sagsCfg.Clone(), thresholdSCfg: cfg.thresholdSCfg.Clone(), routeSCfg: cfg.routeSCfg.Clone(), diff --git a/config/config_defaults.go b/config/config_defaults.go index 39f241889..c9b1ed206 100644 --- a/config/config_defaults.go +++ b/config/config_defaults.go @@ -115,7 +115,7 @@ const CGRATES_CFG_JSON = ` "*resources": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false}, "*statqueue_profiles": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false}, "*sag_profiles": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false}, - "*sar_profiles": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false}, + "*trend_profiles": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false}, "*statqueues": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false}, "*threshold_profiles": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false}, "*thresholds": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false}, @@ -196,7 +196,7 @@ const CGRATES_CFG_JSON = ` "*tp_resources": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false}, "*tp_stats": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false}, "*tp_sags": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false}, - "*tp_sars": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false}, + "*tp_trends": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false}, "*tp_thresholds": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false}, "*tp_filters": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false}, "*tp_routes": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false}, @@ -285,7 +285,7 @@ const CGRATES_CFG_JSON = ` "*resources": {"limit": -1, "ttl": "", "static_ttl": false, "precache": false, "remote":false, "replicate": false}, // control resources caching "*event_resources": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate": false}, // matching resources to events "*statqueue_profiles": {"limit": -1, "ttl": "", "static_ttl": false, "precache": false, "remote":false, "replicate": false}, // statqueue profiles - "*sag_profiles": {"limit": -1, "ttl": "", "static_ttl": false, "precache": false, "remote":false, "replicate": false}, // sagprofiles + "*sag_profiles": {"limit": -1, "ttl": "", "static_ttl": false, "precache": false, "remote":false, "replicate": false}, // stataggregator profiles "*statqueues": {"limit": -1, "ttl": "", "static_ttl": false, "precache": false, "remote":false, "replicate": false}, // statqueues with metrics "*threshold_profiles": {"limit": -1, "ttl": "", "static_ttl": false, "precache": false, "remote":false, "replicate": false}, // control threshold profiles caching "*thresholds": {"limit": -1, "ttl": "", "static_ttl": false, "precache": false, "remote":false, "replicate": false}, // control thresholds caching @@ -832,8 +832,8 @@ const CGRATES_CFG_JSON = ` }, }, -"sars":{ // SaRS config - "enabled": false, // starts SaRS service: . +"trends":{ // TrendS config + "enabled": false, // starts TrendS service: . "stats_conns": [], // connections to StatS ,empty to disable stats functionality: <""|*internal|$rpc_conns_id> }, diff --git a/config/config_json.go b/config/config_json.go index 4b846abc2..b9978268d 100644 --- a/config/config_json.go +++ b/config/config_json.go @@ -44,7 +44,7 @@ const ( RESOURCES_JSON = "resources" STATS_JSON = "stats" THRESHOLDS_JSON = "thresholds" - SARS_JSON = "sars" + TRENDS_JSON = "trends" SAGS_JSON = "sags" RouteSJson = "routes" LoaderJson = "loaders" @@ -74,7 +74,7 @@ const ( var ( sortedCfgSections = []string{GENERAL_JSN, RPCConnsJsonName, DATADB_JSN, STORDB_JSN, LISTEN_JSN, TlsCfgJson, HTTP_JSN, SCHEDULER_JSN, CACHE_JSN, FilterSjsn, RALS_JSN, CDRS_JSN, ERsJson, SessionSJson, AsteriskAgentJSN, FreeSWITCHAgentJSN, KamailioAgentJSN, - DA_JSN, RA_JSN, HttpAgentJson, DNSAgentJson, ATTRIBUTE_JSN, ChargerSCfgJson, RESOURCES_JSON, STATS_JSON, SARS_JSON, SAGS_JSON, + DA_JSN, RA_JSN, HttpAgentJson, DNSAgentJson, ATTRIBUTE_JSN, ChargerSCfgJson, RESOURCES_JSON, STATS_JSON, TRENDS_JSON, SAGS_JSON, THRESHOLDS_JSON, RouteSJson, LoaderJson, MAILER_JSN, SURETAX_JSON, CgrLoaderCfgJson, CgrMigratorCfgJson, DispatcherSJson, JanusAgentJson, AnalyzerCfgJson, ApierS, EEsJson, SIPAgentJson, RegistrarCJson, TemplatesJson, ConfigSJson, APIBanCfgJson, SentryPeerCfgJson, CoreSCfgJson} ) @@ -371,12 +371,12 @@ func (jsnCfg CgrJsonCfg) StatSJsonCfg() (*StatServJsonCfg, error) { return cfg, nil } -func (jsnCfg CgrJsonCfg) SarsJsonCfg() (*SarsJsonCfg, error) { - rawCfg, hasKey := jsnCfg[SARS_JSON] +func (jsnCfg CgrJsonCfg) TrendsJsonCfg() (*TrendsJsonCfg, error) { + rawCfg, hasKey := jsnCfg[TRENDS_JSON] if !hasKey { return nil, nil } - cfg := new(SarsJsonCfg) + cfg := new(TrendsJsonCfg) if err := json.Unmarshal(*rawCfg, cfg); err != nil { return nil, err } diff --git a/config/config_json_test.go b/config/config_json_test.go index edb034ee3..c388a04eb 100644 --- a/config/config_json_test.go +++ b/config/config_json_test.go @@ -417,7 +417,7 @@ func TestDfDataDbJsonCfg(t *testing.T) { Ttl: utils.StringPointer(utils.EmptyString), Static_ttl: utils.BoolPointer(false), }, - utils.MetaSarProfiles: { + utils.MetaTrendProfiles: { Replicate: utils.BoolPointer(false), Remote: utils.BoolPointer(false), Limit: utils.IntPointer(-1), @@ -677,7 +677,7 @@ func TestDfStorDBJsonCfg(t *testing.T) { Ttl: utils.StringPointer(utils.EmptyString), Static_ttl: utils.BoolPointer(false), }, - utils.CacheTBLTPSars: { + utils.CacheTBLTPTrends: { Replicate: utils.BoolPointer(false), Remote: utils.BoolPointer(false), Limit: utils.IntPointer(-1), diff --git a/config/config_test.go b/config/config_test.go index 10352185a..360c0d39d 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -4842,7 +4842,7 @@ func TestV1GetConfigAsJSONGeneral(t *testing.T) { func TestV1GetConfigAsJSONDataDB(t *testing.T) { var reply string - expected := `{"data_db":{"db_host":"127.0.0.1","db_name":"10","db_password":"","db_port":6379,"db_type":"*redis","db_user":"cgrates","items":{"*account_action_plans":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*accounts":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*action_plans":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*action_triggers":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*actions":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*attribute_filter_indexes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*attribute_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*charger_filter_indexes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*charger_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*destinations":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*dispatcher_filter_indexes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*dispatcher_hosts":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*dispatcher_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*filters":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*load_ids":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*rating_plans":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*rating_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*resource_filter_indexes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*resource_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*resources":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*reverse_destinations":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*reverse_filter_indexes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*route_filter_indexes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*route_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*sag_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*sessions_backup":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*shared_groups":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*stat_filter_indexes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*statqueue_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*statqueues":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*threshold_filter_indexes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*threshold_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*thresholds":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*timings":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*versions":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false}},"opts":{"mongoConnScheme":"mongodb","mongoQueryTimeout":"10s","redisCACertificate":"","redisClientCertificate":"","redisClientKey":"","redisCluster":false,"redisClusterOndownDelay":"0s","redisClusterSync":"5s","redisConnectAttempts":20,"redisConnectTimeout":"0s","redisMaxConns":10,"redisPoolPipelineLimit":0,"redisPoolPipelineWindow":"150µs","redisReadTimeout":"0s","redisSentinel":"","redisTLS":false,"redisWriteTimeout":"0s"},"remote_conn_id":"","remote_conns":[],"replication_cache":"","replication_conns":[],"replication_filtered":false}}` + expected := `{"data_db":{"db_host":"127.0.0.1","db_name":"10","db_password":"","db_port":6379,"db_type":"*redis","db_user":"cgrates","items":{"*account_action_plans":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*accounts":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*action_plans":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*action_triggers":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*actions":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*attribute_filter_indexes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*attribute_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*charger_filter_indexes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*charger_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*destinations":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*dispatcher_filter_indexes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*dispatcher_hosts":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*dispatcher_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*filters":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*load_ids":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*rating_plans":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*rating_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*resource_filter_indexes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*resource_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*resources":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*reverse_destinations":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*reverse_filter_indexes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*route_filter_indexes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*route_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*sag_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*sessions_backup":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*shared_groups":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*stat_filter_indexes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*statqueue_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*statqueues":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*threshold_filter_indexes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*threshold_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*thresholds":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*timings":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*trend_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*versions":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false}},"opts":{"mongoConnScheme":"mongodb","mongoQueryTimeout":"10s","redisCACertificate":"","redisClientCertificate":"","redisClientKey":"","redisCluster":false,"redisClusterOndownDelay":"0s","redisClusterSync":"5s","redisConnectAttempts":20,"redisConnectTimeout":"0s","redisMaxConns":10,"redisPoolPipelineLimit":0,"redisPoolPipelineWindow":"150µs","redisReadTimeout":"0s","redisSentinel":"","redisTLS":false,"redisWriteTimeout":"0s"},"remote_conn_id":"","remote_conns":[],"replication_cache":"","replication_conns":[],"replication_filtered":false}}` cfgCgr := NewDefaultCGRConfig() if err := cfgCgr.V1GetConfigAsJSON(context.Background(), &SectionWithAPIOpts{Section: DATADB_JSN}, &reply); err != nil { t.Error(err) @@ -4853,7 +4853,7 @@ func TestV1GetConfigAsJSONDataDB(t *testing.T) { func TestV1GetConfigAsJSONStorDB(t *testing.T) { var reply string - expected := `{"stor_db":{"db_host":"127.0.0.1","db_name":"cgrates","db_password":"CGRateS.org","db_port":3306,"db_type":"*mysql","db_user":"cgrates","items":{"*cdrs":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*session_costs":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_account_actions":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_action_plans":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_action_triggers":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_actions":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_attributes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_chargers":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_destination_rates":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_destinations":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_dispatcher_hosts":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_dispatcher_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_filters":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_rates":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_rating_plans":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_rating_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_resources":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_routes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_sags":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_sars":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_shared_groups":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_stats":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_thresholds":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_timings":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*versions":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false}},"opts":{"mongoConnScheme":"mongodb","mongoQueryTimeout":"10s","mysqlDSNParams":{},"mysqlLocation":"Local","pgSSLMode":"disable","pgSchema":"","sqlConnMaxLifetime":"0s","sqlMaxIdleConns":10,"sqlMaxOpenConns":100},"prefix_indexed_fields":[],"remote_conns":null,"replication_conns":null,"string_indexed_fields":[]}}` + expected := `{"stor_db":{"db_host":"127.0.0.1","db_name":"cgrates","db_password":"CGRateS.org","db_port":3306,"db_type":"*mysql","db_user":"cgrates","items":{"*cdrs":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*session_costs":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_account_actions":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_action_plans":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_action_triggers":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_actions":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_attributes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_chargers":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_destination_rates":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_destinations":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_dispatcher_hosts":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_dispatcher_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_filters":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_rates":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_rating_plans":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_rating_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_resources":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_routes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_sags":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_shared_groups":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_stats":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_thresholds":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_timings":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_trends":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*versions":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false}},"opts":{"mongoConnScheme":"mongodb","mongoQueryTimeout":"10s","mysqlDSNParams":{},"mysqlLocation":"Local","pgSSLMode":"disable","pgSchema":"","sqlConnMaxLifetime":"0s","sqlMaxIdleConns":10,"sqlMaxOpenConns":100},"prefix_indexed_fields":[],"remote_conns":null,"replication_conns":null,"string_indexed_fields":[]}}` cfgCgr := NewDefaultCGRConfig() if err := cfgCgr.V1GetConfigAsJSON(context.Background(), &SectionWithAPIOpts{Section: STORDB_JSN}, &reply); err != nil { t.Error(err) @@ -5365,7 +5365,7 @@ func TestV1GetConfigAsJSONAllConfig(t *testing.T) { }` var reply string cgrCfg, err := NewCGRConfigFromJSONStringWithDefaults(cfgJSON) - expected := `{"analyzers":{"cleanup_interval":"1h0m0s","db_path":"/var/spool/cgrates/analyzers","enabled":false,"index_type":"*scorch","ttl":"24h0m0s"},"apiban":{"keys":[]},"apiers":{"attributes_conns":[],"caches_conns":["*internal"],"ees_conns":[],"enabled":false,"scheduler_conns":[]},"asterisk_agent":{"asterisk_conns":[{"address":"127.0.0.1:8088","alias":"","connect_attempts":3,"max_reconnect_interval":"0s","password":"CGRateS.org","reconnects":5,"user":"cgrates"}],"create_cdr":false,"enabled":false,"sessions_conns":["*birpc_internal"]},"attributes":{"any_context":true,"apiers_conns":[],"enabled":false,"indexed_selects":true,"nested_fields":false,"opts":{"*processRuns":1,"*profileIDs":[],"*profileIgnoreFilters":false,"*profileRuns":0},"prefix_indexed_fields":[],"resources_conns":[],"stats_conns":[],"suffix_indexed_fields":[]},"caches":{"partitions":{"*account_action_plans":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*action_plans":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*action_triggers":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*actions":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*apiban":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false,"ttl":"2m0s"},"*attribute_filter_indexes":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*attribute_profiles":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*caps_events":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*cdr_ids":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false,"ttl":"10m0s"},"*charger_filter_indexes":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*charger_profiles":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*closed_sessions":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false,"ttl":"10s"},"*destinations":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*diameter_messages":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false,"ttl":"3h0m0s"},"*dispatcher_filter_indexes":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*dispatcher_hosts":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*dispatcher_loads":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*dispatcher_profiles":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*dispatcher_routes":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*dispatchers":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*event_charges":{"limit":0,"precache":false,"remote":false,"replicate":false,"static_ttl":false,"ttl":"10s"},"*event_resources":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*filters":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*load_ids":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*radius_packets":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false,"ttl":"3h0m0s"},"*rating_plans":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*rating_profiles":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*replication_hosts":{"limit":0,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*resource_filter_indexes":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*resource_profiles":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*resources":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*reverse_destinations":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*reverse_filter_indexes":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*route_filter_indexes":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*route_profiles":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*rpc_connections":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*rpc_responses":{"limit":0,"precache":false,"remote":false,"replicate":false,"static_ttl":false,"ttl":"2s"},"*sag_profiles":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*sentrypeer":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":true,"ttl":"24h0m0s"},"*shared_groups":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*stat_filter_indexes":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*statqueue_profiles":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*statqueues":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*stir":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false,"ttl":"3h0m0s"},"*threshold_filter_indexes":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*threshold_profiles":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*thresholds":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*timings":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*uch":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false,"ttl":"3h0m0s"}},"remote_conns":[],"replication_conns":[]},"cdrs":{"attributes_conns":[],"chargers_conns":[],"ees_conns":[],"enabled":false,"extra_fields":[],"online_cdr_exports":[],"rals_conns":[],"scheduler_conns":[],"session_cost_retries":5,"stats_conns":[],"store_cdrs":true,"thresholds_conns":[]},"chargers":{"attributes_conns":[],"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"suffix_indexed_fields":[]},"configs":{"enabled":false,"root_dir":"/var/spool/cgrates/configs","url":"/configs/"},"cores":{"caps":0,"caps_stats_interval":"0","caps_strategy":"*busy","shutdown_timeout":"1s"},"data_db":{"db_host":"127.0.0.1","db_name":"10","db_password":"","db_port":6379,"db_type":"*redis","db_user":"cgrates","items":{"*account_action_plans":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*accounts":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*action_plans":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*action_triggers":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*actions":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*attribute_filter_indexes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*attribute_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*charger_filter_indexes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*charger_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*destinations":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*dispatcher_filter_indexes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*dispatcher_hosts":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*dispatcher_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*filters":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*load_ids":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*rating_plans":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*rating_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*resource_filter_indexes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*resource_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*resources":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*reverse_destinations":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*reverse_filter_indexes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*route_filter_indexes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*route_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*sag_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*sessions_backup":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*shared_groups":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*stat_filter_indexes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*statqueue_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*statqueues":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*threshold_filter_indexes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*threshold_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*thresholds":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*timings":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*versions":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false}},"opts":{"mongoConnScheme":"mongodb","mongoQueryTimeout":"10s","redisCACertificate":"","redisClientCertificate":"","redisClientKey":"","redisCluster":false,"redisClusterOndownDelay":"0s","redisClusterSync":"5s","redisConnectAttempts":20,"redisConnectTimeout":"0s","redisMaxConns":10,"redisPoolPipelineLimit":0,"redisPoolPipelineWindow":"150µs","redisReadTimeout":"0s","redisSentinel":"","redisTLS":false,"redisWriteTimeout":"0s"},"remote_conn_id":"","remote_conns":[],"replication_cache":"","replication_conns":[],"replication_filtered":false},"diameter_agent":{"asr_template":"","concurrent_requests":-1,"dictionaries_path":"/usr/share/cgrates/diameter/dict/","enabled":false,"forced_disconnect":"*none","listen":"127.0.0.1:3868","listen_net":"tcp","origin_host":"CGR-DA","origin_realm":"cgrates.org","product_name":"CGRateS","rar_template":"","request_processors":[],"sessions_conns":["*birpc_internal"],"synced_conn_requests":false,"vendor_id":0},"dispatchers":{"any_subsystem":true,"attributes_conns":[],"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"prevent_loop":false,"suffix_indexed_fields":[]},"dns_agent":{"enabled":false,"listeners":[{"address":"127.0.0.1:53","network":"udp"}],"request_processors":[],"sessions_conns":["*internal"],"timezone":""},"ees":{"attributes_conns":[],"cache":{"*file_csv":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false,"ttl":"5s"}},"enabled":false,"exporters":[{"attempts":1,"attribute_context":"","attribute_ids":[],"concurrent_requests":0,"export_path":"/var/spool/cgrates/ees","failed_posts_dir":"/var/spool/cgrates/failed_posts","fields":[],"filters":[],"flags":[],"id":"*default","opts":{},"synchronous":false,"timezone":"","type":"*none"}]},"ers":{"concurrent_events":1,"ees_conns":[],"enabled":false,"partial_cache_ttl":"1s","readers":[{"cache_dump_fields":[],"concurrent_requests":1024,"fields":[{"mandatory":true,"path":"*cgreq.ToR","tag":"ToR","type":"*variable","value":"~*req.2"},{"mandatory":true,"path":"*cgreq.OriginID","tag":"OriginID","type":"*variable","value":"~*req.3"},{"mandatory":true,"path":"*cgreq.RequestType","tag":"RequestType","type":"*variable","value":"~*req.4"},{"mandatory":true,"path":"*cgreq.Tenant","tag":"Tenant","type":"*variable","value":"~*req.6"},{"mandatory":true,"path":"*cgreq.Category","tag":"Category","type":"*variable","value":"~*req.7"},{"mandatory":true,"path":"*cgreq.Account","tag":"Account","type":"*variable","value":"~*req.8"},{"mandatory":true,"path":"*cgreq.Subject","tag":"Subject","type":"*variable","value":"~*req.9"},{"mandatory":true,"path":"*cgreq.Destination","tag":"Destination","type":"*variable","value":"~*req.10"},{"mandatory":true,"path":"*cgreq.SetupTime","tag":"SetupTime","type":"*variable","value":"~*req.11"},{"mandatory":true,"path":"*cgreq.AnswerTime","tag":"AnswerTime","type":"*variable","value":"~*req.12"},{"mandatory":true,"path":"*cgreq.Usage","tag":"Usage","type":"*variable","value":"~*req.13"}],"filters":[],"flags":[],"id":"*default","max_reconnect_interval":"5m0s","opts":{"csvFieldSeparator":",","csvHeaderDefineChar":":","csvRowLength":0,"natsSubject":"cgrates_cdrs","partialCacheAction":"*none","partialOrderField":"~*req.AnswerTime"},"partial_commit_fields":[],"processed_path":"/var/spool/cgrates/ers/out","reconnects":-1,"run_delay":"0","source_path":"/var/spool/cgrates/ers/in","tenant":"","timezone":"","type":"*none"}],"sessions_conns":["*internal"]},"filters":{"apiers_conns":[],"resources_conns":[],"stats_conns":[]},"freeswitch_agent":{"active_session_delimiter":",","create_cdr":false,"empty_balance_ann_file":"","empty_balance_context":"","enabled":false,"event_socket_conns":[{"address":"127.0.0.1:8021","alias":"127.0.0.1:8021","max_reconnect_interval":"0s","password":"ClueCon","reconnects":5,"reply_timeout":"1m0s"}],"extra_fields":"","low_balance_ann_file":"","max_wait_connection":"2s","sessions_conns":["*birpc_internal"],"subscribe_park":true},"general":{"caching_delay":"0","connect_attempts":5,"connect_timeout":"1s","dbdata_encoding":"*msgpack","default_caching":"*reload","default_category":"call","default_request_type":"*rated","default_tenant":"cgrates.org","default_timezone":"Local","digest_equal":":","digest_separator":",","failed_posts_dir":"/var/spool/cgrates/failed_posts","failed_posts_ttl":"5s","locking_timeout":"0","log_level":6,"logger":"*syslog","max_parallel_conns":100,"max_reconnect_interval":"0","node_id":"ENGINE1","poster_attempts":3,"reconnects":-1,"reply_timeout":"2s","rounding_decimals":5,"rsr_separator":";","tpexport_dir":"/var/spool/cgrates/tpe"},"http":{"auth_users":{},"client_opts":{"dialFallbackDelay":"300ms","dialKeepAlive":"30s","dialTimeout":"30s","disableCompression":false,"disableKeepAlives":false,"expectContinueTimeout":"0s","forceAttemptHttp2":true,"idleConnTimeout":"1m30s","maxConnsPerHost":0,"maxIdleConns":100,"maxIdleConnsPerHost":2,"responseHeaderTimeout":"0s","skipTlsVerify":false,"tlsHandshakeTimeout":"10s"},"freeswitch_cdrs_url":"/freeswitch_json","http_cdrs":"/cdr_http","json_rpc_url":"/jsonrpc","registrars_url":"/registrar","use_basic_auth":false,"ws_url":"/ws"},"http_agent":[],"kamailio_agent":{"create_cdr":false,"enabled":false,"evapi_conns":[{"address":"127.0.0.1:8448","alias":"","max_reconnect_interval":"0s","reconnects":5}],"sessions_conns":["*birpc_internal"],"timezone":""},"listen":{"http":"127.0.0.1:2080","http_tls":"127.0.0.1:2280","rpc_gob":"127.0.0.1:2013","rpc_gob_tls":"127.0.0.1:2023","rpc_json":"127.0.0.1:2012","rpc_json_tls":"127.0.0.1:2022"},"loader":{"caches_conns":["*localhost"],"data_path":"./","disable_reverse":false,"field_separator":",","gapi_credentials":".gapi/credentials.json","gapi_token":".gapi/token.json","scheduler_conns":["*localhost"],"tpid":""},"loaders":[{"caches_conns":["*internal"],"data":[{"fields":[{"mandatory":true,"path":"Tenant","tag":"TenantID","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ProfileID","type":"*variable","value":"~*req.1"},{"path":"Contexts","tag":"Contexts","type":"*variable","value":"~*req.2"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.3"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.4"},{"path":"AttributeFilterIDs","tag":"AttributeFilterIDs","type":"*variable","value":"~*req.5"},{"path":"Path","tag":"Path","type":"*variable","value":"~*req.6"},{"path":"Type","tag":"Type","type":"*variable","value":"~*req.7"},{"path":"Value","tag":"Value","type":"*variable","value":"~*req.8"},{"path":"Blocker","tag":"Blocker","type":"*variable","value":"~*req.9"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.10"}],"file_name":"Attributes.csv","flags":null,"type":"*attributes"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"Type","tag":"Type","type":"*variable","value":"~*req.2"},{"path":"Element","tag":"Element","type":"*variable","value":"~*req.3"},{"path":"Values","tag":"Values","type":"*variable","value":"~*req.4"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.5"}],"file_name":"Filters.csv","flags":null,"type":"*filters"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.3"},{"path":"UsageTTL","tag":"TTL","type":"*variable","value":"~*req.4"},{"path":"Limit","tag":"Limit","type":"*variable","value":"~*req.5"},{"path":"AllocationMessage","tag":"AllocationMessage","type":"*variable","value":"~*req.6"},{"path":"Blocker","tag":"Blocker","type":"*variable","value":"~*req.7"},{"path":"Stored","tag":"Stored","type":"*variable","value":"~*req.8"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.9"},{"path":"ThresholdIDs","tag":"ThresholdIDs","type":"*variable","value":"~*req.10"}],"file_name":"Resources.csv","flags":null,"type":"*resources"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.3"},{"path":"QueueLength","tag":"QueueLength","type":"*variable","value":"~*req.4"},{"path":"TTL","tag":"TTL","type":"*variable","value":"~*req.5"},{"path":"MinItems","tag":"MinItems","type":"*variable","value":"~*req.6"},{"path":"MetricIDs","tag":"MetricIDs","type":"*variable","value":"~*req.7"},{"path":"MetricFilterIDs","tag":"MetricFilterIDs","type":"*variable","value":"~*req.8"},{"path":"Blocker","tag":"Blocker","type":"*variable","value":"~*req.9"},{"path":"Stored","tag":"Stored","type":"*variable","value":"~*req.10"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.11"},{"path":"ThresholdIDs","tag":"ThresholdIDs","type":"*variable","value":"~*req.12"}],"file_name":"Stats.csv","flags":null,"type":"*stats"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.3"},{"path":"MaxHits","tag":"MaxHits","type":"*variable","value":"~*req.4"},{"path":"MinHits","tag":"MinHits","type":"*variable","value":"~*req.5"},{"path":"MinSleep","tag":"MinSleep","type":"*variable","value":"~*req.6"},{"path":"Blocker","tag":"Blocker","type":"*variable","value":"~*req.7"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.8"},{"path":"ActionIDs","tag":"ActionIDs","type":"*variable","value":"~*req.9"},{"path":"Async","tag":"Async","type":"*variable","value":"~*req.10"}],"file_name":"Thresholds.csv","flags":null,"type":"*thresholds"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.3"},{"path":"Sorting","tag":"Sorting","type":"*variable","value":"~*req.4"},{"path":"SortingParameters","tag":"SortingParameters","type":"*variable","value":"~*req.5"},{"path":"RouteID","tag":"RouteID","type":"*variable","value":"~*req.6"},{"path":"RouteFilterIDs","tag":"RouteFilterIDs","type":"*variable","value":"~*req.7"},{"path":"RouteAccountIDs","tag":"RouteAccountIDs","type":"*variable","value":"~*req.8"},{"path":"RouteRatingPlanIDs","tag":"RouteRatingPlanIDs","type":"*variable","value":"~*req.9"},{"path":"RouteResourceIDs","tag":"RouteResourceIDs","type":"*variable","value":"~*req.10"},{"path":"RouteStatIDs","tag":"RouteStatIDs","type":"*variable","value":"~*req.11"},{"path":"RouteWeight","tag":"RouteWeight","type":"*variable","value":"~*req.12"},{"path":"RouteBlocker","tag":"RouteBlocker","type":"*variable","value":"~*req.13"},{"path":"RouteParameters","tag":"RouteParameters","type":"*variable","value":"~*req.14"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.15"}],"file_name":"Routes.csv","flags":null,"type":"*routes"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.3"},{"path":"RunID","tag":"RunID","type":"*variable","value":"~*req.4"},{"path":"AttributeIDs","tag":"AttributeIDs","type":"*variable","value":"~*req.5"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.6"}],"file_name":"Chargers.csv","flags":null,"type":"*chargers"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"Contexts","tag":"Contexts","type":"*variable","value":"~*req.2"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.3"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.4"},{"path":"Strategy","tag":"Strategy","type":"*variable","value":"~*req.5"},{"path":"StrategyParameters","tag":"StrategyParameters","type":"*variable","value":"~*req.6"},{"path":"ConnID","tag":"ConnID","type":"*variable","value":"~*req.7"},{"path":"ConnFilterIDs","tag":"ConnFilterIDs","type":"*variable","value":"~*req.8"},{"path":"ConnWeight","tag":"ConnWeight","type":"*variable","value":"~*req.9"},{"path":"ConnBlocker","tag":"ConnBlocker","type":"*variable","value":"~*req.10"},{"path":"ConnParameters","tag":"ConnParameters","type":"*variable","value":"~*req.11"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.12"}],"file_name":"DispatcherProfiles.csv","flags":null,"type":"*dispatchers"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"Address","tag":"Address","type":"*variable","value":"~*req.2"},{"path":"Transport","tag":"Transport","type":"*variable","value":"~*req.3"},{"path":"ConnectAttempts","tag":"ConnectAttempts","type":"*variable","value":"~*req.4"},{"path":"Reconnects","tag":"Reconnects","type":"*variable","value":"~*req.5"},{"path":"MaxReconnectInterval","tag":"MaxReconnectInterval","type":"*variable","value":"~*req.6"},{"path":"ConnectTimeout","tag":"ConnectTimeout","type":"*variable","value":"~*req.7"},{"path":"ReplyTimeout","tag":"ReplyTimeout","type":"*variable","value":"~*req.8"},{"path":"TLS","tag":"TLS","type":"*variable","value":"~*req.9"},{"path":"ClientKey","tag":"ClientKey","type":"*variable","value":"~*req.10"},{"path":"ClientCertificate","tag":"ClientCertificate","type":"*variable","value":"~*req.11"},{"path":"CaCertificate","tag":"CaCertificate","type":"*variable","value":"~*req.12"}],"file_name":"DispatcherHosts.csv","flags":null,"type":"*dispatcher_hosts"}],"dry_run":false,"enabled":false,"field_separator":",","id":"*default","lockfile_path":".cgr.lck","run_delay":"0","tenant":"","tp_in_dir":"/var/spool/cgrates/loader/in","tp_out_dir":"/var/spool/cgrates/loader/out"}],"mailer":{"auth_password":"CGRateS.org","auth_user":"cgrates","from_address":"cgr-mailer@localhost.localdomain","server":"localhost"},"migrator":{"out_datadb_encoding":"msgpack","out_datadb_host":"127.0.0.1","out_datadb_name":"10","out_datadb_opts":{"mongoConnScheme":"mongodb","mongoQueryTimeout":"0s","redisCACertificate":"","redisClientCertificate":"","redisClientKey":"","redisCluster":false,"redisClusterOndownDelay":"0s","redisClusterSync":"5s","redisConnectAttempts":20,"redisConnectTimeout":"0s","redisMaxConns":10,"redisPoolPipelineLimit":0,"redisPoolPipelineWindow":"150µs","redisReadTimeout":"0s","redisSentinel":"","redisTLS":false,"redisWriteTimeout":"0s"},"out_datadb_password":"","out_datadb_port":"6379","out_datadb_type":"*redis","out_datadb_user":"cgrates","out_stordb_host":"127.0.0.1","out_stordb_name":"cgrates","out_stordb_opts":{"mongoConnScheme":"mongodb","mongoQueryTimeout":"0s","mysqlDSNParams":null,"mysqlLocation":"","pgSSLMode":"","sqlConnMaxLifetime":"0s","sqlMaxIdleConns":0,"sqlMaxOpenConns":0},"out_stordb_password":"","out_stordb_port":"3306","out_stordb_type":"*mysql","out_stordb_user":"cgrates","users_filters":null},"radius_agent":{"client_dictionaries":{"*default":["/usr/share/cgrates/radius/dict/"]},"client_secrets":{"*default":"CGRateS.org"},"coa_template":"*coa","dmr_template":"*dmr","enabled":false,"listeners":[{"acct_address":"127.0.0.1:1813","auth_address":"127.0.0.1:1812","network":"udp"}],"request_processors":[],"requests_cache_key":"","sessions_conns":["*internal"]},"rals":{"balance_rating_subject":{"*any":"*zero1ns","*voice":"*zero1s"},"enabled":false,"fallback_depth":3,"max_computed_usage":{"*any":"189h0m0s","*data":"107374182400","*mms":"10000","*sms":"10000","*voice":"72h0m0s"},"max_increments":1000000,"remove_expired":true,"rp_subject_prefix_matching":false,"sessions_conns":[],"stats_conns":[],"thresholds_conns":[]},"registrarc":{"dispatchers":{"hosts":[],"refresh_interval":"5m0s","registrars_conns":[]},"rpc":{"hosts":[],"refresh_interval":"5m0s","registrars_conns":[]}},"resources":{"enabled":false,"indexed_selects":true,"nested_fields":false,"opts":{"*units":1,"*usageID":""},"prefix_indexed_fields":[],"store_interval":"","suffix_indexed_fields":[],"thresholds_conns":[]},"routes":{"attributes_conns":[],"default_ratio":1,"enabled":false,"indexed_selects":true,"nested_fields":false,"opts":{"*context":"*routes","*ignoreErrors":false,"*maxCost":""},"prefix_indexed_fields":[],"rals_conns":[],"resources_conns":[],"stats_conns":[],"suffix_indexed_fields":[]},"rpc_conns":{"*bijson_localhost":{"conns":[{"address":"127.0.0.1:2014","transport":"*birpc_json"}],"poolSize":0,"strategy":"*first"},"*birpc_internal":{"conns":[{"address":"*birpc_internal","transport":""}],"poolSize":0,"strategy":"*first"},"*internal":{"conns":[{"address":"*internal","transport":""}],"poolSize":0,"strategy":"*first"},"*localhost":{"conns":[{"address":"127.0.0.1:2012","transport":"*json"}],"poolSize":0,"strategy":"*first"}},"sags":{"enabled":false},"sars":{"enabled":false,"stats_conns":[]},"schedulers":{"cdrs_conns":[],"dynaprepaid_actionplans":[],"enabled":false,"filters":[],"stats_conns":[],"thresholds_conns":[]},"sentrypeer":{"Audience":"https://sentrypeer.com/api","ClientID":"","ClientSecret":"","GrantType":"client_credentials","IpUrl":"https://sentrypeer.com/api/ip-addresses","NumberUrl":"https://sentrypeer.com/api/phone-numbers","TokenURL":"https://authz.sentrypeer.com/oauth/token"},"sessions":{"alterable_fields":[],"attributes_conns":[],"backup_interval":"0","cdrs_conns":[],"channel_sync_interval":"0","chargers_conns":[],"client_protocol":2,"debit_interval":"0","default_usage":{"*any":"3h0m0s","*data":"1048576","*sms":"1","*voice":"3h0m0s"},"enabled":false,"listen_bigob":"","listen_bijson":"127.0.0.1:2014","min_dur_low_balance":"0","rals_conns":[],"replication_conns":[],"resources_conns":[],"routes_conns":[],"scheduler_conns":[],"session_indexes":[],"session_ttl":"0","stale_chan_max_extra_usage":"0","stats_conns":[],"stir":{"allowed_attest":["*any"],"default_attest":"A","payload_maxduration":"-1","privatekey_path":"","publickey_path":""},"store_session_costs":false,"terminate_attempts":5,"thresholds_conns":[]},"sip_agent":{"enabled":false,"listen":"127.0.0.1:5060","listen_net":"udp","request_processors":[],"retransmission_timer":1000000000,"sessions_conns":["*internal"],"timezone":""},"stats":{"enabled":false,"indexed_selects":true,"nested_fields":false,"opts":{"*profileIDs":[],"*profileIgnoreFilters":false},"prefix_indexed_fields":[],"store_interval":"","store_uncompressed_limit":0,"suffix_indexed_fields":[],"thresholds_conns":[]},"stor_db":{"db_host":"127.0.0.1","db_name":"cgrates","db_password":"CGRateS.org","db_port":3306,"db_type":"*mysql","db_user":"cgrates","items":{"*cdrs":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*session_costs":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_account_actions":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_action_plans":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_action_triggers":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_actions":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_attributes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_chargers":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_destination_rates":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_destinations":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_dispatcher_hosts":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_dispatcher_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_filters":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_rates":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_rating_plans":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_rating_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_resources":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_routes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_sags":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_shared_groups":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_stats":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_thresholds":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_timings":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*versions":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false}},"opts":{"mongoConnScheme":"mongodb","mongoQueryTimeout":"10s","mysqlDSNParams":{},"mysqlLocation":"Local","pgSSLMode":"disable","pgSchema":"","sqlConnMaxLifetime":"0s","sqlMaxIdleConns":10,"sqlMaxOpenConns":100},"prefix_indexed_fields":[],"remote_conns":null,"replication_conns":null,"string_indexed_fields":[]},"suretax":{"bill_to_number":"","business_unit":"","client_number":"","client_tracking":"~*req.CGRID","customer_number":"~*req.Subject","include_local_cost":false,"orig_number":"~*req.Subject","p2pplus4":"","p2pzipcode":"","plus4":"","regulatory_code":"03","response_group":"03","response_type":"D4","return_file_code":"0","sales_type_code":"R","tax_exemption_code_list":"","tax_included":"0","tax_situs_rule":"04","term_number":"~*req.Destination","timezone":"UTC","trans_type_code":"010101","unit_type":"00","units":"1","url":"","validation_key":"","zipcode":""},"templates":{"*asr":[{"mandatory":true,"path":"*diamreq.Session-Id","tag":"SessionId","type":"*variable","value":"~*req.Session-Id"},{"mandatory":true,"path":"*diamreq.Origin-Host","tag":"OriginHost","type":"*variable","value":"~*req.Destination-Host"},{"mandatory":true,"path":"*diamreq.Origin-Realm","tag":"OriginRealm","type":"*variable","value":"~*req.Destination-Realm"},{"mandatory":true,"path":"*diamreq.Destination-Realm","tag":"DestinationRealm","type":"*variable","value":"~*req.Origin-Realm"},{"mandatory":true,"path":"*diamreq.Destination-Host","tag":"DestinationHost","type":"*variable","value":"~*req.Origin-Host"},{"mandatory":true,"path":"*diamreq.Auth-Application-Id","tag":"AuthApplicationId","type":"*variable","value":"~*vars.*appid"}],"*cca":[{"mandatory":true,"path":"*rep.Session-Id","tag":"SessionId","type":"*variable","value":"~*req.Session-Id"},{"path":"*rep.Result-Code","tag":"ResultCode","type":"*constant","value":"2001"},{"mandatory":true,"path":"*rep.Origin-Host","tag":"OriginHost","type":"*variable","value":"~*vars.OriginHost"},{"mandatory":true,"path":"*rep.Origin-Realm","tag":"OriginRealm","type":"*variable","value":"~*vars.OriginRealm"},{"mandatory":true,"path":"*rep.Auth-Application-Id","tag":"AuthApplicationId","type":"*variable","value":"~*vars.*appid"},{"mandatory":true,"path":"*rep.CC-Request-Type","tag":"CCRequestType","type":"*variable","value":"~*req.CC-Request-Type"},{"mandatory":true,"path":"*rep.CC-Request-Number","tag":"CCRequestNumber","type":"*variable","value":"~*req.CC-Request-Number"}],"*cdrLog":[{"mandatory":true,"path":"*cdr.ToR","tag":"ToR","type":"*variable","value":"~*req.BalanceType"},{"mandatory":true,"path":"*cdr.OriginHost","tag":"OriginHost","type":"*constant","value":"127.0.0.1"},{"mandatory":true,"path":"*cdr.RequestType","tag":"RequestType","type":"*constant","value":"*none"},{"mandatory":true,"path":"*cdr.Tenant","tag":"Tenant","type":"*variable","value":"~*req.Tenant"},{"mandatory":true,"path":"*cdr.Account","tag":"Account","type":"*variable","value":"~*req.Account"},{"mandatory":true,"path":"*cdr.Subject","tag":"Subject","type":"*variable","value":"~*req.Account"},{"mandatory":true,"path":"*cdr.Cost","tag":"Cost","type":"*variable","value":"~*req.Cost"},{"mandatory":true,"path":"*cdr.Source","tag":"Source","type":"*constant","value":"*cdrLog"},{"mandatory":true,"path":"*cdr.Usage","tag":"Usage","type":"*constant","value":"1"},{"mandatory":true,"path":"*cdr.RunID","tag":"RunID","type":"*variable","value":"~*req.ActionType"},{"mandatory":true,"path":"*cdr.SetupTime","tag":"SetupTime","type":"*constant","value":"*now"},{"mandatory":true,"path":"*cdr.AnswerTime","tag":"AnswerTime","type":"*constant","value":"*now"},{"mandatory":true,"path":"*cdr.PreRated","tag":"PreRated","type":"*constant","value":"true"}],"*coa":[{"path":"*radDAReq.User-Name","tag":"User-Name","type":"*variable","value":"~*oreq.User-Name"},{"path":"*radDAReq.NAS-IP-Address","tag":"NAS-IP-Address","type":"*variable","value":"~*oreq.NAS-IP-Address"},{"path":"*radDAReq.Acct-Session-Id","tag":"Acct-Session-Id","type":"*variable","value":"~*oreq.Acct-Session-Id"},{"path":"*radDAReq.Filter-Id","tag":"Filter-Id","type":"*variable","value":"~*req.CustomFilter"}],"*dmr":[{"path":"*radDAReq.User-Name","tag":"User-Name","type":"*variable","value":"~*oreq.User-Name"},{"path":"*radDAReq.NAS-IP-Address","tag":"NAS-IP-Address","type":"*variable","value":"~*oreq.NAS-IP-Address"},{"path":"*radDAReq.Acct-Session-Id","tag":"Acct-Session-Id","type":"*variable","value":"~*oreq.Acct-Session-Id"},{"path":"*radDAReq.Reply-Message","tag":"Reply-Message","type":"*variable","value":"~*req.DisconnectCause"}],"*err":[{"mandatory":true,"path":"*rep.Session-Id","tag":"SessionId","type":"*variable","value":"~*req.Session-Id"},{"mandatory":true,"path":"*rep.Origin-Host","tag":"OriginHost","type":"*variable","value":"~*vars.OriginHost"},{"mandatory":true,"path":"*rep.Origin-Realm","tag":"OriginRealm","type":"*variable","value":"~*vars.OriginRealm"}],"*errSip":[{"mandatory":true,"path":"*rep.Request","tag":"Request","type":"*constant","value":"SIP/2.0 500 Internal Server Error"}],"*rar":[{"mandatory":true,"path":"*diamreq.Session-Id","tag":"SessionId","type":"*variable","value":"~*req.Session-Id"},{"mandatory":true,"path":"*diamreq.Origin-Host","tag":"OriginHost","type":"*variable","value":"~*req.Destination-Host"},{"mandatory":true,"path":"*diamreq.Origin-Realm","tag":"OriginRealm","type":"*variable","value":"~*req.Destination-Realm"},{"mandatory":true,"path":"*diamreq.Destination-Realm","tag":"DestinationRealm","type":"*variable","value":"~*req.Origin-Realm"},{"mandatory":true,"path":"*diamreq.Destination-Host","tag":"DestinationHost","type":"*variable","value":"~*req.Origin-Host"},{"mandatory":true,"path":"*diamreq.Auth-Application-Id","tag":"AuthApplicationId","type":"*variable","value":"~*vars.*appid"},{"path":"*diamreq.Re-Auth-Request-Type","tag":"ReAuthRequestType","type":"*constant","value":"0"}]},"thresholds":{"enabled":false,"indexed_selects":true,"nested_fields":false,"opts":{"*profileIDs":[],"*profileIgnoreFilters":false},"prefix_indexed_fields":[],"store_interval":"","suffix_indexed_fields":[]},"tls":{"ca_certificate":"","client_certificate":"","client_key":"","server_certificate":"","server_key":"","server_name":"","server_policy":4}}` + expected := `{"analyzers":{"cleanup_interval":"1h0m0s","db_path":"/var/spool/cgrates/analyzers","enabled":false,"index_type":"*scorch","ttl":"24h0m0s"},"apiban":{"keys":[]},"apiers":{"attributes_conns":[],"caches_conns":["*internal"],"ees_conns":[],"enabled":false,"scheduler_conns":[]},"asterisk_agent":{"asterisk_conns":[{"address":"127.0.0.1:8088","alias":"","connect_attempts":3,"max_reconnect_interval":"0s","password":"CGRateS.org","reconnects":5,"user":"cgrates"}],"create_cdr":false,"enabled":false,"sessions_conns":["*birpc_internal"]},"attributes":{"any_context":true,"apiers_conns":[],"enabled":false,"indexed_selects":true,"nested_fields":false,"opts":{"*processRuns":1,"*profileIDs":[],"*profileIgnoreFilters":false,"*profileRuns":0},"prefix_indexed_fields":[],"resources_conns":[],"stats_conns":[],"suffix_indexed_fields":[]},"caches":{"partitions":{"*account_action_plans":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*action_plans":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*action_triggers":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*actions":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*apiban":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false,"ttl":"2m0s"},"*attribute_filter_indexes":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*attribute_profiles":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*caps_events":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*cdr_ids":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false,"ttl":"10m0s"},"*charger_filter_indexes":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*charger_profiles":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*closed_sessions":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false,"ttl":"10s"},"*destinations":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*diameter_messages":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false,"ttl":"3h0m0s"},"*dispatcher_filter_indexes":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*dispatcher_hosts":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*dispatcher_loads":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*dispatcher_profiles":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*dispatcher_routes":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*dispatchers":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*event_charges":{"limit":0,"precache":false,"remote":false,"replicate":false,"static_ttl":false,"ttl":"10s"},"*event_resources":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*filters":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*load_ids":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*radius_packets":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false,"ttl":"3h0m0s"},"*rating_plans":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*rating_profiles":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*replication_hosts":{"limit":0,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*resource_filter_indexes":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*resource_profiles":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*resources":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*reverse_destinations":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*reverse_filter_indexes":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*route_filter_indexes":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*route_profiles":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*rpc_connections":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*rpc_responses":{"limit":0,"precache":false,"remote":false,"replicate":false,"static_ttl":false,"ttl":"2s"},"*sag_profiles":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*sentrypeer":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":true,"ttl":"24h0m0s"},"*shared_groups":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*stat_filter_indexes":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*statqueue_profiles":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*statqueues":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*stir":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false,"ttl":"3h0m0s"},"*threshold_filter_indexes":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*threshold_profiles":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*thresholds":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*timings":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false},"*uch":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false,"ttl":"3h0m0s"}},"remote_conns":[],"replication_conns":[]},"cdrs":{"attributes_conns":[],"chargers_conns":[],"ees_conns":[],"enabled":false,"extra_fields":[],"online_cdr_exports":[],"rals_conns":[],"scheduler_conns":[],"session_cost_retries":5,"stats_conns":[],"store_cdrs":true,"thresholds_conns":[]},"chargers":{"attributes_conns":[],"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"suffix_indexed_fields":[]},"configs":{"enabled":false,"root_dir":"/var/spool/cgrates/configs","url":"/configs/"},"cores":{"caps":0,"caps_stats_interval":"0","caps_strategy":"*busy","shutdown_timeout":"1s"},"data_db":{"db_host":"127.0.0.1","db_name":"10","db_password":"","db_port":6379,"db_type":"*redis","db_user":"cgrates","items":{"*account_action_plans":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*accounts":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*action_plans":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*action_triggers":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*actions":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*attribute_filter_indexes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*attribute_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*charger_filter_indexes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*charger_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*destinations":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*dispatcher_filter_indexes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*dispatcher_hosts":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*dispatcher_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*filters":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*load_ids":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*rating_plans":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*rating_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*resource_filter_indexes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*resource_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*resources":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*reverse_destinations":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*reverse_filter_indexes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*route_filter_indexes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*route_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*sag_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*sessions_backup":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*shared_groups":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*stat_filter_indexes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*statqueue_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*statqueues":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*threshold_filter_indexes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*threshold_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*thresholds":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*timings":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*trend_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*versions":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false}},"opts":{"mongoConnScheme":"mongodb","mongoQueryTimeout":"10s","redisCACertificate":"","redisClientCertificate":"","redisClientKey":"","redisCluster":false,"redisClusterOndownDelay":"0s","redisClusterSync":"5s","redisConnectAttempts":20,"redisConnectTimeout":"0s","redisMaxConns":10,"redisPoolPipelineLimit":0,"redisPoolPipelineWindow":"150µs","redisReadTimeout":"0s","redisSentinel":"","redisTLS":false,"redisWriteTimeout":"0s"},"remote_conn_id":"","remote_conns":[],"replication_cache":"","replication_conns":[],"replication_filtered":false},"diameter_agent":{"asr_template":"","concurrent_requests":-1,"dictionaries_path":"/usr/share/cgrates/diameter/dict/","enabled":false,"forced_disconnect":"*none","listen":"127.0.0.1:3868","listen_net":"tcp","origin_host":"CGR-DA","origin_realm":"cgrates.org","product_name":"CGRateS","rar_template":"","request_processors":[],"sessions_conns":["*birpc_internal"],"synced_conn_requests":false,"vendor_id":0},"dispatchers":{"any_subsystem":true,"attributes_conns":[],"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"prevent_loop":false,"suffix_indexed_fields":[]},"dns_agent":{"enabled":false,"listeners":[{"address":"127.0.0.1:53","network":"udp"}],"request_processors":[],"sessions_conns":["*internal"],"timezone":""},"ees":{"attributes_conns":[],"cache":{"*file_csv":{"limit":-1,"precache":false,"remote":false,"replicate":false,"static_ttl":false,"ttl":"5s"}},"enabled":false,"exporters":[{"attempts":1,"attribute_context":"","attribute_ids":[],"concurrent_requests":0,"export_path":"/var/spool/cgrates/ees","failed_posts_dir":"/var/spool/cgrates/failed_posts","fields":[],"filters":[],"flags":[],"id":"*default","opts":{},"synchronous":false,"timezone":"","type":"*none"}]},"ers":{"concurrent_events":1,"ees_conns":[],"enabled":false,"partial_cache_ttl":"1s","readers":[{"cache_dump_fields":[],"concurrent_requests":1024,"fields":[{"mandatory":true,"path":"*cgreq.ToR","tag":"ToR","type":"*variable","value":"~*req.2"},{"mandatory":true,"path":"*cgreq.OriginID","tag":"OriginID","type":"*variable","value":"~*req.3"},{"mandatory":true,"path":"*cgreq.RequestType","tag":"RequestType","type":"*variable","value":"~*req.4"},{"mandatory":true,"path":"*cgreq.Tenant","tag":"Tenant","type":"*variable","value":"~*req.6"},{"mandatory":true,"path":"*cgreq.Category","tag":"Category","type":"*variable","value":"~*req.7"},{"mandatory":true,"path":"*cgreq.Account","tag":"Account","type":"*variable","value":"~*req.8"},{"mandatory":true,"path":"*cgreq.Subject","tag":"Subject","type":"*variable","value":"~*req.9"},{"mandatory":true,"path":"*cgreq.Destination","tag":"Destination","type":"*variable","value":"~*req.10"},{"mandatory":true,"path":"*cgreq.SetupTime","tag":"SetupTime","type":"*variable","value":"~*req.11"},{"mandatory":true,"path":"*cgreq.AnswerTime","tag":"AnswerTime","type":"*variable","value":"~*req.12"},{"mandatory":true,"path":"*cgreq.Usage","tag":"Usage","type":"*variable","value":"~*req.13"}],"filters":[],"flags":[],"id":"*default","max_reconnect_interval":"5m0s","opts":{"csvFieldSeparator":",","csvHeaderDefineChar":":","csvRowLength":0,"natsSubject":"cgrates_cdrs","partialCacheAction":"*none","partialOrderField":"~*req.AnswerTime"},"partial_commit_fields":[],"processed_path":"/var/spool/cgrates/ers/out","reconnects":-1,"run_delay":"0","source_path":"/var/spool/cgrates/ers/in","tenant":"","timezone":"","type":"*none"}],"sessions_conns":["*internal"]},"filters":{"apiers_conns":[],"resources_conns":[],"stats_conns":[]},"freeswitch_agent":{"active_session_delimiter":",","create_cdr":false,"empty_balance_ann_file":"","empty_balance_context":"","enabled":false,"event_socket_conns":[{"address":"127.0.0.1:8021","alias":"127.0.0.1:8021","max_reconnect_interval":"0s","password":"ClueCon","reconnects":5,"reply_timeout":"1m0s"}],"extra_fields":"","low_balance_ann_file":"","max_wait_connection":"2s","sessions_conns":["*birpc_internal"],"subscribe_park":true},"general":{"caching_delay":"0","connect_attempts":5,"connect_timeout":"1s","dbdata_encoding":"*msgpack","default_caching":"*reload","default_category":"call","default_request_type":"*rated","default_tenant":"cgrates.org","default_timezone":"Local","digest_equal":":","digest_separator":",","failed_posts_dir":"/var/spool/cgrates/failed_posts","failed_posts_ttl":"5s","locking_timeout":"0","log_level":6,"logger":"*syslog","max_parallel_conns":100,"max_reconnect_interval":"0","node_id":"ENGINE1","poster_attempts":3,"reconnects":-1,"reply_timeout":"2s","rounding_decimals":5,"rsr_separator":";","tpexport_dir":"/var/spool/cgrates/tpe"},"http":{"auth_users":{},"client_opts":{"dialFallbackDelay":"300ms","dialKeepAlive":"30s","dialTimeout":"30s","disableCompression":false,"disableKeepAlives":false,"expectContinueTimeout":"0s","forceAttemptHttp2":true,"idleConnTimeout":"1m30s","maxConnsPerHost":0,"maxIdleConns":100,"maxIdleConnsPerHost":2,"responseHeaderTimeout":"0s","skipTlsVerify":false,"tlsHandshakeTimeout":"10s"},"freeswitch_cdrs_url":"/freeswitch_json","http_cdrs":"/cdr_http","json_rpc_url":"/jsonrpc","registrars_url":"/registrar","use_basic_auth":false,"ws_url":"/ws"},"http_agent":[],"kamailio_agent":{"create_cdr":false,"enabled":false,"evapi_conns":[{"address":"127.0.0.1:8448","alias":"","max_reconnect_interval":"0s","reconnects":5}],"sessions_conns":["*birpc_internal"],"timezone":""},"listen":{"http":"127.0.0.1:2080","http_tls":"127.0.0.1:2280","rpc_gob":"127.0.0.1:2013","rpc_gob_tls":"127.0.0.1:2023","rpc_json":"127.0.0.1:2012","rpc_json_tls":"127.0.0.1:2022"},"loader":{"caches_conns":["*localhost"],"data_path":"./","disable_reverse":false,"field_separator":",","gapi_credentials":".gapi/credentials.json","gapi_token":".gapi/token.json","scheduler_conns":["*localhost"],"tpid":""},"loaders":[{"caches_conns":["*internal"],"data":[{"fields":[{"mandatory":true,"path":"Tenant","tag":"TenantID","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ProfileID","type":"*variable","value":"~*req.1"},{"path":"Contexts","tag":"Contexts","type":"*variable","value":"~*req.2"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.3"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.4"},{"path":"AttributeFilterIDs","tag":"AttributeFilterIDs","type":"*variable","value":"~*req.5"},{"path":"Path","tag":"Path","type":"*variable","value":"~*req.6"},{"path":"Type","tag":"Type","type":"*variable","value":"~*req.7"},{"path":"Value","tag":"Value","type":"*variable","value":"~*req.8"},{"path":"Blocker","tag":"Blocker","type":"*variable","value":"~*req.9"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.10"}],"file_name":"Attributes.csv","flags":null,"type":"*attributes"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"Type","tag":"Type","type":"*variable","value":"~*req.2"},{"path":"Element","tag":"Element","type":"*variable","value":"~*req.3"},{"path":"Values","tag":"Values","type":"*variable","value":"~*req.4"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.5"}],"file_name":"Filters.csv","flags":null,"type":"*filters"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.3"},{"path":"UsageTTL","tag":"TTL","type":"*variable","value":"~*req.4"},{"path":"Limit","tag":"Limit","type":"*variable","value":"~*req.5"},{"path":"AllocationMessage","tag":"AllocationMessage","type":"*variable","value":"~*req.6"},{"path":"Blocker","tag":"Blocker","type":"*variable","value":"~*req.7"},{"path":"Stored","tag":"Stored","type":"*variable","value":"~*req.8"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.9"},{"path":"ThresholdIDs","tag":"ThresholdIDs","type":"*variable","value":"~*req.10"}],"file_name":"Resources.csv","flags":null,"type":"*resources"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.3"},{"path":"QueueLength","tag":"QueueLength","type":"*variable","value":"~*req.4"},{"path":"TTL","tag":"TTL","type":"*variable","value":"~*req.5"},{"path":"MinItems","tag":"MinItems","type":"*variable","value":"~*req.6"},{"path":"MetricIDs","tag":"MetricIDs","type":"*variable","value":"~*req.7"},{"path":"MetricFilterIDs","tag":"MetricFilterIDs","type":"*variable","value":"~*req.8"},{"path":"Blocker","tag":"Blocker","type":"*variable","value":"~*req.9"},{"path":"Stored","tag":"Stored","type":"*variable","value":"~*req.10"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.11"},{"path":"ThresholdIDs","tag":"ThresholdIDs","type":"*variable","value":"~*req.12"}],"file_name":"Stats.csv","flags":null,"type":"*stats"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.3"},{"path":"MaxHits","tag":"MaxHits","type":"*variable","value":"~*req.4"},{"path":"MinHits","tag":"MinHits","type":"*variable","value":"~*req.5"},{"path":"MinSleep","tag":"MinSleep","type":"*variable","value":"~*req.6"},{"path":"Blocker","tag":"Blocker","type":"*variable","value":"~*req.7"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.8"},{"path":"ActionIDs","tag":"ActionIDs","type":"*variable","value":"~*req.9"},{"path":"Async","tag":"Async","type":"*variable","value":"~*req.10"}],"file_name":"Thresholds.csv","flags":null,"type":"*thresholds"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.3"},{"path":"Sorting","tag":"Sorting","type":"*variable","value":"~*req.4"},{"path":"SortingParameters","tag":"SortingParameters","type":"*variable","value":"~*req.5"},{"path":"RouteID","tag":"RouteID","type":"*variable","value":"~*req.6"},{"path":"RouteFilterIDs","tag":"RouteFilterIDs","type":"*variable","value":"~*req.7"},{"path":"RouteAccountIDs","tag":"RouteAccountIDs","type":"*variable","value":"~*req.8"},{"path":"RouteRatingPlanIDs","tag":"RouteRatingPlanIDs","type":"*variable","value":"~*req.9"},{"path":"RouteResourceIDs","tag":"RouteResourceIDs","type":"*variable","value":"~*req.10"},{"path":"RouteStatIDs","tag":"RouteStatIDs","type":"*variable","value":"~*req.11"},{"path":"RouteWeight","tag":"RouteWeight","type":"*variable","value":"~*req.12"},{"path":"RouteBlocker","tag":"RouteBlocker","type":"*variable","value":"~*req.13"},{"path":"RouteParameters","tag":"RouteParameters","type":"*variable","value":"~*req.14"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.15"}],"file_name":"Routes.csv","flags":null,"type":"*routes"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.3"},{"path":"RunID","tag":"RunID","type":"*variable","value":"~*req.4"},{"path":"AttributeIDs","tag":"AttributeIDs","type":"*variable","value":"~*req.5"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.6"}],"file_name":"Chargers.csv","flags":null,"type":"*chargers"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"Contexts","tag":"Contexts","type":"*variable","value":"~*req.2"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.3"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.4"},{"path":"Strategy","tag":"Strategy","type":"*variable","value":"~*req.5"},{"path":"StrategyParameters","tag":"StrategyParameters","type":"*variable","value":"~*req.6"},{"path":"ConnID","tag":"ConnID","type":"*variable","value":"~*req.7"},{"path":"ConnFilterIDs","tag":"ConnFilterIDs","type":"*variable","value":"~*req.8"},{"path":"ConnWeight","tag":"ConnWeight","type":"*variable","value":"~*req.9"},{"path":"ConnBlocker","tag":"ConnBlocker","type":"*variable","value":"~*req.10"},{"path":"ConnParameters","tag":"ConnParameters","type":"*variable","value":"~*req.11"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.12"}],"file_name":"DispatcherProfiles.csv","flags":null,"type":"*dispatchers"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"Address","tag":"Address","type":"*variable","value":"~*req.2"},{"path":"Transport","tag":"Transport","type":"*variable","value":"~*req.3"},{"path":"ConnectAttempts","tag":"ConnectAttempts","type":"*variable","value":"~*req.4"},{"path":"Reconnects","tag":"Reconnects","type":"*variable","value":"~*req.5"},{"path":"MaxReconnectInterval","tag":"MaxReconnectInterval","type":"*variable","value":"~*req.6"},{"path":"ConnectTimeout","tag":"ConnectTimeout","type":"*variable","value":"~*req.7"},{"path":"ReplyTimeout","tag":"ReplyTimeout","type":"*variable","value":"~*req.8"},{"path":"TLS","tag":"TLS","type":"*variable","value":"~*req.9"},{"path":"ClientKey","tag":"ClientKey","type":"*variable","value":"~*req.10"},{"path":"ClientCertificate","tag":"ClientCertificate","type":"*variable","value":"~*req.11"},{"path":"CaCertificate","tag":"CaCertificate","type":"*variable","value":"~*req.12"}],"file_name":"DispatcherHosts.csv","flags":null,"type":"*dispatcher_hosts"}],"dry_run":false,"enabled":false,"field_separator":",","id":"*default","lockfile_path":".cgr.lck","run_delay":"0","tenant":"","tp_in_dir":"/var/spool/cgrates/loader/in","tp_out_dir":"/var/spool/cgrates/loader/out"}],"mailer":{"auth_password":"CGRateS.org","auth_user":"cgrates","from_address":"cgr-mailer@localhost.localdomain","server":"localhost"},"migrator":{"out_datadb_encoding":"msgpack","out_datadb_host":"127.0.0.1","out_datadb_name":"10","out_datadb_opts":{"mongoConnScheme":"mongodb","mongoQueryTimeout":"0s","redisCACertificate":"","redisClientCertificate":"","redisClientKey":"","redisCluster":false,"redisClusterOndownDelay":"0s","redisClusterSync":"5s","redisConnectAttempts":20,"redisConnectTimeout":"0s","redisMaxConns":10,"redisPoolPipelineLimit":0,"redisPoolPipelineWindow":"150µs","redisReadTimeout":"0s","redisSentinel":"","redisTLS":false,"redisWriteTimeout":"0s"},"out_datadb_password":"","out_datadb_port":"6379","out_datadb_type":"*redis","out_datadb_user":"cgrates","out_stordb_host":"127.0.0.1","out_stordb_name":"cgrates","out_stordb_opts":{"mongoConnScheme":"mongodb","mongoQueryTimeout":"0s","mysqlDSNParams":null,"mysqlLocation":"","pgSSLMode":"","sqlConnMaxLifetime":"0s","sqlMaxIdleConns":0,"sqlMaxOpenConns":0},"out_stordb_password":"","out_stordb_port":"3306","out_stordb_type":"*mysql","out_stordb_user":"cgrates","users_filters":null},"radius_agent":{"client_dictionaries":{"*default":["/usr/share/cgrates/radius/dict/"]},"client_secrets":{"*default":"CGRateS.org"},"coa_template":"*coa","dmr_template":"*dmr","enabled":false,"listeners":[{"acct_address":"127.0.0.1:1813","auth_address":"127.0.0.1:1812","network":"udp"}],"request_processors":[],"requests_cache_key":"","sessions_conns":["*internal"]},"rals":{"balance_rating_subject":{"*any":"*zero1ns","*voice":"*zero1s"},"enabled":false,"fallback_depth":3,"max_computed_usage":{"*any":"189h0m0s","*data":"107374182400","*mms":"10000","*sms":"10000","*voice":"72h0m0s"},"max_increments":1000000,"remove_expired":true,"rp_subject_prefix_matching":false,"sessions_conns":[],"stats_conns":[],"thresholds_conns":[]},"registrarc":{"dispatchers":{"hosts":[],"refresh_interval":"5m0s","registrars_conns":[]},"rpc":{"hosts":[],"refresh_interval":"5m0s","registrars_conns":[]}},"resources":{"enabled":false,"indexed_selects":true,"nested_fields":false,"opts":{"*units":1,"*usageID":""},"prefix_indexed_fields":[],"store_interval":"","suffix_indexed_fields":[],"thresholds_conns":[]},"routes":{"attributes_conns":[],"default_ratio":1,"enabled":false,"indexed_selects":true,"nested_fields":false,"opts":{"*context":"*routes","*ignoreErrors":false,"*maxCost":""},"prefix_indexed_fields":[],"rals_conns":[],"resources_conns":[],"stats_conns":[],"suffix_indexed_fields":[]},"rpc_conns":{"*bijson_localhost":{"conns":[{"address":"127.0.0.1:2014","transport":"*birpc_json"}],"poolSize":0,"strategy":"*first"},"*birpc_internal":{"conns":[{"address":"*birpc_internal","transport":""}],"poolSize":0,"strategy":"*first"},"*internal":{"conns":[{"address":"*internal","transport":""}],"poolSize":0,"strategy":"*first"},"*localhost":{"conns":[{"address":"127.0.0.1:2012","transport":"*json"}],"poolSize":0,"strategy":"*first"}},"sags":{"enabled":false},"schedulers":{"cdrs_conns":[],"dynaprepaid_actionplans":[],"enabled":false,"filters":[],"stats_conns":[],"thresholds_conns":[]},"sentrypeer":{"Audience":"https://sentrypeer.com/api","ClientID":"","ClientSecret":"","GrantType":"client_credentials","IpUrl":"https://sentrypeer.com/api/ip-addresses","NumberUrl":"https://sentrypeer.com/api/phone-numbers","TokenURL":"https://authz.sentrypeer.com/oauth/token"},"sessions":{"alterable_fields":[],"attributes_conns":[],"backup_interval":"0","cdrs_conns":[],"channel_sync_interval":"0","chargers_conns":[],"client_protocol":2,"debit_interval":"0","default_usage":{"*any":"3h0m0s","*data":"1048576","*sms":"1","*voice":"3h0m0s"},"enabled":false,"listen_bigob":"","listen_bijson":"127.0.0.1:2014","min_dur_low_balance":"0","rals_conns":[],"replication_conns":[],"resources_conns":[],"routes_conns":[],"scheduler_conns":[],"session_indexes":[],"session_ttl":"0","stale_chan_max_extra_usage":"0","stats_conns":[],"stir":{"allowed_attest":["*any"],"default_attest":"A","payload_maxduration":"-1","privatekey_path":"","publickey_path":""},"store_session_costs":false,"terminate_attempts":5,"thresholds_conns":[]},"sip_agent":{"enabled":false,"listen":"127.0.0.1:5060","listen_net":"udp","request_processors":[],"retransmission_timer":1000000000,"sessions_conns":["*internal"],"timezone":""},"stats":{"enabled":false,"indexed_selects":true,"nested_fields":false,"opts":{"*profileIDs":[],"*profileIgnoreFilters":false},"prefix_indexed_fields":[],"store_interval":"","store_uncompressed_limit":0,"suffix_indexed_fields":[],"thresholds_conns":[]},"stor_db":{"db_host":"127.0.0.1","db_name":"cgrates","db_password":"CGRateS.org","db_port":3306,"db_type":"*mysql","db_user":"cgrates","items":{"*cdrs":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*session_costs":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_account_actions":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_action_plans":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_action_triggers":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_actions":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_attributes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_chargers":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_destination_rates":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_destinations":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_dispatcher_hosts":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_dispatcher_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_filters":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_rates":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_rating_plans":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_rating_profiles":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_resources":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_routes":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_sags":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_shared_groups":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_stats":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_thresholds":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_timings":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*tp_trends":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false},"*versions":{"limit":-1,"remote":false,"replicate":false,"static_ttl":false}},"opts":{"mongoConnScheme":"mongodb","mongoQueryTimeout":"10s","mysqlDSNParams":{},"mysqlLocation":"Local","pgSSLMode":"disable","pgSchema":"","sqlConnMaxLifetime":"0s","sqlMaxIdleConns":10,"sqlMaxOpenConns":100},"prefix_indexed_fields":[],"remote_conns":null,"replication_conns":null,"string_indexed_fields":[]},"suretax":{"bill_to_number":"","business_unit":"","client_number":"","client_tracking":"~*req.CGRID","customer_number":"~*req.Subject","include_local_cost":false,"orig_number":"~*req.Subject","p2pplus4":"","p2pzipcode":"","plus4":"","regulatory_code":"03","response_group":"03","response_type":"D4","return_file_code":"0","sales_type_code":"R","tax_exemption_code_list":"","tax_included":"0","tax_situs_rule":"04","term_number":"~*req.Destination","timezone":"UTC","trans_type_code":"010101","unit_type":"00","units":"1","url":"","validation_key":"","zipcode":""},"templates":{"*asr":[{"mandatory":true,"path":"*diamreq.Session-Id","tag":"SessionId","type":"*variable","value":"~*req.Session-Id"},{"mandatory":true,"path":"*diamreq.Origin-Host","tag":"OriginHost","type":"*variable","value":"~*req.Destination-Host"},{"mandatory":true,"path":"*diamreq.Origin-Realm","tag":"OriginRealm","type":"*variable","value":"~*req.Destination-Realm"},{"mandatory":true,"path":"*diamreq.Destination-Realm","tag":"DestinationRealm","type":"*variable","value":"~*req.Origin-Realm"},{"mandatory":true,"path":"*diamreq.Destination-Host","tag":"DestinationHost","type":"*variable","value":"~*req.Origin-Host"},{"mandatory":true,"path":"*diamreq.Auth-Application-Id","tag":"AuthApplicationId","type":"*variable","value":"~*vars.*appid"}],"*cca":[{"mandatory":true,"path":"*rep.Session-Id","tag":"SessionId","type":"*variable","value":"~*req.Session-Id"},{"path":"*rep.Result-Code","tag":"ResultCode","type":"*constant","value":"2001"},{"mandatory":true,"path":"*rep.Origin-Host","tag":"OriginHost","type":"*variable","value":"~*vars.OriginHost"},{"mandatory":true,"path":"*rep.Origin-Realm","tag":"OriginRealm","type":"*variable","value":"~*vars.OriginRealm"},{"mandatory":true,"path":"*rep.Auth-Application-Id","tag":"AuthApplicationId","type":"*variable","value":"~*vars.*appid"},{"mandatory":true,"path":"*rep.CC-Request-Type","tag":"CCRequestType","type":"*variable","value":"~*req.CC-Request-Type"},{"mandatory":true,"path":"*rep.CC-Request-Number","tag":"CCRequestNumber","type":"*variable","value":"~*req.CC-Request-Number"}],"*cdrLog":[{"mandatory":true,"path":"*cdr.ToR","tag":"ToR","type":"*variable","value":"~*req.BalanceType"},{"mandatory":true,"path":"*cdr.OriginHost","tag":"OriginHost","type":"*constant","value":"127.0.0.1"},{"mandatory":true,"path":"*cdr.RequestType","tag":"RequestType","type":"*constant","value":"*none"},{"mandatory":true,"path":"*cdr.Tenant","tag":"Tenant","type":"*variable","value":"~*req.Tenant"},{"mandatory":true,"path":"*cdr.Account","tag":"Account","type":"*variable","value":"~*req.Account"},{"mandatory":true,"path":"*cdr.Subject","tag":"Subject","type":"*variable","value":"~*req.Account"},{"mandatory":true,"path":"*cdr.Cost","tag":"Cost","type":"*variable","value":"~*req.Cost"},{"mandatory":true,"path":"*cdr.Source","tag":"Source","type":"*constant","value":"*cdrLog"},{"mandatory":true,"path":"*cdr.Usage","tag":"Usage","type":"*constant","value":"1"},{"mandatory":true,"path":"*cdr.RunID","tag":"RunID","type":"*variable","value":"~*req.ActionType"},{"mandatory":true,"path":"*cdr.SetupTime","tag":"SetupTime","type":"*constant","value":"*now"},{"mandatory":true,"path":"*cdr.AnswerTime","tag":"AnswerTime","type":"*constant","value":"*now"},{"mandatory":true,"path":"*cdr.PreRated","tag":"PreRated","type":"*constant","value":"true"}],"*coa":[{"path":"*radDAReq.User-Name","tag":"User-Name","type":"*variable","value":"~*oreq.User-Name"},{"path":"*radDAReq.NAS-IP-Address","tag":"NAS-IP-Address","type":"*variable","value":"~*oreq.NAS-IP-Address"},{"path":"*radDAReq.Acct-Session-Id","tag":"Acct-Session-Id","type":"*variable","value":"~*oreq.Acct-Session-Id"},{"path":"*radDAReq.Filter-Id","tag":"Filter-Id","type":"*variable","value":"~*req.CustomFilter"}],"*dmr":[{"path":"*radDAReq.User-Name","tag":"User-Name","type":"*variable","value":"~*oreq.User-Name"},{"path":"*radDAReq.NAS-IP-Address","tag":"NAS-IP-Address","type":"*variable","value":"~*oreq.NAS-IP-Address"},{"path":"*radDAReq.Acct-Session-Id","tag":"Acct-Session-Id","type":"*variable","value":"~*oreq.Acct-Session-Id"},{"path":"*radDAReq.Reply-Message","tag":"Reply-Message","type":"*variable","value":"~*req.DisconnectCause"}],"*err":[{"mandatory":true,"path":"*rep.Session-Id","tag":"SessionId","type":"*variable","value":"~*req.Session-Id"},{"mandatory":true,"path":"*rep.Origin-Host","tag":"OriginHost","type":"*variable","value":"~*vars.OriginHost"},{"mandatory":true,"path":"*rep.Origin-Realm","tag":"OriginRealm","type":"*variable","value":"~*vars.OriginRealm"}],"*errSip":[{"mandatory":true,"path":"*rep.Request","tag":"Request","type":"*constant","value":"SIP/2.0 500 Internal Server Error"}],"*rar":[{"mandatory":true,"path":"*diamreq.Session-Id","tag":"SessionId","type":"*variable","value":"~*req.Session-Id"},{"mandatory":true,"path":"*diamreq.Origin-Host","tag":"OriginHost","type":"*variable","value":"~*req.Destination-Host"},{"mandatory":true,"path":"*diamreq.Origin-Realm","tag":"OriginRealm","type":"*variable","value":"~*req.Destination-Realm"},{"mandatory":true,"path":"*diamreq.Destination-Realm","tag":"DestinationRealm","type":"*variable","value":"~*req.Origin-Realm"},{"mandatory":true,"path":"*diamreq.Destination-Host","tag":"DestinationHost","type":"*variable","value":"~*req.Origin-Host"},{"mandatory":true,"path":"*diamreq.Auth-Application-Id","tag":"AuthApplicationId","type":"*variable","value":"~*vars.*appid"},{"path":"*diamreq.Re-Auth-Request-Type","tag":"ReAuthRequestType","type":"*constant","value":"0"}]},"thresholds":{"enabled":false,"indexed_selects":true,"nested_fields":false,"opts":{"*profileIDs":[],"*profileIgnoreFilters":false},"prefix_indexed_fields":[],"store_interval":"","suffix_indexed_fields":[]},"tls":{"ca_certificate":"","client_certificate":"","client_key":"","server_certificate":"","server_key":"","server_name":"","server_policy":4},"trends":{"enabled":false,"stats_conns":[]}}` if err != nil { t.Fatal(err) } @@ -5977,13 +5977,13 @@ func TestCgrCfgJSONDefaultSagSCfg(t *testing.T) { } } -func TestCgrCfgJSONDefaultSarSCfg(t *testing.T) { - want := &SarSCfg{ +func TestCgrCfgJSONDefaultTrendSCfg(t *testing.T) { + want := &TrendSCfg{ Enabled: false, StatSConns: []string{}, ThresholdSConns: []string{}, } - got := cgrCfg.SarSCfg() + got := cgrCfg.TrendSCfg() if reflect.DeepEqual(got, want) { t.Errorf("received: %+v, expecting: %+v", got, want) } @@ -6013,11 +6013,11 @@ func TestV1GetConfigAsJSONJanusAgentJson(t *testing.T) { } } -func TestV1GetConfigAsJsonSARS_JSON(t *testing.T) { +func TestV1GetConfigAsJsonTrendS_JSON(t *testing.T) { var reply string - expected := `{"sars":{"enabled":false,"stats_conns":[]}}` + expected := `{"trends":{"enabled":false,"stats_conns":[]}}` cfgCgr := NewDefaultCGRConfig() - if err := cfgCgr.V1GetConfigAsJSON(context.Background(), &SectionWithAPIOpts{Section: SARS_JSON}, &reply); err != nil { + if err := cfgCgr.V1GetConfigAsJSON(context.Background(), &SectionWithAPIOpts{Section: TRENDS_JSON}, &reply); err != nil { t.Error(err) } else if expected != reply { t.Errorf("Expected %+v \n, received %+v", expected, reply) @@ -6035,16 +6035,16 @@ func TestV1GetConfigAsJsonSAGS_JSON(t *testing.T) { } } -func TestV1GetConfigSARS_JSON(t *testing.T) { +func TestV1GetConfigTRENDS_JSON(t *testing.T) { var reply map[string]any expected := map[string]any{ - SARS_JSON: map[string]any{ + TRENDS_JSON: map[string]any{ utils.EnabledCfg: false, utils.StatSConnsCfg: []string{}, }, } cfgCgr := NewDefaultCGRConfig() - if err := cfgCgr.V1GetConfig(context.Background(), &SectionWithAPIOpts{Section: SARS_JSON}, &reply); err != nil { + if err := cfgCgr.V1GetConfig(context.Background(), &SectionWithAPIOpts{Section: TRENDS_JSON}, &reply); err != nil { t.Error(err) } else if !reflect.DeepEqual(reply, expected) { t.Errorf("Expected %+v \n, received %+v", utils.ToJSON(expected), utils.ToJSON(reply)) diff --git a/config/configsanity.go b/config/configsanity.go index 275ed91ce..4572a1a3f 100644 --- a/config/configsanity.go +++ b/config/configsanity.go @@ -628,14 +628,14 @@ func (cfg *CGRConfig) checkConfigSanity() error { } } } - //SarS checks - if cfg.sarsCfg.Enabled { - for _, connID := range cfg.sarsCfg.StatSConns { + //TrendS checks + if cfg.trendsCfg.Enabled { + for _, connID := range cfg.trendsCfg.StatSConns { if strings.HasPrefix(connID, utils.MetaInternal) && !cfg.statsCfg.Enabled { - return fmt.Errorf("<%s> not enabled but requested by <%s> component", utils.StatS, utils.SarS) + return fmt.Errorf("<%s> not enabled but requested by <%s> component", utils.StatS, utils.TrendS) } if _, has := cfg.rpcConns[connID]; !has && !strings.HasPrefix(connID, utils.MetaInternal) { - return fmt.Errorf("<%s> connection with id: <%s> not defined", utils.SarS, connID) + return fmt.Errorf("<%s> connection with id: <%s> not defined", utils.TrendS, connID) } } } diff --git a/config/libconfig_json.go b/config/libconfig_json.go index b2edd803a..131ef900b 100644 --- a/config/libconfig_json.go +++ b/config/libconfig_json.go @@ -668,7 +668,7 @@ type StatServJsonCfg struct { Opts *StatsOptsJson } -type SarsJsonCfg struct { +type TrendsJsonCfg struct { Enabled *bool Stats_conns *[]string Thresholds_conns *[]string diff --git a/config/sarscfg.go b/config/trendscfg.go similarity index 91% rename from config/sarscfg.go rename to config/trendscfg.go index 156df5176..5b1b244cf 100644 --- a/config/sarscfg.go +++ b/config/trendscfg.go @@ -20,13 +20,13 @@ package config import "github.com/cgrates/cgrates/utils" -type SarSCfg struct { +type TrendSCfg struct { Enabled bool StatSConns []string ThresholdSConns []string } -func (sa *SarSCfg) loadFromJSONCfg(jsnCfg *SarsJsonCfg) (err error) { +func (sa *TrendSCfg) loadFromJSONCfg(jsnCfg *TrendsJsonCfg) (err error) { if jsnCfg == nil { return } @@ -54,7 +54,7 @@ func (sa *SarSCfg) loadFromJSONCfg(jsnCfg *SarsJsonCfg) (err error) { return } -func (sa *SarSCfg) AsMapInterface() (initialMP map[string]any) { +func (sa *TrendSCfg) AsMapInterface() (initialMP map[string]any) { initialMP = map[string]any{ utils.EnabledCfg: sa.Enabled, } @@ -81,8 +81,8 @@ func (sa *SarSCfg) AsMapInterface() (initialMP map[string]any) { return } -func (sa *SarSCfg) Clone() (cln *SarSCfg) { - cln = &SarSCfg{ +func (sa *TrendSCfg) Clone() (cln *TrendSCfg) { + cln = &TrendSCfg{ Enabled: sa.Enabled, } if sa.StatSConns != nil { diff --git a/data/storage/mysql/create_tariffplan_tables.sql b/data/storage/mysql/create_tariffplan_tables.sql index fbdf9d0c3..136ecbf1c 100644 --- a/data/storage/mysql/create_tariffplan_tables.sql +++ b/data/storage/mysql/create_tariffplan_tables.sql @@ -318,11 +318,11 @@ CREATE TABLE tp_sags( ); -- --- Table structure for tabls `tp_sars` +-- Table structure for tabls `tp_trends` -- -DROP TABLE IF EXISTS tp_sars; -CREATE TABLE tp_sars( +DROP TABLE IF EXISTS tp_trends; +CREATE TABLE tp_trends( `pk` int(11) NOT NULL AUTO_INCREMENT, `tpid` varchar(64) NOT NULL, `tenant` varchar(64) NOT NULL, @@ -337,7 +337,7 @@ CREATE TABLE tp_sars( `created_at` TIMESTAMP, PRIMARY KEY (`pk`), KEY `tpid` (`tpid`), - UNIQUE KEY `unique_tp_sars` (`tpid`,`tenant`,`id`,`stat_id`) + UNIQUE KEY `unique_tp_trends` (`tpid`,`tenant`,`id`,`stat_id`) ); diff --git a/data/storage/postgres/create_tariffplan_tables.sql b/data/storage/postgres/create_tariffplan_tables.sql index 06cdd06d4..037d4fe1c 100644 --- a/data/storage/postgres/create_tariffplan_tables.sql +++ b/data/storage/postgres/create_tariffplan_tables.sql @@ -311,11 +311,11 @@ CREATE INDEX tp_sags_idx ON tp_sags (tpid); CREATE INDEX tp_sags_unique ON tp_sags ("tpid","tenant", "id","stat_ids"); -- --- Table structure for tabls `tp_sars` +-- Table structure for tabls `tp_trends` -- -DROP TABLE IF EXISTS tp_sars; -CREATE TABLE tp_sars( +DROP TABLE IF EXISTS tp_trends; +CREATE TABLE tp_trends( "pk" SERIAL PRIMARY KEY, "tpid" varchar(64) NOT NULL, "tenant" varchar(64) NOT NULL, @@ -329,8 +329,8 @@ CREATE TABLE tp_sars( "threshold_ids" varchar(64) NOT NULL, "created_at" TIMESTAMP ); - CREATE INDEX tp_sars_idx ON tp_sars(tpid); - CREATE INDEX tp_sars_unique ON tp_sars("tpid","tenant","id","stat_id"); + CREATE INDEX tp_trends_idx ON tp_trends(tpid); + CREATE INDEX tp_trends_unique ON tp_trends("tpid","tenant","id","stat_id"); -- -- Table structure for table `tp_threshold_cfgs` diff --git a/engine/datadbmock.go b/engine/datadbmock.go index ac4ca1c49..fcd7b3b4e 100644 --- a/engine/datadbmock.go +++ b/engine/datadbmock.go @@ -41,9 +41,9 @@ type DataDBMock struct { SetSagProfileDrvF func(sq *SagProfile) (err error) GetSagProfileDrvF func(tenant string, id string) (sq *SagProfile, err error) RemSagProfileDrvF func(tenant string, id string) (err error) - SetSarProfileDrvF func(sq *SarProfile) (err error) - GetSarProfileDrvF func(tenant string, id string) (sq *SarProfile, err error) - RemSarProfileDrvF func(tenant string, id string) (err error) + SetTrendProfileDrvF func(sq *TrendProfile) (err error) + GetTrendProfileDrvF func(tenant string, id string) (sq *TrendProfile, err error) + RemTrendProfileDrvF func(tenant string, id string) (err error) GetSagsProfileDrvF func(tenant, id string) (sg *SagProfile, err error) GetActionPlanDrvF func(key string) (ap *ActionPlan, err error) SetActionPlanDrvF func(key string, ap *ActionPlan) (err error) @@ -357,23 +357,23 @@ func (dbM *DataDBMock) RemSagProfileDrv(tenant string, id string) (err error) { } return utils.ErrNotImplemented } -func (dbM *DataDBMock) GetSarProfileDrv(tenant, id string) (sg *SarProfile, err error) { +func (dbM *DataDBMock) GetTrendProfileDrv(tenant, id string) (sg *TrendProfile, err error) { if dbM.GetStatQueueProfileDrvF != nil { - return dbM.GetSarProfileDrvF(tenant, id) + return dbM.GetTrendProfileDrvF(tenant, id) } return nil, utils.ErrNotImplemented } -func (dbM *DataDBMock) SetSarProfileDrv(sar *SarProfile) (err error) { - if dbM.SetSarProfileDrvF(sar) != nil { - return dbM.SetSarProfileDrvF(sar) +func (dbM *DataDBMock) SetTrendProfileDrv(trend *TrendProfile) (err error) { + if dbM.SetTrendProfileDrvF(trend) != nil { + return dbM.SetTrendProfileDrvF(trend) } return utils.ErrNotImplemented } -func (dbM *DataDBMock) RemSarProfileDrv(tenant string, id string) (err error) { - if dbM.RemSarProfileDrvF != nil { - return dbM.RemSarProfileDrvF(tenant, id) +func (dbM *DataDBMock) RemTrendProfileDrv(tenant string, id string) (err error) { + if dbM.RemTrendProfileDrvF != nil { + return dbM.RemTrendProfileDrvF(tenant, id) } return utils.ErrNotImplemented } diff --git a/engine/datamanager.go b/engine/datamanager.go index b1c911c73..66c21558e 100644 --- a/engine/datamanager.go +++ b/engine/datamanager.go @@ -78,6 +78,7 @@ var ( utils.FilterIndexPrfx: {}, utils.MetaAPIBan: {}, // not realy a prefix as this is not stored in DB utils.MetaNotSentryPeer: {}, + utils.TrendsProfilePrefix: {}, } ) @@ -1286,62 +1287,62 @@ func (dm *DataManager) RemoveStatQueueProfile(tenant, id string, withIndex bool) return dm.RemoveStatQueue(tenant, id) } -func (dm *DataManager) GetSarProfile(tenant, id string) (srp *SarProfile, err error) { +func (dm *DataManager) GetTrendProfile(tenant, id string) (srp *TrendProfile, err error) { if dm == nil { err = utils.ErrNoDatabaseConn return } - srp, err = dm.dataDB.GetSarProfileDrv(tenant, id) + srp, err = dm.dataDB.GetTrendProfileDrv(tenant, id) if err != nil { - if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaSarProfiles]; err == utils.ErrNotFound && itm.Remote { + if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaTrendProfiles]; err == utils.ErrNotFound && itm.Remote { if err = dm.connMgr.Call(context.TODO(), config.CgrConfig().DataDbCfg().RmtConns, - utils.ReplicatorSv1GetSarProfile, + utils.ReplicatorSv1GetTrendProfile, &utils.TenantIDWithAPIOpts{ TenantID: &utils.TenantID{Tenant: tenant, ID: id}, APIOpts: utils.GenerateDBItemOpts(itm.APIKey, itm.RouteID, utils.EmptyString, utils.FirstNonEmpty(config.CgrConfig().DataDbCfg().RmtConnID, config.CgrConfig().GeneralCfg().NodeID)), }, &srp); err == nil { - err = dm.dataDB.SetSarProfileDrv(srp) + err = dm.dataDB.SetTrendProfileDrv(srp) } } } return } -func (dm *DataManager) SetSarProfile(srp *SarProfile) (err error) { - if err = dm.DataDB().SetSarProfileDrv(srp); err != nil { +func (dm *DataManager) SetTrendProfile(srp *TrendProfile) (err error) { + if err = dm.DataDB().SetTrendProfileDrv(srp); err != nil { return } - if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaSarProfiles]; itm.Replicate { + if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaTrendProfiles]; itm.Replicate { err = replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, config.CgrConfig().DataDbCfg().RplFiltered, - utils.SarsProfilePrefix, srp.TenantID(), - utils.ReplicatorSv1SetSarProfile, - &SarProfileWithAPIOpts{ - SarProfile: srp, + utils.TrendsProfilePrefix, srp.TenantID(), + utils.ReplicatorSv1SetTrendProfile, + &TrendProfileWithAPIOpts{ + TrendProfile: srp, APIOpts: utils.GenerateDBItemOpts(itm.APIKey, itm.RouteID, config.CgrConfig().DataDbCfg().RplCache, utils.EmptyString)}) } return } -func (dm *DataManager) RemoveSarProfile(tenant, id string) (err error) { - oldSgs, err := dm.GetSarProfile(tenant, id) +func (dm *DataManager) RemoveTrendProfile(tenant, id string) (err error) { + oldSgs, err := dm.GetTrendProfile(tenant, id) if err != nil && err != utils.ErrNotFound { return err } - if err = dm.DataDB().RemSarProfileDrv(tenant, id); err != nil { + if err = dm.DataDB().RemTrendProfileDrv(tenant, id); err != nil { return } if oldSgs == nil { return utils.ErrNotFound } - if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaSarProfiles]; itm.Replicate { + if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaSagProfiles]; itm.Replicate { replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, config.CgrConfig().DataDbCfg().RplFiltered, - utils.SarsProfilePrefix, utils.ConcatenatedKey(tenant, id), // this are used to get the host IDs from cache - utils.ReplicatorSv1RemoveSarProfile, + utils.TrendsProfilePrefix, utils.ConcatenatedKey(tenant, id), // this are used to get the host IDs from cache + utils.ReplicatorSv1RemoveTrendProfile, &utils.TenantIDWithAPIOpts{ TenantID: &utils.TenantID{Tenant: tenant, ID: id}, APIOpts: utils.GenerateDBItemOpts(itm.APIKey, itm.RouteID, diff --git a/engine/libtest.go b/engine/libtest.go index d04424556..5610b992b 100644 --- a/engine/libtest.go +++ b/engine/libtest.go @@ -246,9 +246,9 @@ cgrates.org,TestStats2,,,,,2,*sum#~*req.Cost;*average#~*req.Cost,,true,true,20, #Tenant[0],Id[1],QueryInterval[2],StatIDs[2],MetricIDs[3],Sorting[4],SortingParameters[5],ThresholdIDs[6] cgrates.org,SAGS1,15m,Stats2;Stats3;Stats4,Metric1;Metric3,*asc,,THD1;THD2 ` - SarsCSVContent = ` + TrendsCSVContent = ` #Tenant[0],Id[1],QueryInterval[2],StatID[3],QueueLength[4],TTL[5],PurgeFilterIDs[6],Trend[7],ThresholdIDs[7] -cgrates.org,SARS1,5m,Stats2,-1,-1,,*average,TD1;THD2 +cgrates.org,TRENDS1,5m,Stats2,-1,-1,,*average,TD1;THD2 ` ThresholdsCSVContent = ` #Tenant[0],Id[1],FilterIDs[2],ActivationInterval[3],MaxHits[4],MinHits[5],MinSleep[6],Blocker[7],Weight[8],ActionIDs[9],Async[10] diff --git a/engine/libsars.go b/engine/libtrends.go similarity index 89% rename from engine/libsars.go rename to engine/libtrends.go index fb01fd398..dff19e20b 100644 --- a/engine/libsars.go +++ b/engine/libtrends.go @@ -24,7 +24,7 @@ import ( "github.com/cgrates/cgrates/utils" ) -type SarProfile struct { +type TrendProfile struct { Tenant string ID string QueryInterval time.Duration @@ -36,11 +36,11 @@ type SarProfile struct { ThresholdIDs []string } -type SarProfileWithAPIOpts struct { - *SarProfile +type TrendProfileWithAPIOpts struct { + *TrendProfile APIOpts map[string]any } -func (srp *SarProfile) TenantID() string { +func (srp *TrendProfile) TenantID() string { return utils.ConcatenatedKey(srp.Tenant, srp.ID) } diff --git a/engine/loader_csv_test.go b/engine/loader_csv_test.go index 13537ce54..55e947d1d 100644 --- a/engine/loader_csv_test.go +++ b/engine/loader_csv_test.go @@ -42,7 +42,7 @@ func init() { DestinationsCSVContent, TimingsCSVContent, RatesCSVContent, DestinationRatesCSVContent, RatingPlansCSVContent, RatingProfilesCSVContent, SharedGroupsCSVContent, ActionsCSVContent, ActionPlansCSVContent, ActionTriggersCSVContent, AccountActionsCSVContent, - ResourcesCSVContent, StatsCSVContent, SarsCSVContent, SagsCSVContent, ThresholdsCSVContent, FiltersCSVContent, + ResourcesCSVContent, StatsCSVContent, TrendsCSVContent, SagsCSVContent, ThresholdsCSVContent, FiltersCSVContent, RoutesCSVContent, AttributesCSVContent, ChargersCSVContent, DispatcherCSVContent, DispatcherHostCSVContent), testTPID, "", nil, nil, false) if err != nil { diff --git a/engine/model_helpers.go b/engine/model_helpers.go index 18065a93c..823d87da6 100644 --- a/engine/model_helpers.go +++ b/engine/model_helpers.go @@ -1640,22 +1640,22 @@ func SagProfileToAPI(sg *SagProfile) (tpSG *utils.TPSagsProfile) { return } -type SarsMdls []*SarsMdl +type TrendsMdls []*TrendsMdl -func (tps SarsMdls) CSVHeader() (result []string) { +func (tps TrendsMdls) CSVHeader() (result []string) { return []string{"#" + utils.Tenant, utils.ID, utils.QueryInterval, utils.StatID, utils.TTL, utils.PurgeFilterIDs, utils.Trend, utils.ThresholdIDs} } -func (models SarsMdls) AsTPSars() (result []*utils.TPSarsProfile) { +func (models TrendsMdls) AsTPTrends() (result []*utils.TPTrendsProfile) { thresholdsMap := make(map[string]utils.StringSet) purgeFiltersIDsMap := make(map[string]utils.StringSet) - msr := make(map[string]*utils.TPSarsProfile) + msr := make(map[string]*utils.TPTrendsProfile) for _, model := range models { key := &utils.TenantID{Tenant: model.Tenant, ID: model.ID} sr, found := msr[key.TenantID()] if !found { - sr = &utils.TPSarsProfile{ + sr = &utils.TPTrendsProfile{ Tenant: model.Tenant, TPid: model.Tpid, ID: model.ID, @@ -1695,7 +1695,7 @@ func (models SarsMdls) AsTPSars() (result []*utils.TPSarsProfile) { } msr[key.TenantID()] = sr } - result = make([]*utils.TPSarsProfile, len(msr)) + result = make([]*utils.TPTrendsProfile, len(msr)) i := 0 for tntId, sr := range msr { result[i] = sr @@ -1706,12 +1706,12 @@ func (models SarsMdls) AsTPSars() (result []*utils.TPSarsProfile) { return } -func APItoModelSars(tpSR *utils.TPSarsProfile) (mdls SarsMdls) { +func APItoModelTrends(tpSR *utils.TPTrendsProfile) (mdls TrendsMdls) { if tpSR == nil { return } if len(tpSR.PurgeFilterIDs) == 0 { - mdl := &SarsMdl{ + mdl := &TrendsMdl{ Tpid: tpSR.TPid, Tenant: tpSR.Tenant, ID: tpSR.ID, @@ -1729,7 +1729,7 @@ func APItoModelSars(tpSR *utils.TPSarsProfile) (mdls SarsMdls) { mdls = append(mdls, mdl) } for i, filterID := range tpSR.PurgeFilterIDs { - mdl := &SarsMdl{ + mdl := &TrendsMdl{ Tpid: tpSR.TPid, Tenant: tpSR.Tenant, ID: tpSR.ID, @@ -1753,8 +1753,8 @@ func APItoModelSars(tpSR *utils.TPSarsProfile) (mdls SarsMdls) { return } -func APItoSars(tpSR *utils.TPSarsProfile) (sr *SarProfile, err error) { - sr = &SarProfile{ +func APItoTrends(tpSR *utils.TPTrendsProfile) (sr *TrendProfile, err error) { + sr = &TrendProfile{ Tenant: tpSR.Tenant, ID: tpSR.ID, StatID: tpSR.StatID, @@ -1778,8 +1778,8 @@ func APItoSars(tpSR *utils.TPSarsProfile) (sr *SarProfile, err error) { return } -func SarProfileToAPI(sr *SarProfile) (tpSR *utils.TPSarsProfile) { - tpSR = &utils.TPSarsProfile{ +func TrendProfileToAPI(sr *TrendProfile) (tpSR *utils.TPTrendsProfile) { + tpSR = &utils.TPTrendsProfile{ Tenant: sr.Tenant, ID: sr.ID, PurgeFilterIDs: make([]string, len(sr.PurgeFilterIDs)), diff --git a/engine/models.go b/engine/models.go index 85b4b3219..e40221018 100644 --- a/engine/models.go +++ b/engine/models.go @@ -301,7 +301,7 @@ func (SagsMdl) TableName() string { return utils.TBLTPSags } -type SarsMdl struct { +type TrendsMdl struct { PK uint `gorm:"primary_key"` Tpid string Tenant string `index:"0" re:".*"` @@ -316,8 +316,8 @@ type SarsMdl struct { CreatedAt time.Time } -func (SarsMdl) TableName() string { - return utils.TBLTPSars +func (TrendsMdl) TableName() string { + return utils.TBLTPTrends } type ThresholdMdl struct { diff --git a/engine/storage_csv.go b/engine/storage_csv.go index 9500e4d62..f7cbec79a 100644 --- a/engine/storage_csv.go +++ b/engine/storage_csv.go @@ -58,7 +58,7 @@ type CSVStorage struct { accountactionsFn []string resProfilesFn []string statsFn []string - sarsFn []string + trendsFn []string sagsFn []string thresholdsFn []string filterFn []string @@ -74,7 +74,7 @@ func NewCSVStorage(sep rune, destinationsFn, timingsFn, ratesFn, destinationratesFn, destinationratetimingsFn, ratingprofilesFn, sharedgroupsFn, actionsFn, actiontimingsFn, actiontriggersFn, accountactionsFn, - resProfilesFn, statsFn, sarsFn, sagsFn, thresholdsFn, filterFn, routeProfilesFn, + resProfilesFn, statsFn, trendsFn, sagsFn, thresholdsFn, filterFn, routeProfilesFn, attributeProfilesFn, chargerProfilesFn, dispatcherProfilesFn, dispatcherHostsFn []string) *CSVStorage { return &CSVStorage{ sep: sep, @@ -92,7 +92,7 @@ func NewCSVStorage(sep rune, accountactionsFn: accountactionsFn, resProfilesFn: resProfilesFn, statsFn: statsFn, - sarsFn: sarsFn, + trendsFn: trendsFn, sagsFn: sagsFn, thresholdsFn: thresholdsFn, filterFn: filterFn, @@ -123,7 +123,7 @@ func NewFileCSVStorage(sep rune, dataPath string) (*CSVStorage, error) { accountActionsPaths := appendName(allFoldersPath, utils.AccountActionsCsv) resourcesPaths := appendName(allFoldersPath, utils.ResourcesCsv) statsPaths := appendName(allFoldersPath, utils.StatsCsv) - sarsPaths := appendName(allFoldersPath, utils.SarsCsv) + trendsPaths := appendName(allFoldersPath, utils.TrendsCsv) sagsPaths := appendName(allFoldersPath, utils.SagsCsv) thresholdsPaths := appendName(allFoldersPath, utils.ThresholdsCsv) filtersPaths := appendName(allFoldersPath, utils.FiltersCsv) @@ -146,7 +146,7 @@ func NewFileCSVStorage(sep rune, dataPath string) (*CSVStorage, error) { accountActionsPaths, resourcesPaths, statsPaths, - sarsPaths, + trendsPaths, sagsPaths, thresholdsPaths, filtersPaths, @@ -163,13 +163,13 @@ func NewStringCSVStorage(sep rune, destinationsFn, timingsFn, ratesFn, destinationratesFn, destinationratetimingsFn, ratingprofilesFn, sharedgroupsFn, actionsFn, actiontimingsFn, actiontriggersFn, accountactionsFn, - resProfilesFn, statsFn, sarsFn, sagsFn, thresholdsFn, filterFn, routeProfilesFn, + resProfilesFn, statsFn, trendsFn, sagsFn, thresholdsFn, filterFn, routeProfilesFn, attributeProfilesFn, chargerProfilesFn, dispatcherProfilesFn, dispatcherHostsFn string) *CSVStorage { c := NewCSVStorage(sep, []string{destinationsFn}, []string{timingsFn}, []string{ratesFn}, []string{destinationratesFn}, []string{destinationratetimingsFn}, []string{ratingprofilesFn}, []string{sharedgroupsFn}, []string{actionsFn}, []string{actiontimingsFn}, []string{actiontriggersFn}, []string{accountactionsFn}, - []string{resProfilesFn}, []string{statsFn}, []string{sarsFn}, []string{sagsFn}, []string{thresholdsFn}, []string{filterFn}, + []string{resProfilesFn}, []string{statsFn}, []string{trendsFn}, []string{sagsFn}, []string{thresholdsFn}, []string{filterFn}, []string{routeProfilesFn}, []string{attributeProfilesFn}, []string{chargerProfilesFn}, []string{dispatcherProfilesFn}, []string{dispatcherHostsFn}) c.generator = NewCsvString @@ -206,8 +206,8 @@ func NewGoogleCSVStorage(sep rune, spreadsheetID string) (*CSVStorage, error) { getIfExist(utils.AccountActions), getIfExist(utils.Resources), getIfExist(utils.Stats), - getIfExist(utils.SarS), - getIfExist(utils.Sars), + getIfExist(utils.Trends), + getIfExist(utils.Trends), getIfExist(utils.Thresholds), getIfExist(utils.Filters), getIfExist(utils.Routes), @@ -240,7 +240,7 @@ func NewURLCSVStorage(sep rune, dataPath string) *CSVStorage { var accountActionsPaths []string var resourcesPaths []string var statsPaths []string - var sarsPaths []string + var trendsPaths []string var sagsPaths []string var thresholdsPaths []string var filtersPaths []string @@ -265,7 +265,7 @@ func NewURLCSVStorage(sep rune, dataPath string) *CSVStorage { accountActionsPaths = append(accountActionsPaths, joinURL(baseURL, utils.AccountActionsCsv)) resourcesPaths = append(resourcesPaths, joinURL(baseURL, utils.ResourcesCsv)) statsPaths = append(statsPaths, joinURL(baseURL, utils.StatsCsv)) - sarsPaths = append(sarsPaths, joinURL(baseURL, utils.SarsCsv)) + trendsPaths = append(trendsPaths, joinURL(baseURL, utils.TrendsCsv)) sagsPaths = append(sagsPaths, joinURL(baseURL, utils.SagsCsv)) thresholdsPaths = append(thresholdsPaths, joinURL(baseURL, utils.ThresholdsCsv)) filtersPaths = append(filtersPaths, joinURL(baseURL, utils.FiltersCsv)) @@ -303,8 +303,8 @@ func NewURLCSVStorage(sep rune, dataPath string) *CSVStorage { resourcesPaths = append(resourcesPaths, baseURL) case strings.HasSuffix(baseURL, utils.StatsCsv): statsPaths = append(statsPaths, baseURL) - case strings.HasSuffix(baseURL, utils.SarsCsv): - sarsPaths = append(sarsPaths, baseURL) + case strings.HasSuffix(baseURL, utils.TrendsCsv): + trendsPaths = append(trendsPaths, baseURL) case strings.HasSuffix(baseURL, utils.SagsCsv): sagsPaths = append(sagsPaths, baseURL) case strings.HasSuffix(baseURL, utils.ThresholdsCsv): @@ -338,7 +338,7 @@ func NewURLCSVStorage(sep rune, dataPath string) *CSVStorage { accountActionsPaths, resourcesPaths, statsPaths, - sarsPaths, + trendsPaths, sagsPaths, thresholdsPaths, filtersPaths, @@ -577,16 +577,16 @@ func (csvs *CSVStorage) GetTPStats(tpid, tenant, id string) ([]*utils.TPStatProf return tpStats.AsTPStats(), nil } -func (csvs *CSVStorage) GetTPSars(tpid, tenant, id string) ([]*utils.TPSarsProfile, error) { - var tpSars SarsMdls - if err := csvs.proccesData(SarsMdl{}, csvs.sarsFn, func(tp any) { - tPsars := tp.(SarsMdl) - tPsars.Tpid = tpid - tpSars = append(tpSars, &tPsars) +func (csvs *CSVStorage) GetTPTrends(tpid, tenant, id string) ([]*utils.TPTrendsProfile, error) { + var tpTrends TrendsMdls + if err := csvs.proccesData(TrendsMdl{}, csvs.trendsFn, func(tp any) { + tPTrends := tp.(TrendsMdl) + tPTrends.Tpid = tpid + tpTrends = append(tpTrends, &tPTrends) }); err != nil { return nil, err } - return tpSars.AsTPSars(), nil + return tpTrends.AsTPTrends(), nil } func (csvs *CSVStorage) GetTPSags(tpid, tenant, id string) ([]*utils.TPSagsProfile, error) { diff --git a/engine/storage_interface.go b/engine/storage_interface.go index 9ba8b94ea..1338c3f02 100644 --- a/engine/storage_interface.go +++ b/engine/storage_interface.go @@ -104,9 +104,9 @@ type DataDB interface { SetSagProfileDrv(sq *SagProfile) (err error) GetSagProfileDrv(tenant string, id string) (sq *SagProfile, err error) RemSagProfileDrv(tenant string, id string) (err error) - SetSarProfileDrv(sq *SarProfile) (err error) - GetSarProfileDrv(tenant string, id string) (sq *SarProfile, err error) - RemSarProfileDrv(tenant string, id string) (err error) + SetTrendProfileDrv(sq *TrendProfile) (err error) + GetTrendProfileDrv(tenant string, id string) (sq *TrendProfile, err error) + RemTrendProfileDrv(tenant string, id string) (err error) GetThresholdProfileDrv(tenant string, ID string) (tp *ThresholdProfile, err error) SetThresholdProfileDrv(tp *ThresholdProfile) (err error) RemThresholdProfileDrv(tenant, id string) (err error) @@ -179,7 +179,7 @@ type LoadReader interface { GetTPAccountActions(*utils.TPAccountActions) ([]*utils.TPAccountActions, error) GetTPResources(string, string, string) ([]*utils.TPResourceProfile, error) GetTPStats(string, string, string) ([]*utils.TPStatProfile, error) - GetTPSars(string, string, string) ([]*utils.TPSarsProfile, error) + GetTPTrends(string, string, string) ([]*utils.TPTrendsProfile, error) GetTPSags(string, string, string) ([]*utils.TPSagsProfile, error) GetTPThresholds(string, string, string) ([]*utils.TPThresholdProfile, error) GetTPFilters(string, string, string) ([]*utils.TPFilterProfile, error) @@ -205,7 +205,7 @@ type LoadWriter interface { SetTPAccountActions([]*utils.TPAccountActions) error SetTPResources([]*utils.TPResourceProfile) error SetTPStats([]*utils.TPStatProfile) error - SetTPSars([]*utils.TPSarsProfile) error + SetTPTrends([]*utils.TPTrendsProfile) error SetTPSags([]*utils.TPSagsProfile) error SetTPThresholds([]*utils.TPThresholdProfile) error SetTPFilters([]*utils.TPFilterProfile) error diff --git a/engine/storage_internal_datadb.go b/engine/storage_internal_datadb.go index a7150f8d3..f4358f9b4 100644 --- a/engine/storage_internal_datadb.go +++ b/engine/storage_internal_datadb.go @@ -592,22 +592,22 @@ func (iDB *InternalDB) RemStatQueueDrv(tenant, id string) (err error) { true, utils.NonTransactional) return } -func (iDB *InternalDB) SetSarProfileDrv(srp *SarProfile) (err error) { - iDB.db.Set(utils.CacheSarProfiles, srp.TenantID(), srp, nil, true, utils.NonTransactional) +func (iDB *InternalDB) SetTrendProfileDrv(srp *TrendProfile) (err error) { + iDB.db.Set(utils.CacheTrendProfiles, srp.TenantID(), srp, nil, true, utils.NonTransactional) return nil } -func (iDB *InternalDB) RemSarProfileDrv(tenant, id string) (err error) { - iDB.db.Remove(utils.CacheSarProfiles, utils.ConcatenatedKey(tenant, id), true, utils.NonTransactional) +func (iDB *InternalDB) RemTrendProfileDrv(tenant, id string) (err error) { + iDB.db.Remove(utils.CacheTrendProfiles, utils.ConcatenatedKey(tenant, id), true, utils.NonTransactional) return nil } -func (iDB *InternalDB) GetSarProfileDrv(tenant, id string) (sg *SarProfile, err error) { - x, ok := iDB.db.Get(utils.CacheSarProfiles, utils.ConcatenatedKey(tenant, id)) +func (iDB *InternalDB) GetTrendProfileDrv(tenant, id string) (sg *TrendProfile, err error) { + x, ok := iDB.db.Get(utils.CacheTrendProfiles, utils.ConcatenatedKey(tenant, id)) if !ok || x == nil { return nil, utils.ErrNotFound } - return x.(*SarProfile), nil + return x.(*TrendProfile), nil } func (iDB *InternalDB) SetSagProfileDrv(sgp *SagProfile) (err error) { diff --git a/engine/storage_internal_stordb.go b/engine/storage_internal_stordb.go index 27547c0ea..f1db5104d 100644 --- a/engine/storage_internal_stordb.go +++ b/engine/storage_internal_stordb.go @@ -403,7 +403,7 @@ func (iDB *InternalDB) GetTPStats(tpid, tenant, id string) (stats []*utils.TPSta return } -func (iDB *InternalDB) GetTPSars(tpid string, tenant string, id string) (sars []*utils.TPSarsProfile, err error) { +func (iDB *InternalDB) GetTPTrends(tpid string, tenant string, id string) (trends []*utils.TPTrendsProfile, err error) { key := tpid if tenant != utils.EmptyString { key += utils.ConcatenatedKeySep + tenant @@ -411,15 +411,15 @@ func (iDB *InternalDB) GetTPSars(tpid string, tenant string, id string) (sars [] if id != utils.EmptyString { key += utils.ConcatenatedKeySep + id } - ids := iDB.db.GetItemIDs(utils.CacheTBLTPSars, key) + ids := iDB.db.GetItemIDs(utils.CacheTBLTPTrends, key) for _, id := range ids { - x, ok := iDB.db.Get(utils.CacheTBLTPSars, id) + x, ok := iDB.db.Get(utils.CacheTBLTPTrends, id) if !ok || x == nil { return nil, utils.ErrNotFound } - sars = append(sars, x.(*utils.TPSarsProfile)) + trends = append(trends, x.(*utils.TPTrendsProfile)) } - if len(sars) == 0 { + if len(trends) == 0 { return nil, utils.ErrNotFound } return @@ -790,12 +790,12 @@ func (iDB *InternalDB) SetTPSags(sags []*utils.TPSagsProfile) (err error) { } return } -func (iDB *InternalDB) SetTPSars(sars []*utils.TPSarsProfile) (err error) { - if len(sars) == 0 { +func (iDB *InternalDB) SetTPTrends(trends []*utils.TPTrendsProfile) (err error) { + if len(trends) == 0 { return nil } - for _, sar := range sars { - iDB.db.Set(utils.CacheTBLTPSars, utils.ConcatenatedKey(sar.TPid, sar.Tenant, sar.ID), sar, nil, cacheCommit(utils.NonTransactional), utils.NonTransactional) + for _, trend := range trends { + iDB.db.Set(utils.CacheTBLTPTrends, utils.ConcatenatedKey(trend.TPid, trend.Tenant, trend.ID), trend, nil, cacheCommit(utils.NonTransactional), utils.NonTransactional) } return } diff --git a/engine/storage_mongo_datadb.go b/engine/storage_mongo_datadb.go index 3228ba793..43a78f4fb 100644 --- a/engine/storage_mongo_datadb.go +++ b/engine/storage_mongo_datadb.go @@ -64,7 +64,7 @@ const ( ColTmg = "timings" ColRes = "resources" ColSqs = "statqueues" - ColSrs = "sar_profiles" + ColTrs = "trend_profiles" ColSqp = "statqueue_profiles" ColSgp = "sag_profiles" ColTps = "threshold_profiles" @@ -302,7 +302,7 @@ func (ms *MongoStorage) ensureIndexesForCol(col string) error { // exported for switch col { case ColAct, ColApl, ColAAp, ColAtr, ColRpl, ColDst, ColRds, ColLht, ColIndx: err = ms.enusureIndex(col, true, "key") - case ColRsP, ColRes, ColSqs, ColSgp, ColSrs, ColSqp, ColTps, ColThs, ColRts, ColAttr, ColFlt, ColCpp, ColDpp, ColDph: + case ColRsP, ColRes, ColSqs, ColSgp, ColTrs, ColSqp, ColTps, ColThs, ColRts, ColAttr, ColFlt, ColCpp, ColDpp, ColDph: err = ms.enusureIndex(col, true, "tenant", "id") case ColRpf, ColShg, ColAcc: err = ms.enusureIndex(col, true, "id") @@ -348,7 +348,7 @@ func (ms *MongoStorage) EnsureIndexes(cols ...string) error { cols = []string{ ColAct, ColApl, ColAAp, ColAtr, ColRpl, ColDst, ColRds, ColLht, ColIndx, ColRsP, ColRes, ColSqs, ColSqp, ColTps, ColThs, ColRts, ColAttr, ColFlt, ColCpp, - ColDpp, ColRpf, ColShg, ColAcc, ColSgp, ColSrs, + ColDpp, ColRpf, ColShg, ColAcc, ColSgp, ColTrs, } } else { cols = []string{ @@ -437,8 +437,8 @@ func (ms *MongoStorage) RemoveKeysForPrefix(prefix string) error { colName = ColSqp case utils.SagsProfilePrefix: colName = ColSgp - case utils.SarsProfilePrefix: - colName = ColSrs + case utils.TrendsProfilePrefix: + colName = ColTrs case utils.ThresholdPrefix: colName = ColThs case utils.FilterPrefix: @@ -606,8 +606,8 @@ func (ms *MongoStorage) GetKeysForPrefix(prefix string) (keys []string, err erro keys, qryErr = ms.getAllKeysMatchingTenantID(sctx, ColSqs, utils.StatQueuePrefix, subject, tntID) case utils.SagsProfilePrefix: keys, qryErr = ms.getAllKeysMatchingTenantID(sctx, ColSgp, utils.SagsProfilePrefix, subject, tntID) - case utils.SarsProfilePrefix: - keys, qryErr = ms.getAllKeysMatchingTenantID(sctx, ColSrs, utils.SarsProfilePrefix, subject, tntID) + case utils.TrendsProfilePrefix: + keys, qryErr = ms.getAllKeysMatchingTenantID(sctx, ColTrs, utils.TrendsProfilePrefix, subject, tntID) case utils.StatQueueProfilePrefix: keys, qryErr = ms.getAllKeysMatchingTenantID(sctx, ColSqp, utils.StatQueueProfilePrefix, subject, tntID) case utils.AccountActionPlansPrefix: @@ -1561,10 +1561,10 @@ func (ms *MongoStorage) RemSagProfileDrv(tenant, id string) (err error) { } -func (ms *MongoStorage) GetSarProfileDrv(tenant, id string) (*SarProfile, error) { - srProfile := new(SarProfile) +func (ms *MongoStorage) GetTrendProfileDrv(tenant, id string) (*TrendProfile, error) { + srProfile := new(TrendProfile) err := ms.query(func(sctx mongo.SessionContext) error { - sr := ms.getCol(ColSrs).FindOne(sctx, bson.M{"tenant": tenant, "id": id}) + sr := ms.getCol(ColTrs).FindOne(sctx, bson.M{"tenant": tenant, "id": id}) decodeErr := sr.Decode(srProfile) if errors.Is(decodeErr, mongo.ErrNoDocuments) { return utils.ErrNotFound @@ -1574,18 +1574,18 @@ func (ms *MongoStorage) GetSarProfileDrv(tenant, id string) (*SarProfile, error) return srProfile, err } -func (ms *MongoStorage) SetSarProfileDrv(srp *SarProfile) (err error) { +func (ms *MongoStorage) SetTrendProfileDrv(srp *TrendProfile) (err error) { return ms.query(func(sctx mongo.SessionContext) error { - _, err := ms.getCol(ColSrs).UpdateOne(sctx, bson.M{"tenant": srp.Tenant, "id": srp.ID}, + _, err := ms.getCol(ColTrs).UpdateOne(sctx, bson.M{"tenant": srp.Tenant, "id": srp.ID}, bson.M{"$set": srp}, options.Update().SetUpsert(true)) return err }) } -func (ms *MongoStorage) RemSarProfileDrv(tenant, id string) (err error) { +func (ms *MongoStorage) RemTrendProfileDrv(tenant, id string) (err error) { return ms.query(func(sctx mongo.SessionContext) error { - dr, err := ms.getCol(ColSrs).DeleteOne(sctx, bson.M{"tenant": tenant, "id": id}) + dr, err := ms.getCol(ColTrs).DeleteOne(sctx, bson.M{"tenant": tenant, "id": id}) if dr.DeletedCount == 0 { return utils.ErrNotFound } diff --git a/engine/storage_mongo_stordb.go b/engine/storage_mongo_stordb.go index eb81d5ca5..d2a664696 100644 --- a/engine/storage_mongo_stordb.go +++ b/engine/storage_mongo_stordb.go @@ -440,7 +440,7 @@ func (ms *MongoStorage) GetTPStats(tpid, tenant, id string) ([]*utils.TPStatProf return results, err } -func (ms *MongoStorage) GetTPSars(tpid string, tenant string, id string) ([]*utils.TPSarsProfile, error) { +func (ms *MongoStorage) GetTPTrends(tpid string, tenant string, id string) ([]*utils.TPTrendsProfile, error) { filter := bson.M{ "tpid": tpid, } @@ -450,14 +450,14 @@ func (ms *MongoStorage) GetTPSars(tpid string, tenant string, id string) ([]*uti if tenant != "" { filter["tenant"] = tenant } - var results []*utils.TPSarsProfile + var results []*utils.TPTrendsProfile err := ms.query(func(sctx mongo.SessionContext) error { - cur, err := ms.getCol(utils.TBLTPSars).Find(sctx, filter) + cur, err := ms.getCol(utils.TBLTPTrends).Find(sctx, filter) if err != nil { return err } for cur.Next(sctx) { - var el utils.TPSarsProfile + var el utils.TPTrendsProfile err := cur.Decode(&el) if err != nil { return err @@ -1281,13 +1281,13 @@ func (ms *MongoStorage) SetTPStats(tpSTs []*utils.TPStatProfile) (err error) { }) } -func (ms *MongoStorage) SetTPSars(tpSars []*utils.TPSarsProfile) (err error) { - if len(tpSars) == 0 { +func (ms *MongoStorage) SetTPTrends(tpTrends []*utils.TPTrendsProfile) (err error) { + if len(tpTrends) == 0 { return } return ms.query(func(sctx mongo.SessionContext) (err error) { - for _, tp := range tpSars { - _, err := ms.getCol(utils.TBLTPSars).UpdateOne(sctx, bson.M{"tpid": tp.TPid, "id": tp.ID}, + for _, tp := range tpTrends { + _, err := ms.getCol(utils.TBLTPTrends).UpdateOne(sctx, bson.M{"tpid": tp.TPid, "id": tp.ID}, bson.M{"$set": tp}, options.Update().SetUpsert(true)) if err != nil { return err diff --git a/engine/storage_redis.go b/engine/storage_redis.go index e4786e580..ad64ddb02 100644 --- a/engine/storage_redis.go +++ b/engine/storage_redis.go @@ -939,17 +939,17 @@ func (rs *RedisStorage) RemStatQueueDrv(tenant, id string) (err error) { return rs.Cmd(nil, redis_DEL, utils.StatQueuePrefix+utils.ConcatenatedKey(tenant, id)) } -func (rs *RedisStorage) SetSarProfileDrv(sg *SarProfile) (err error) { +func (rs *RedisStorage) SetTrendProfileDrv(sg *TrendProfile) (err error) { var result []byte if result, err = rs.ms.Marshal(sg); err != nil { return } - return rs.Cmd(nil, redis_SET, utils.SarsProfilePrefix+utils.ConcatenatedKey(sg.Tenant, sg.ID), string(result)) + return rs.Cmd(nil, redis_SET, utils.TrendsProfilePrefix+utils.ConcatenatedKey(sg.Tenant, sg.ID), string(result)) } -func (rs *RedisStorage) GetSarProfileDrv(tenant string, id string) (sg *SarProfile, err error) { +func (rs *RedisStorage) GetTrendProfileDrv(tenant string, id string) (sg *TrendProfile, err error) { var values []byte - if err = rs.Cmd(&values, redis_GET, utils.SarsProfilePrefix+utils.ConcatenatedKey(tenant, id)); err != nil { + if err = rs.Cmd(&values, redis_GET, utils.TrendsProfilePrefix+utils.ConcatenatedKey(tenant, id)); err != nil { return } else if len(values) == 0 { err = utils.ErrNotFound @@ -958,8 +958,8 @@ func (rs *RedisStorage) GetSarProfileDrv(tenant string, id string) (sg *SarProfi err = rs.ms.Unmarshal(values, &sg) return } -func (rs *RedisStorage) RemSarProfileDrv(tenant string, id string) (err error) { - return rs.Cmd(nil, redis_DEL, utils.SarsProfilePrefix+utils.ConcatenatedKey(tenant, id)) +func (rs *RedisStorage) RemTrendProfileDrv(tenant string, id string) (err error) { + return rs.Cmd(nil, redis_DEL, utils.TrendsProfilePrefix+utils.ConcatenatedKey(tenant, id)) } func (rs *RedisStorage) SetSagProfileDrv(sg *SagProfile) (err error) { diff --git a/engine/storage_sql.go b/engine/storage_sql.go index a3168e4af..b09b22a9f 100644 --- a/engine/storage_sql.go +++ b/engine/storage_sql.go @@ -598,17 +598,17 @@ func (sqls *SQLStorage) SetTPSags(sgs []*utils.TPSagsProfile) error { return nil } -func (sqls *SQLStorage) SetTPSars(srs []*utils.TPSarsProfile) error { +func (sqls *SQLStorage) SetTPTrends(srs []*utils.TPTrendsProfile) error { if len(srs) == 0 { return nil } tx := sqls.db.Begin() for _, sg := range srs { - if err := tx.Where(&SarsMdl{Tpid: sg.TPid, ID: sg.ID}).Delete(SarsMdl{}).Error; err != nil { + if err := tx.Where(&TrendsMdl{Tpid: sg.TPid, ID: sg.ID}).Delete(TrendsMdl{}).Error; err != nil { tx.Rollback() return err } - for _, msg := range APItoModelSars(sg) { + for _, msg := range APItoModelTrends(sg) { if err := tx.Create(&msg).Error; err != nil { tx.Rollback() return err @@ -1461,8 +1461,8 @@ func (sqls *SQLStorage) GetTPStats(tpid, tenant, id string) ([]*utils.TPStatProf return asts, nil } -func (sqls *SQLStorage) GetTPSars(tpid, tenant, id string) ([]*utils.TPSarsProfile, error) { - var srs SarsMdls +func (sqls *SQLStorage) GetTPTrends(tpid, tenant, id string) ([]*utils.TPTrendsProfile, error) { + var srs TrendsMdls q := sqls.db.Where("tpid = ?", tpid) if len(id) != 0 { q = q.Where("id = ?", id) @@ -1473,7 +1473,7 @@ func (sqls *SQLStorage) GetTPSars(tpid, tenant, id string) ([]*utils.TPSarsProfi if err := q.Find(&srs).Error; err != nil { return nil, err } - asrs := srs.AsTPSars() + asrs := srs.AsTPTrends() if len(asrs) == 0 { return asrs, utils.ErrNotFound } diff --git a/engine/tpexporter.go b/engine/tpexporter.go index d4ef4e633..d2cbeacfb 100644 --- a/engine/tpexporter.go +++ b/engine/tpexporter.go @@ -279,16 +279,16 @@ func (tpExp *TPExporter) Run() error { } } - storDataSars, err := tpExp.storDb.GetTPSars(tpExp.tpID, "", "") + storDataTrends, err := tpExp.storDb.GetTPTrends(tpExp.tpID, "", "") if err != nil && err.Error() != utils.ErrNotFound.Error() { - utils.Logger.Warning(fmt.Sprintf("<%s> error: %s,when getting %s from stordb for export", utils.ApierS, err, utils.TpSars)) + utils.Logger.Warning(fmt.Sprintf("<%s> error: %s,when getting %s from stordb for export", utils.ApierS, err, utils.TpTrends)) } - if len(storDataSars) != 0 { - toExportMap[utils.SarsCsv] = make([]any, len(storDataSars)) - for _, sd := range storDataSars { - sModels := APItoModelSars(sd) + if len(storDataTrends) != 0 { + toExportMap[utils.TrendsCsv] = make([]any, len(storDataTrends)) + for _, sd := range storDataTrends { + sModels := APItoModelTrends(sd) for _, sdModel := range sModels { - toExportMap[utils.SarsCsv] = append(toExportMap[utils.SarsCsv], sdModel) + toExportMap[utils.TrendsCsv] = append(toExportMap[utils.TrendsCsv], sdModel) } } } diff --git a/engine/tpimporter_csv.go b/engine/tpimporter_csv.go index 8da2996bf..0e03bc3a6 100644 --- a/engine/tpimporter_csv.go +++ b/engine/tpimporter_csv.go @@ -53,7 +53,7 @@ var fileHandlers = map[string]func(*TPCSVImporter, string) error{ utils.AccountActionsCsv: (*TPCSVImporter).importAccountActions, utils.ResourcesCsv: (*TPCSVImporter).importResources, utils.StatsCsv: (*TPCSVImporter).importStats, - utils.SarsCsv: (*TPCSVImporter).importSars, + utils.TrendsCsv: (*TPCSVImporter).importTrends, utils.SagsCsv: (*TPCSVImporter).importSags, utils.ThresholdsCsv: (*TPCSVImporter).importThresholds, utils.FiltersCsv: (*TPCSVImporter).importFilters, @@ -287,15 +287,15 @@ func (tpImp *TPCSVImporter) importStats(fn string) error { return tpImp.StorDb.SetTPStats(sts) } -func (tpImp *TPCSVImporter) importSars(fn string) error { +func (tpImp *TPCSVImporter) importTrends(fn string) error { if tpImp.Verbose { log.Printf("Processing file: <%s>", fn) } - srs, err := tpImp.csvr.GetTPSars(tpImp.TPid, "", "") + srs, err := tpImp.csvr.GetTPTrends(tpImp.TPid, "", "") if err != nil { return err } - return tpImp.StorDb.SetTPSars(srs) + return tpImp.StorDb.SetTPTrends(srs) } func (tpImp *TPCSVImporter) importSags(fn string) error { diff --git a/engine/tpreader.go b/engine/tpreader.go index 650a3434e..ef9279c72 100644 --- a/engine/tpreader.go +++ b/engine/tpreader.go @@ -49,7 +49,7 @@ type TpReader struct { sharedGroups map[string]*SharedGroup resProfiles map[utils.TenantID]*utils.TPResourceProfile sqProfiles map[utils.TenantID]*utils.TPStatProfile - srProfiles map[utils.TenantID]*utils.TPSarsProfile + trProfiles map[utils.TenantID]*utils.TPTrendsProfile sgProfiles map[utils.TenantID]*utils.TPSagsProfile thProfiles map[utils.TenantID]*utils.TPThresholdProfile filters map[utils.TenantID]*utils.TPFilterProfile @@ -1137,21 +1137,21 @@ func (tpr *TpReader) LoadStats() error { return tpr.LoadStatsFiltered("") } -func (tpr *TpReader) LoadSarsFiltered(tag string) error { - tps, err := tpr.lr.GetTPSars(tpr.tpid, "", tag) +func (tpr *TpReader) LoadTrendsFiltered(tag string) error { + tps, err := tpr.lr.GetTPTrends(tpr.tpid, "", tag) if err != nil { return err } - mapSrs := make(map[utils.TenantID]*utils.TPSarsProfile) + mapSrs := make(map[utils.TenantID]*utils.TPTrendsProfile) for _, sr := range tps { mapSrs[utils.TenantID{Tenant: sr.Tenant, ID: sr.ID}] = sr } - tpr.srProfiles = mapSrs + tpr.trProfiles = mapSrs return nil } -func (tpr *TpReader) LoadSars() error { - return tpr.LoadSarsFiltered("") +func (tpr *TpReader) LoadTrends() error { + return tpr.LoadTrendsFiltered("") } func (tpr *TpReader) LoadSagsFiltered(tag string) error { @@ -1354,7 +1354,7 @@ func (tpr *TpReader) LoadAll() (err error) { if err = tpr.LoadStats(); err != nil && err.Error() != utils.NotFoundCaps { return } - if err = tpr.LoadSars(); err != nil && err.Error() != utils.NotFoundCaps { + if err = tpr.LoadTrends(); err != nil && err.Error() != utils.NotFoundCaps { return } if err = tpr.LoadSags(); err != nil && err.Error() != utils.NotFoundCaps { @@ -1616,18 +1616,18 @@ func (tpr *TpReader) WriteToDatabase(verbose, disableReverse bool) (err error) { loadIDs[utils.CacheStatQueueProfiles] = loadID } if verbose { - log.Print("SarProfiles") + log.Print("TrendProfiles") } - for _, tpSR := range tpr.srProfiles { - var sr *SarProfile - if sr, err = APItoSars(tpSR); err != nil { + for _, tpTR := range tpr.trProfiles { + var tr *TrendProfile + if tr, err = APItoTrends(tpTR); err != nil { return } - if err = tpr.dm.SetSarProfile(sr); err != nil { + if err = tpr.dm.SetTrendProfile(tr); err != nil { return } if verbose { - log.Print("\t", sr.TenantID()) + log.Print("\t", tr.TenantID()) } } if verbose { diff --git a/general_tests/acntacts_test.go b/general_tests/acntacts_test.go index f0688dcd6..86896e3bf 100644 --- a/general_tests/acntacts_test.go +++ b/general_tests/acntacts_test.go @@ -50,7 +50,7 @@ ENABLE_ACNT,*enable_account,,,,,,,,,,,,,false,false,10` accountActions := `cgrates.org,1,TOPUP10_AT,,,` resLimits := `` stats := `` - sars := `` + trends := `` sags := `` thresholds := `` filters := `` @@ -60,7 +60,7 @@ ENABLE_ACNT,*enable_account,,,,,,,,,,,,,false,false,10` csvr, err := engine.NewTpReader(dbAcntActs.DataDB(), engine.NewStringCSVStorage(utils.CSVSep, destinations, timings, rates, destinationRates, ratingPlans, ratingProfiles, sharedGroups, actions, actionPlans, actionTriggers, accountActions, - resLimits, stats, sars, sags, thresholds, filters, suppliers, attrProfiles, chargerProfiles, ``, ""), "", "", nil, nil, false) + resLimits, stats, trends, sags, thresholds, filters, suppliers, attrProfiles, chargerProfiles, ``, ""), "", "", nil, nil, false) if err != nil { t.Error(err) } diff --git a/general_tests/auth_test.go b/general_tests/auth_test.go index 39862c6fc..7db79861d 100644 --- a/general_tests/auth_test.go +++ b/general_tests/auth_test.go @@ -54,7 +54,7 @@ func TestAuthLoadCsvError(t *testing.T) { accountActions := `` resLimits := `` stats := `` - sars := `` + trends := `` sags := `` thresholds := `` filters := `` @@ -63,7 +63,7 @@ func TestAuthLoadCsvError(t *testing.T) { chargerProfiles := `` csvr, err := engine.NewTpReader(dbAuth.DataDB(), engine.NewStringCSVStorage(utils.CSVSep, destinations, timings, rates, destinationRates, ratingPlans, ratingProfiles, sharedGroups, actions, actionPlans, actionTriggers, accountActions, - resLimits, stats, sars, sags, thresholds, filters, suppliers, attrProfiles, chargerProfiles, ``, ""), "", "", nil, nil, false) + resLimits, stats, trends, sags, thresholds, filters, suppliers, attrProfiles, chargerProfiles, ``, ""), "", "", nil, nil, false) if err != nil { t.Error(err) } @@ -90,7 +90,7 @@ cgrates.org,call,*any,2013-01-06T00:00:00Z,RP_ANY,` accountActions := `cgrates.org,testauthpostpaid1,TOPUP10_AT,,,` resLimits := `` stats := `` - sars := `` + trends := `` sags := `` thresholds := `` filters := `` @@ -99,7 +99,7 @@ cgrates.org,call,*any,2013-01-06T00:00:00Z,RP_ANY,` chargerProfiles := `` csvr, err := engine.NewTpReader(dbAuth.DataDB(), engine.NewStringCSVStorage(utils.CSVSep, destinations, timings, rates, destinationRates, ratingPlans, ratingProfiles, sharedGroups, actions, actionPlans, actionTriggers, accountActions, - resLimits, stats, sars, sags, thresholds, filters, suppliers, attrProfiles, chargerProfiles, ``, ""), "", "", nil, nil, false) + resLimits, stats, trends, sags, thresholds, filters, suppliers, attrProfiles, chargerProfiles, ``, ""), "", "", nil, nil, false) if err != nil { t.Error(err) } diff --git a/general_tests/ddazmbl1_test.go b/general_tests/ddazmbl1_test.go index 68abe8406..06e1183a2 100644 --- a/general_tests/ddazmbl1_test.go +++ b/general_tests/ddazmbl1_test.go @@ -58,7 +58,7 @@ TOPUP10_AT,TOPUP10_AC1,ASAP,10` accountActions := `cgrates.org,12344,TOPUP10_AT,,,` resLimits := `` stats := `` - sars := `` + trends := `` sags := `` thresholds := `` filters := `` @@ -69,7 +69,7 @@ TOPUP10_AT,TOPUP10_AC1,ASAP,10` engine.NewStringCSVStorage(utils.CSVSep, destinations, timings, rates, destinationRates, ratingPlans, ratingProfiles, sharedGroups, actions, actionPlans, actionTriggers, accountActions, - resLimits, stats, sars, sags, thresholds, filters, suppliers, + resLimits, stats, trends, sags, thresholds, filters, suppliers, attrProfiles, chargerProfiles, ``, ""), "", "", nil, nil, false) if err != nil { t.Error(err) diff --git a/general_tests/ddazmbl2_test.go b/general_tests/ddazmbl2_test.go index 2e638cbf7..ddc741f09 100644 --- a/general_tests/ddazmbl2_test.go +++ b/general_tests/ddazmbl2_test.go @@ -58,7 +58,7 @@ TOPUP10_AT,TOPUP10_AC1,ASAP,10` accountActions := `cgrates.org,12345,TOPUP10_AT,,,` resLimits := `` stats := `` - sars := `` + trends := `` sags := `` thresholds := `` filters := `` @@ -68,7 +68,7 @@ TOPUP10_AT,TOPUP10_AC1,ASAP,10` csvr, err := engine.NewTpReader(dataDB2.DataDB(), engine.NewStringCSVStorage(utils.CSVSep, destinations, timings, rates, destinationRates, ratingPlans, ratingProfiles, sharedGroups, actions, actionPlans, actionTriggers, accountActions, resLimits, - stats, sars, sags, thresholds, filters, suppliers, attrProfiles, chargerProfiles, ``, ""), "", "", nil, nil, false) + stats, trends, sags, thresholds, filters, suppliers, attrProfiles, chargerProfiles, ``, ""), "", "", nil, nil, false) if err != nil { t.Error(err) } diff --git a/general_tests/ddazmbl3_test.go b/general_tests/ddazmbl3_test.go index fb223459f..ad8207368 100644 --- a/general_tests/ddazmbl3_test.go +++ b/general_tests/ddazmbl3_test.go @@ -56,7 +56,7 @@ cgrates.org,call,discounted_minutes,2013-01-06T00:00:00Z,RP_UK_Mobile_BIG5_PKG,` accountActions := `cgrates.org,12346,TOPUP10_AT,,,` resLimits := `` stats := `` - sars := `` + trends := `` sags := `` thresholds := `` filters := `` @@ -65,7 +65,7 @@ cgrates.org,call,discounted_minutes,2013-01-06T00:00:00Z,RP_UK_Mobile_BIG5_PKG,` chargerProfiles := `` csvr, err := engine.NewTpReader(dataDB3.DataDB(), engine.NewStringCSVStorage(utils.CSVSep, destinations, timings, rates, destinationRates, ratingPlans, ratingProfiles, sharedGroups, actions, actionPlans, actionTriggers, - accountActions, resLimits, stats, sars, sags, + accountActions, resLimits, stats, trends, sags, thresholds, filters, suppliers, attrProfiles, chargerProfiles, ``, ""), "", "", nil, nil, false) if err != nil { t.Error(err) diff --git a/loaders/loader.go b/loaders/loader.go index 965e72e1d..89f5331f1 100644 --- a/loaders/loader.go +++ b/loaders/loader.go @@ -408,29 +408,29 @@ func (ldr *Loader) storeLoadedData(loaderType string, cacheArgs[utils.CacheStatQueues] = ids } } - case utils.MetaSars: + case utils.MetaTrends: for _, lDataSet := range lds { - srsModels := make(engine.SarsMdls, len(lDataSet)) + trsModels := make(engine.TrendsMdls, len(lDataSet)) for i, ld := range lDataSet { - srsModels[i] = new(engine.SarsMdl) - if err = utils.UpdateStructWithIfaceMap(srsModels[i], ld); err != nil { + trsModels[i] = new(engine.TrendsMdl) + if err = utils.UpdateStructWithIfaceMap(trsModels[i], ld); err != nil { return } } - for _, tpSrs := range srsModels.AsTPSars() { - srsPrf, err := engine.APItoSars(tpSrs) + for _, tpTrs := range trsModels.AsTPTrends() { + trsPrf, err := engine.APItoTrends(tpTrs) if err != nil { return err } if ldr.dryRun { utils.Logger.Info( - fmt.Sprintf("<%s-%s> DRY_RUN: SarsProfile: %s", - utils.LoaderS, ldr.ldrID, utils.ToJSON(srsPrf))) + fmt.Sprintf("<%s-%s> DRY_RUN: TrendProfile: %s", + utils.LoaderS, ldr.ldrID, utils.ToJSON(trsPrf))) continue } - ids = append(ids, srsPrf.TenantID()) - if err := ldr.dm.SetSarProfile(srsPrf); err != nil { + ids = append(ids, trsPrf.TenantID()) + if err := ldr.dm.SetTrendProfile(trsPrf); err != nil { return err } } diff --git a/services/datadb_it_test.go b/services/datadb_it_test.go index d93ed7555..e140a3b2a 100644 --- a/services/datadb_it_test.go +++ b/services/datadb_it_test.go @@ -123,7 +123,7 @@ func TestDataDBReload(t *testing.T) { utils.MetaResources: {Limit: -1}, utils.MetaStatQueueProfiles: {Limit: -1}, utils.MetaSagProfiles: {Limit: -1}, - utils.MetaSarProfiles: {Limit: -1}, + utils.MetaTrendProfiles: {Limit: -1}, utils.MetaThresholds: {Limit: -1}, utils.MetaThresholdProfiles: {Limit: -1}, utils.MetaFilters: {Limit: -1}, diff --git a/services/sags.go b/services/sags.go index 8780755f7..ecaa64808 100644 --- a/services/sags.go +++ b/services/sags.go @@ -31,7 +31,7 @@ import ( "github.com/cgrates/cgrates/utils" ) -// NewSagsService returns the SaRS Service +// NewSagsService returns the SagS Service func NewSagService(cfg *config.CGRConfig, dm *DataDBService, cacheS *engine.CacheS, filterSChan chan *engine.FilterS, server *cores.Server, internalSagSChan chan birpc.ClientConnector, diff --git a/services/sars.go b/services/trends.go similarity index 83% rename from services/sars.go rename to services/trends.go index 498dde144..cf43187c4 100644 --- a/services/sars.go +++ b/services/trends.go @@ -31,13 +31,13 @@ import ( "github.com/cgrates/cgrates/utils" ) -// NewSarsService returns the SaRS Service -func NewSarService(cfg *config.CGRConfig, dm *DataDBService, +// NewTrendsService returns the TrendS Service +func NewTrendService(cfg *config.CGRConfig, dm *DataDBService, cacheS *engine.CacheS, filterSChan chan *engine.FilterS, server *cores.Server, internalStatSChan chan birpc.ClientConnector, connMgr *engine.ConnManager, anz *AnalyzerService, srvDep map[string]*sync.WaitGroup) servmanager.Service { - return &SarService{ + return &TrendService{ connChan: internalStatSChan, cfg: cfg, dm: dm, @@ -50,7 +50,7 @@ func NewSarService(cfg *config.CGRConfig, dm *DataDBService, } } -type SarService struct { +type TrendService struct { sync.RWMutex cfg *config.CGRConfig dm *DataDBService @@ -64,7 +64,7 @@ type SarService struct { } // Start should handle the sercive start -func (sa *SarService) Start() error { +func (sa *TrendService) Start() error { if sa.IsRunning() { return utils.ErrServiceAlreadyRunning } @@ -78,8 +78,8 @@ func (sa *SarService) Start() error { dbchan <- datadb utils.Logger.Info(fmt.Sprintf("<%s> starting <%s> subsystem", - utils.CoreS, utils.SarS)) - srv, err := engine.NewService(v1.NewSarSv1()) + utils.CoreS, utils.TrendS)) + srv, err := engine.NewService(v1.NewTrendSv1()) if err != nil { return err } @@ -93,12 +93,12 @@ func (sa *SarService) Start() error { } // Reload handles the change of config -func (sa *SarService) Reload() (err error) { +func (sa *TrendService) Reload() (err error) { return } // Shutdown stops the service -func (sa *SarService) Shutdown() (err error) { +func (sa *TrendService) Shutdown() (err error) { defer sa.srvDep[utils.DataDB].Done() sa.Lock() defer sa.Unlock() @@ -107,18 +107,18 @@ func (sa *SarService) Shutdown() (err error) { } // IsRunning returns if the service is running -func (sa *SarService) IsRunning() bool { +func (sa *TrendService) IsRunning() bool { sa.RLock() defer sa.RUnlock() return false } // ServiceName returns the service name -func (sa *SarService) ServiceName() string { - return utils.SarS +func (sa *TrendService) ServiceName() string { + return utils.TrendS } // ShouldRun returns if the service should be running -func (sa *SarService) ShouldRun() bool { - return sa.cfg.SarSCfg().Enabled +func (sa *TrendService) ShouldRun() bool { + return sa.cfg.TrendSCfg().Enabled } diff --git a/servmanager/servmanager.go b/servmanager/servmanager.go index 5a77b1c76..c59cdba0f 100644 --- a/servmanager/servmanager.go +++ b/servmanager/servmanager.go @@ -195,8 +195,8 @@ func (srvMngr *ServiceManager) handleReload() { go srvMngr.reloadService(utils.ThresholdS) case <-srvMngr.GetConfig().GetReloadChan(config.STATS_JSON): go srvMngr.reloadService(utils.StatS) - case <-srvMngr.GetConfig().GetReloadChan(config.SARS_JSON): - go srvMngr.reloadService(utils.SarS) + case <-srvMngr.GetConfig().GetReloadChan(config.TRENDS_JSON): + go srvMngr.reloadService(utils.TrendS) case <-srvMngr.GetConfig().GetReloadChan(config.SAGS_JSON): go srvMngr.reloadService(utils.SagS) case <-srvMngr.GetConfig().GetReloadChan(config.RESOURCES_JSON): diff --git a/utils/apitpdata.go b/utils/apitpdata.go index afe2c6997..1a71d014e 100644 --- a/utils/apitpdata.go +++ b/utils/apitpdata.go @@ -987,7 +987,7 @@ type TPStatProfile struct { ThresholdIDs []string } -// TPSarProfile is used in APIs to manage remotely offline SarProfile +// TPSagProfile is used in APIs to manage remotely offline SagProfile type TPSagsProfile struct { TPid string Tenant string @@ -1000,8 +1000,8 @@ type TPSagsProfile struct { ThresholdIDs []string } -// TPSarProfile is used in APIs to manage remotely offline SarProfile -type TPSarsProfile struct { +// TPTrendProfile is used in APIs to manage remotely offline TrendProfile +type TPTrendsProfile struct { TPid string Tenant string ID string @@ -1349,30 +1349,29 @@ func NewAttrReloadCacheWithOptsFromMap(arg map[string][]string, tnt string, opts Tenant: tnt, APIOpts: opts, - DestinationIDs: arg[CacheDestinations], - ReverseDestinationIDs: arg[CacheReverseDestinations], - RatingPlanIDs: arg[CacheRatingPlans], - RatingProfileIDs: arg[CacheRatingProfiles], - ActionIDs: arg[CacheActions], - ActionPlanIDs: arg[CacheActionPlans], - AccountActionPlanIDs: arg[CacheAccountActionPlans], - ActionTriggerIDs: arg[CacheActionTriggers], - SharedGroupIDs: arg[CacheSharedGroups], - ResourceProfileIDs: arg[CacheResourceProfiles], - ResourceIDs: arg[CacheResources], - StatsQueueIDs: arg[CacheStatQueues], - StatsQueueProfileIDs: arg[CacheStatQueueProfiles], - SagProfileIDs: arg[CacheSagProfiles], - ThresholdIDs: arg[CacheThresholds], - ThresholdProfileIDs: arg[CacheThresholdProfiles], - FilterIDs: arg[CacheFilters], - RouteProfileIDs: arg[CacheRouteProfiles], - AttributeProfileIDs: arg[CacheAttributeProfiles], - ChargerProfileIDs: arg[CacheChargerProfiles], - DispatcherProfileIDs: arg[CacheDispatcherProfiles], - DispatcherHostIDs: arg[CacheDispatcherHosts], - Dispatchers: arg[CacheDispatchers], - + DestinationIDs: arg[CacheDestinations], + ReverseDestinationIDs: arg[CacheReverseDestinations], + RatingPlanIDs: arg[CacheRatingPlans], + RatingProfileIDs: arg[CacheRatingProfiles], + ActionIDs: arg[CacheActions], + ActionPlanIDs: arg[CacheActionPlans], + AccountActionPlanIDs: arg[CacheAccountActionPlans], + ActionTriggerIDs: arg[CacheActionTriggers], + SharedGroupIDs: arg[CacheSharedGroups], + ResourceProfileIDs: arg[CacheResourceProfiles], + ResourceIDs: arg[CacheResources], + StatsQueueIDs: arg[CacheStatQueues], + StatsQueueProfileIDs: arg[CacheStatQueueProfiles], + SagProfileIDs: arg[CacheSagProfiles], + ThresholdIDs: arg[CacheThresholds], + ThresholdProfileIDs: arg[CacheThresholdProfiles], + FilterIDs: arg[CacheFilters], + RouteProfileIDs: arg[CacheRouteProfiles], + AttributeProfileIDs: arg[CacheAttributeProfiles], + ChargerProfileIDs: arg[CacheChargerProfiles], + DispatcherProfileIDs: arg[CacheDispatcherProfiles], + DispatcherHostIDs: arg[CacheDispatcherHosts], + Dispatchers: arg[CacheDispatchers], TimingIDs: arg[CacheTimings], AttributeFilterIndexIDs: arg[CacheAttributeFilterIndexes], ResourceFilterIndexIDs: arg[CacheResourceFilterIndexes], @@ -1424,30 +1423,29 @@ type AttrReloadCacheWithAPIOpts struct { func (a *AttrReloadCacheWithAPIOpts) Map() map[string][]string { return map[string][]string{ - CacheDestinations: a.DestinationIDs, - CacheReverseDestinations: a.ReverseDestinationIDs, - CacheRatingPlans: a.RatingPlanIDs, - CacheRatingProfiles: a.RatingProfileIDs, - CacheActions: a.ActionIDs, - CacheActionPlans: a.ActionPlanIDs, - CacheAccountActionPlans: a.AccountActionPlanIDs, - CacheActionTriggers: a.ActionTriggerIDs, - CacheSharedGroups: a.SharedGroupIDs, - CacheResourceProfiles: a.ResourceProfileIDs, - CacheResources: a.ResourceIDs, - CacheStatQueues: a.StatsQueueIDs, - CacheStatQueueProfiles: a.StatsQueueProfileIDs, - CacheThresholds: a.ThresholdIDs, - CacheThresholdProfiles: a.ThresholdProfileIDs, - CacheSagProfiles: a.SagProfileIDs, - CacheFilters: a.FilterIDs, - CacheRouteProfiles: a.RouteProfileIDs, - CacheAttributeProfiles: a.AttributeProfileIDs, - CacheChargerProfiles: a.ChargerProfileIDs, - CacheDispatcherProfiles: a.DispatcherProfileIDs, - CacheDispatcherHosts: a.DispatcherHostIDs, - CacheDispatchers: a.Dispatchers, - + CacheDestinations: a.DestinationIDs, + CacheReverseDestinations: a.ReverseDestinationIDs, + CacheRatingPlans: a.RatingPlanIDs, + CacheRatingProfiles: a.RatingProfileIDs, + CacheActions: a.ActionIDs, + CacheActionPlans: a.ActionPlanIDs, + CacheAccountActionPlans: a.AccountActionPlanIDs, + CacheActionTriggers: a.ActionTriggerIDs, + CacheSharedGroups: a.SharedGroupIDs, + CacheResourceProfiles: a.ResourceProfileIDs, + CacheResources: a.ResourceIDs, + CacheStatQueues: a.StatsQueueIDs, + CacheStatQueueProfiles: a.StatsQueueProfileIDs, + CacheThresholds: a.ThresholdIDs, + CacheThresholdProfiles: a.ThresholdProfileIDs, + CacheSagProfiles: a.SagProfileIDs, + CacheFilters: a.FilterIDs, + CacheRouteProfiles: a.RouteProfileIDs, + CacheAttributeProfiles: a.AttributeProfileIDs, + CacheChargerProfiles: a.ChargerProfileIDs, + CacheDispatcherProfiles: a.DispatcherProfileIDs, + CacheDispatcherHosts: a.DispatcherHostIDs, + CacheDispatchers: a.Dispatchers, CacheTimings: a.TimingIDs, CacheAttributeFilterIndexes: a.AttributeFilterIndexIDs, CacheResourceFilterIndexes: a.ResourceFilterIndexIDs, diff --git a/utils/apitpdata_test.go b/utils/apitpdata_test.go index aa6bc2904..90501956f 100644 --- a/utils/apitpdata_test.go +++ b/utils/apitpdata_test.go @@ -1009,7 +1009,7 @@ func TestNewAttrReloadCacheWithOptsFromMap(t *testing.T) { excluded := NewStringSet([]string{MetaAPIBan, MetaSentryPeer, MetaAccounts, MetaLoadIDs}) mp := make(map[string][]string) for k := range CacheInstanceToPrefix { - if !excluded.Has(k) { + if !excluded.Has(k) && k != CacheTrendProfiles { mp[k] = []string{MetaAny} } } diff --git a/utils/consts.go b/utils/consts.go index 99b7b6a76..c8850d5a9 100644 --- a/utils/consts.go +++ b/utils/consts.go @@ -70,6 +70,7 @@ var ( CacheStatQueueProfiles: StatQueueProfilePrefix, CacheStatQueues: StatQueuePrefix, CacheSagProfiles: SagsProfilePrefix, + CacheTrendProfiles: TrendsProfilePrefix, CacheThresholdProfiles: ThresholdProfilePrefix, CacheThresholds: ThresholdPrefix, CacheFilters: FilterPrefix, @@ -136,7 +137,7 @@ var ( TBLTPAccountActions: CacheTBLTPAccountActions, TBLTPResources: CacheTBLTPResources, TBLTPStats: CacheTBLTPStats, - TBLTPSars: CacheTBLTPSars, + TBLTPTrends: CacheTBLTPTrends, TBLTPSags: CacheTBLTPSags, TBLTPThresholds: CacheTBLTPThresholds, TBLTPFilters: CacheTBLTPFilters, @@ -306,7 +307,7 @@ const ( ThresholdProfilePrefix = "thp_" StatQueuePrefix = "stq_" SagsProfilePrefix = "sgp_" - SarsProfilePrefix = "srp_" + TrendsProfilePrefix = "trp_" LoadIDPrefix = "lid_" SessionsBackupPrefix = "sbk_" LoadInstKey = "load_history" @@ -403,7 +404,7 @@ const ( MetaRerate = "*rerate" MetaRefund = "*refund" MetaStats = "*stats" - MetaSars = "*sars" + MetaTrends = "*trends" MetaSags = "*sags" MetaResponder = "*responder" MetaCore = "*core" @@ -463,7 +464,7 @@ const ( AccountActions = "AccountActions" Resources = "Resources" Stats = "Stats" - Sars = "Sars" + Trends = "Trends" Filters = "Filters" DispatcherProfiles = "DispatcherProfiles" DispatcherHosts = "DispatcherHosts" @@ -975,7 +976,7 @@ const ( MetaStatQueueProfiles = "*statqueue_profiles" MetaStatQueues = "*statqueues" MetaSagProfiles = "*sag_profiles" - MetaSarProfiles = "*sar_profiles" + MetaTrendProfiles = "*trend_profiles" MetaThresholdProfiles = "*threshold_profiles" MetaRouteProfiles = "*route_profiles" MetaAttributeProfiles = "*attribute_profiles" @@ -1030,7 +1031,7 @@ const ( RouteS = "RouteS" SessionS = "SessionS" StatService = "StatS" - SarS = "SarS" + TrendS = "TrendS" SagS = "SagS" ThresholdS = "ThresholdS" ) @@ -1154,7 +1155,7 @@ const ( TpRoutes = "TpRoutes" TpAttributes = "TpAttributes" TpStats = "TpStats" - TpSars = "TpSars" + TpTrends = "TpTrends" TpSags = "TpSags" TpSharedGroups = "TpSharedGroups" TpRatingProfiles = "TpRatingProfiles" @@ -1180,7 +1181,7 @@ const ( MetaDefaultRatio = "*default_ratio" ThresholdSv1 = "ThresholdSv1" StatSv1 = "StatSv1" - SarSv1 = "SarSv1" + TrendSv1 = "TrendSv1" SagSv1 = "SagSv1" ResourceSv1 = "ResourceSv1" RouteSv1 = "RouteSv1" @@ -1256,7 +1257,7 @@ const ( ReplicatorSv1GetThresholdProfile = "ReplicatorSv1.GetThresholdProfile" ReplicatorSv1GetStatQueueProfile = "ReplicatorSv1.GetStatQueueProfile" ReplicatorSv1GetSagProfile = "ReplicatorSv1.GetSagProfile" - ReplicatorSv1GetSarProfile = "ReplicatorSv1.GetSarProfile" + ReplicatorSv1GetTrendProfile = "ReplicatorSv1.GetTrendProfile" ReplicatorSv1GetTiming = "ReplicatorSv1.GetTiming" ReplicatorSv1GetResource = "ReplicatorSv1.GetResource" ReplicatorSv1GetResourceProfile = "ReplicatorSv1.GetResourceProfile" @@ -1283,7 +1284,7 @@ const ( ReplicatorSv1SetFilter = "ReplicatorSv1.SetFilter" ReplicatorSv1SetStatQueueProfile = "ReplicatorSv1.SetStatQueueProfile" ReplicatorSv1SetSagProfile = "ReplicatorSv1.SetSagProfile" - ReplicatorSv1SetSarProfile = "ReplicatorSv1.SetSarProfile" + ReplicatorSv1SetTrendProfile = "ReplicatorSv1.SetTrendProfile" ReplicatorSv1SetTiming = "ReplicatorSv1.SetTiming" ReplicatorSv1SetResource = "ReplicatorSv1.SetResource" ReplicatorSv1SetResourceProfile = "ReplicatorSv1.SetResourceProfile" @@ -1310,7 +1311,7 @@ const ( ReplicatorSv1RemoveThresholdProfile = "ReplicatorSv1.RemoveThresholdProfile" ReplicatorSv1RemoveStatQueueProfile = "ReplicatorSv1.RemoveStatQueueProfile" ReplicatorSv1RemoveSagProfile = "ReplicatorSv1.RemoveSagProfile" - ReplicatorSv1RemoveSarProfile = "ReplicatorSv1.RemoveSarProfile" + ReplicatorSv1RemoveTrendProfile = "ReplicatorSv1.RemoveTrendProfile" ReplicatorSv1RemoveTiming = "ReplicatorSv1.RemoveTiming" ReplicatorSv1RemoveResource = "ReplicatorSv1.RemoveResource" ReplicatorSv1RemoveResourceProfile = "ReplicatorSv1.RemoveResourceProfile" @@ -1443,9 +1444,9 @@ const ( APIerSv1SetTPSag = "APIerSv1.SetTPSag" APIerSv1GetTPSag = "APIerSv1.GetTPSag" APIerSv1RemoveTPSag = "APIerSv1.RemoveTPSag" - APIerSv1SetTPSar = "APIerSv1.SetTPSar" - APIerSv1GetTPSar = "APIerSv1.GetTPSar" - APIerSv1RemoveTPSar = "APIerSv1.RemoveTPSar" + APIerSv1SetTPTrend = "APIerSv1.SetTPTrend" + APIerSv1GetTPTrend = "APIerSv1.GetTPTrend" + APIerSv1RemoveTPTrend = "APIerSv1.RemoveTPTrend" APIerSv1GetTPDestinationRate = "APIerSv1.GetTPDestinationRate" APIerSv1SetTPRouteProfile = "APIerSv1.SetTPRouteProfile" APIerSv1GetTPRouteProfile = "APIerSv1.GetTPRouteProfile" @@ -1667,13 +1668,13 @@ const ( APIerSv1GetStatQueueProfileIDs = "APIerSv1.GetStatQueueProfileIDs" ) -// SarS APIs +// TrendS APIs const ( - APIerSv1SetSarProfile = "APIerSv1.SetSagProfile" - APIerSv1RemoveSarProfile = "APIerSv1.RemoveSagProfile" - APIerSv1GetSarProfile = "APIerSv1.GetSagProfile" - APIerSv1GetSarProfileIDs = "APIerSv1.GetSagProfileIDs" - SarSv1Ping = "SagSv1.Ping" + APIerSv1SetTrendProfile = "APIerSv1.SetTrendProfile" + APIerSv1RemoveTrendProfile = "APIerSv1.RemoveTrendProfile" + APIerSv1GetTrendProfile = "APIerSv1.GetTrendProfile" + APIerSv1GetTrendProfileIDs = "APIerSv1.GetTrendProfileIDs" + TrendSv1Ping = "TrendSv1.Ping" ) // SagS APIs @@ -1898,7 +1899,7 @@ const ( AccountActionsCsv = "AccountActions.csv" ResourcesCsv = "Resources.csv" StatsCsv = "Stats.csv" - SarsCsv = "Sars.csv" + TrendsCsv = "Trends.csv" SagsCsv = "Sags.csv" ThresholdsCsv = "Thresholds.csv" FiltersCsv = "Filters.csv" @@ -1925,7 +1926,7 @@ const ( TBLTPResources = "tp_resources" TBLTPStats = "tp_stats" TBLTPSags = "tp_sags" - TBLTPSars = "tp_sars" + TBLTPTrends = "tp_trends" TBLTPThresholds = "tp_thresholds" TBLTPFilters = "tp_filters" SessionCostsTBL = "session_costs" @@ -1957,7 +1958,7 @@ const ( CacheStatQueueProfiles = "*statqueue_profiles" CacheStatQueues = "*statqueues" CacheSagProfiles = "*sag_profiles" - CacheSarProfiles = "*sar_profiles" + CacheTrendProfiles = "*trend_profiles" CacheThresholdProfiles = "*threshold_profiles" CacheThresholds = "*thresholds" CacheFilters = "*filters" @@ -2011,7 +2012,7 @@ const ( CacheTBLTPAccountActions = "*tp_account_actions" CacheTBLTPResources = "*tp_resources" CacheTBLTPStats = "*tp_stats" - CacheTBLTPSars = "*tp_sars" + CacheTBLTPTrends = "*tp_trends" CacheTBLTPSags = "*tp_sags" CacheTBLTPThresholds = "*tp_thresholds" CacheTBLTPFilters = "*tp_filters"