diff --git a/apier/v1/filter_indexes.go b/apier/v1/filter_indexes.go index 03e8df0b7..19eacb210 100644 --- a/apier/v1/filter_indexes.go +++ b/apier/v1/filter_indexes.go @@ -19,13 +19,11 @@ along with this program. If not, see package v1 import ( - "fmt" "strings" "time" "github.com/cgrates/cgrates/engine" "github.com/cgrates/cgrates/utils" - "github.com/cgrates/ltcache" ) type AttrGetFilterIndexes struct { @@ -594,8 +592,8 @@ func (apierSv1 *APIerSv1) ComputeFilterIndexIDs(args *utils.ArgsComputeFilterInd return nil } -func (apierSv1 *APIerSv1) GetAccountActionPlansIndexHealth(args *IndexHealthArgs, reply *IndexHealthReply) error { - rp, err := getAccountActionPlanIndexHealth(apierSv1.DataManager, args.ObjectCacheLimit, args.IndexCacheLimit, +func (apierSv1 *APIerSv1) GetAccountActionPlansIndexHealth(args *engine.IndexHealthArgs, reply *engine.IndexHealthReply) error { + rp, err := engine.GetAccountActionPlanIndexHealth(apierSv1.DataManager, args.ObjectCacheLimit, args.IndexCacheLimit, args.ObjectCacheTTL, args.IndexCacheTTL, args.ObjectCacheStaticTTL, args.IndexCacheStaticTTL) if err != nil { @@ -604,126 +602,3 @@ func (apierSv1 *APIerSv1) GetAccountActionPlansIndexHealth(args *IndexHealthArgs *reply = *rp return nil } - -type IndexHealthArgs struct { - IndexCacheLimit int - IndexCacheTTL time.Duration - IndexCacheStaticTTL bool - - ObjectCacheLimit int - ObjectCacheTTL time.Duration - ObjectCacheStaticTTL bool -} -type IndexHealthReply struct { - MissingObjects []string // list of object that are referenced in indexes but are not found in the dataDB - MissingIndexes map[string][]string // list of missing indexes for each object (the map has the key as the objectID and a list of indexes) - BrokenReferences map[string][]string // list of broken references (the map has the key as the objectID and a list of indexes) -} - -// add cache in args API -func getAccountActionPlanIndexHealth(dm *engine.DataManager, objLimit, indexLimit int, objTTL, indexTTL time.Duration, objStaticTTL, indexStaticTTL bool) (rply *IndexHealthReply, err error) { - // posible errors - missingAP := utils.StringSet{} // the index are present but the action plans are not //missing actionplans - brokenRef := map[string][]string{} // the actionPlans match the index but they are missing the account // broken reference - missingIndex := map[string][]string{} // the indexes are not present but the action plans points to that account // misingAccounts - - // local cache - indexesCache := ltcache.NewCache(objLimit, objTTL, objStaticTTL, nil) - objectsCache := ltcache.NewCache(indexLimit, indexTTL, indexStaticTTL, nil) - - getCachedIndex := func(acntID string) (apIDs []string, err error) { - if x, ok := indexesCache.Get(acntID); ok { - if x == nil { - return nil, utils.ErrNotFound - } - return x.([]string), nil - } - if apIDs, err = dm.GetAccountActionPlans(acntID, true, false, utils.NonTransactional); err != nil { // read from cache but do not write if not there - if err == utils.ErrNotFound { - indexesCache.Set(acntID, nil, nil) - } - return - } - indexesCache.Set(acntID, apIDs, nil) - return - } - - getCachedObject := func(apID string) (obj *engine.ActionPlan, err error) { - if x, ok := objectsCache.Get(apID); ok { - if x == nil { - return nil, utils.ErrNotFound - } - return x.(*engine.ActionPlan), nil - } - if obj, err = dm.GetActionPlan(apID, true, false, utils.NonTransactional); err != nil { // read from cache but do not write if not there - if err == utils.ErrNotFound { - objectsCache.Set(apID, nil, nil) - } - return - } - objectsCache.Set(apID, obj, nil) - return - } - - var acntIDs []string // start with the indexes and check the references - if acntIDs, err = dm.DataDB().GetKeysForPrefix(utils.AccountActionPlansPrefix); err != nil { - err = fmt.Errorf("error <%s> querying keys for accountActionPlans", err.Error()) - return - } - - for _, acntID := range acntIDs { - acntID = strings.TrimPrefix(acntID, utils.AccountActionPlansPrefix) // - var apIDs []string - if apIDs, err = getCachedIndex(acntID); err != nil { // read from cache but do not write if not there - err = fmt.Errorf("error <%s> querying the accountActionPlan: <%v>", err.Error(), acntID) - return - } - for _, apID := range apIDs { - var ap *engine.ActionPlan - if ap, err = getCachedObject(apID); err != nil { - if err != utils.ErrNotFound { - err = fmt.Errorf("error <%s> querying the actionPlan: <%v>", err.Error(), apID) - return - } - missingAP.Add(apID) // not found - continue - - } - if !ap.AccountIDs.HasKey(acntID) { // the action plan exists but doesn't point towards the account we have index - brokenRef[apID] = append(brokenRef[apID], acntID) - } - } - } - - var apIDs []string // we have all the indexes in cache now do a reverse check - if apIDs, err = dm.DataDB().GetKeysForPrefix(utils.ActionPlanPrefix); err != nil { - err = fmt.Errorf("error <%s> querying keys for actionPlans", err.Error()) - return - } - - for _, apID := range apIDs { - apID = strings.TrimPrefix(apID, utils.ActionPlanPrefix) // - var ap *engine.ActionPlan - if ap, err = getCachedObject(apID); err != nil { - err = fmt.Errorf("error <%s> querying the actionPlan: <%v>", err.Error(), apID) - return - } - for acntID := range ap.AccountIDs { - var ids []string - if ids, err = getCachedIndex(acntID); err != nil { // read from cache but do not write if not there - err = fmt.Errorf("error <%s> querying the accountActionPlan: <%v>", err.Error(), acntID) - return - } - if !utils.IsSliceMember(ids, apID) { // the index doesn't exits for this actionPlan - missingIndex[apID] = append(missingIndex[apID], acntID) - } - } - } - - rply = &IndexHealthReply{ - MissingObjects: missingAP.AsSlice(), - MissingIndexes: missingIndex, - BrokenReferences: brokenRef, - } - return -} diff --git a/apier/v1/filter_indexes_health_it_test.go b/apier/v1/filter_indexes_health_it_test.go new file mode 100644 index 000000000..d5174467f --- /dev/null +++ b/apier/v1/filter_indexes_health_it_test.go @@ -0,0 +1,131 @@ +// +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 FIdxTNESS 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 ( + "net/rpc" + "path" + "reflect" + "testing" + "time" + + "github.com/cgrates/cgrates/config" + "github.com/cgrates/cgrates/engine" + "github.com/cgrates/cgrates/utils" +) + +var ( + tFIdxHRpc *rpc.Client + + sTestsFilterIndexesSHealth = []func(t *testing.T){ + testV1FIdxHLoadConfig, + testV1FIdxHdxInitDataDb, + testV1FIdxHResetStorDb, + testV1FIdxHStartEngine, + testV1FIdxHRpcConn, + testV1FIdxHLoadFromFolder, + testV1FIdxHAccountActionPlansHealth, + + testV1FIdxHStopEngine, + } +) + +// Test start here +func TestFIdxHealthIT(t *testing.T) { + switch *dbType { + case utils.MetaInternal: + tSv1ConfDIR = "tutinternal" + case utils.MetaMySQL: + tSv1ConfDIR = "tutmysql" + case utils.MetaMongo: + tSv1ConfDIR = "tutmongo" + case utils.MetaPostgres: + t.SkipNow() + default: + t.Fatal("Unknown Database type") + } + for _, stest := range sTestsFilterIndexesSHealth { + t.Run(tSv1ConfDIR, stest) + } +} + +func testV1FIdxHLoadConfig(t *testing.T) { + tSv1CfgPath = path.Join(*dataDir, "conf", "samples", tSv1ConfDIR) + var err error + if tSv1Cfg, err = config.NewCGRConfigFromPath(tSv1CfgPath); err != nil { + t.Error(err) + } +} + +func testV1FIdxHdxInitDataDb(t *testing.T) { + if err := engine.InitDataDb(tSv1Cfg); err != nil { + t.Fatal(err) + } +} + +// Wipe out the cdr database +func testV1FIdxHResetStorDb(t *testing.T) { + if err := engine.InitStorDb(tSv1Cfg); err != nil { + t.Fatal(err) + } +} + +func testV1FIdxHStartEngine(t *testing.T) { + if _, err := engine.StopStartEngine(tSv1CfgPath, *waitRater); err != nil { + t.Fatal(err) + } +} + +func testV1FIdxHRpcConn(t *testing.T) { + var err error + tFIdxHRpc, err = newRPCClient(tSv1Cfg.ListenCfg()) // We connect over JSON so we can also troubleshoot if needed + if err != nil { + t.Fatal("Could not connect to rater: ", err.Error()) + } +} + +func testV1FIdxHLoadFromFolder(t *testing.T) { + var reply string + attrs := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "tutorial")} + if err := tFIdxHRpc.Call(utils.APIerSv1LoadTariffPlanFromFolder, attrs, &reply); err != nil { + t.Error(err) + } + time.Sleep(100 * time.Millisecond) +} + +func testV1FIdxHAccountActionPlansHealth(t *testing.T) { + var reply engine.IndexHealthReply + if err := tFIdxHRpc.Call(utils.APIerSv1GetAccountActionPlansIndexHealth, engine.IndexHealthArgs{ + IndexCacheLimit: -1, + ObjectCacheLimit: -1, + }, &reply); err != nil { + t.Error(err) + } + exp := engine.IndexHealthReply{} + if !reflect.DeepEqual(exp, reply) { + t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(exp), utils.ToJSON(reply)) + } +} + +func testV1FIdxHStopEngine(t *testing.T) { + if err := engine.KillEngine(100); err != nil { + t.Error(err) + } +} diff --git a/engine/libindex.go b/engine/libindex.go index 0076b29e8..f07c30a4a 100644 --- a/engine/libindex.go +++ b/engine/libindex.go @@ -21,10 +21,12 @@ package engine import ( "fmt" "strings" + "time" "github.com/cgrates/cgrates/config" "github.com/cgrates/cgrates/guardian" "github.com/cgrates/cgrates/utils" + "github.com/cgrates/ltcache" ) var ( @@ -818,3 +820,133 @@ func IsDynamicDPPath(path string) bool { } return false } + +type IndexHealthArgs struct { + IndexCacheLimit int + IndexCacheTTL time.Duration + IndexCacheStaticTTL bool + + ObjectCacheLimit int + ObjectCacheTTL time.Duration + ObjectCacheStaticTTL bool +} + +type IndexHealthReply struct { + MissingObjects []string // list of object that are referenced in indexes but are not found in the dataDB + MissingIndexes map[string][]string // list of missing indexes for each object (the map has the key as the objectID and a list of indexes) + BrokenReferences map[string][]string // list of broken references (the map has the key as the objectID and a list of indexes) +} + +// add cache in args API +func GetAccountActionPlanIndexHealth(dm *DataManager, objLimit, indexLimit int, objTTL, indexTTL time.Duration, objStaticTTL, indexStaticTTL bool) (rply *IndexHealthReply, err error) { + // posible errors + missingAP := utils.StringSet{} // the index are present but the action plans are not //missing actionplans + brokenRef := map[string][]string{} // the actionPlans match the index but they are missing the account // broken reference + missingIndex := map[string][]string{} // the indexes are not present but the action plans points to that account // misingAccounts + + // local cache + indexesCache := ltcache.NewCache(objLimit, objTTL, objStaticTTL, nil) + objectsCache := ltcache.NewCache(indexLimit, indexTTL, indexStaticTTL, nil) + + getCachedIndex := func(acntID string) (apIDs []string, err error) { + if x, ok := indexesCache.Get(acntID); ok { + if x == nil { + return nil, utils.ErrNotFound + } + return x.([]string), nil + } + if apIDs, err = dm.GetAccountActionPlans(acntID, true, false, utils.NonTransactional); err != nil { // read from cache but do not write if not there + if err == utils.ErrNotFound { + indexesCache.Set(acntID, nil, nil) + } + return + } + indexesCache.Set(acntID, apIDs, nil) + return + } + + getCachedObject := func(apID string) (obj *ActionPlan, err error) { + if x, ok := objectsCache.Get(apID); ok { + if x == nil { + return nil, utils.ErrNotFound + } + return x.(*ActionPlan), nil + } + if obj, err = dm.GetActionPlan(apID, true, false, utils.NonTransactional); err != nil { // read from cache but do not write if not there + if err == utils.ErrNotFound { + objectsCache.Set(apID, nil, nil) + } + return + } + objectsCache.Set(apID, obj, nil) + return + } + + var acntIDs []string // start with the indexes and check the references + if acntIDs, err = dm.DataDB().GetKeysForPrefix(utils.AccountActionPlansPrefix); err != nil { + err = fmt.Errorf("error <%s> querying keys for accountActionPlans", err.Error()) + return + } + + for _, acntID := range acntIDs { + acntID = strings.TrimPrefix(acntID, utils.AccountActionPlansPrefix) // + var apIDs []string + if apIDs, err = getCachedIndex(acntID); err != nil { // read from cache but do not write if not there + err = fmt.Errorf("error <%s> querying the accountActionPlan: <%v>", err.Error(), acntID) + return + } + for _, apID := range apIDs { + var ap *ActionPlan + if ap, err = getCachedObject(apID); err != nil { + if err != utils.ErrNotFound { + err = fmt.Errorf("error <%s> querying the actionPlan: <%v>", err.Error(), apID) + return + } + err = nil + missingAP.Add(apID) // not found + continue + + } + if !ap.AccountIDs.HasKey(acntID) { // the action plan exists but doesn't point towards the account we have index + brokenRef[apID] = append(brokenRef[apID], acntID) + } + } + } + + var apIDs []string // we have all the indexes in cache now do a reverse check + if apIDs, err = dm.DataDB().GetKeysForPrefix(utils.ActionPlanPrefix); err != nil { + err = fmt.Errorf("error <%s> querying keys for actionPlans", err.Error()) + return + } + + for _, apID := range apIDs { + apID = strings.TrimPrefix(apID, utils.ActionPlanPrefix) // + var ap *ActionPlan + if ap, err = getCachedObject(apID); err != nil { + err = fmt.Errorf("error <%s> querying the actionPlan: <%v>", err.Error(), apID) + return + } + for acntID := range ap.AccountIDs { + var ids []string + if ids, err = getCachedIndex(acntID); err != nil { // read from cache but do not write if not there + if err != utils.ErrNotFound { + err = fmt.Errorf("error <%s> querying the accountActionPlan: <%v>", err.Error(), acntID) + return + } + err = nil + brokenRef[apID] = append(brokenRef[apID], acntID) + continue + } + if !utils.IsSliceMember(ids, apID) { // the index doesn't exits for this actionPlan + missingIndex[apID] = append(missingIndex[apID], acntID) + } + } + } + + rply = &IndexHealthReply{ + MissingObjects: missingAP.AsSlice(), + MissingIndexes: missingIndex, + BrokenReferences: brokenRef, + } + return +} diff --git a/engine/z_libindex_health_test.go b/engine/z_libindex_health_test.go new file mode 100644 index 000000000..a3466e4f0 --- /dev/null +++ b/engine/z_libindex_health_test.go @@ -0,0 +1,45 @@ +/* +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 engine + +/* +func TestHealthAccountAction(t *testing.T) { + Cache.Clear(nil) + cfg := config.NewDefaultCGRConfig() + db := NewInternalDB(nil, nil, true) + dm := NewDataManager(db, cfg.CacheCfg(), nil) + + if err := dm.SetAccountActionPlans("1001", []string{"AP1", "AP2"}, true); err != nil { + t.Fatal(err) + } + if err := dm.SetActionPlan("AP2", &ActionPlan{ + Id: "AP2", + AccountIDs: utils.NewStringMap("1002"), + ActionTimings: []*ActionTiming{{}}, + }, true, utils.NonTransactional); err != nil { + t.Fatal(err) + } + if rply, err := GetAccountActionPlanIndexHealth(dm, -1, -1, -1, -1, false, false); err != nil { + t.Fatal(err) + } else { + t.Error(utils.ToJSON(rply)) + } + +} +*/ diff --git a/utils/consts.go b/utils/consts.go index 312064756..9819d5d00 100644 --- a/utils/consts.go +++ b/utils/consts.go @@ -1269,173 +1269,174 @@ const ( // APIerSv1 APIs const ( - ApierV1 = "ApierV1" - ApierV2 = "ApierV2" - APIerSv1 = "APIerSv1" - APIerSv1ComputeFilterIndexes = "APIerSv1.ComputeFilterIndexes" - APIerSv1ComputeFilterIndexIDs = "APIerSv1.ComputeFilterIndexIDs" - APIerSv1Ping = "APIerSv1.Ping" - APIerSv1SetDispatcherProfile = "APIerSv1.SetDispatcherProfile" - APIerSv1GetDispatcherProfile = "APIerSv1.GetDispatcherProfile" - APIerSv1GetDispatcherProfileIDs = "APIerSv1.GetDispatcherProfileIDs" - APIerSv1RemoveDispatcherProfile = "APIerSv1.RemoveDispatcherProfile" - APIerSv1SetBalances = "APIerSv1.SetBalances" - APIerSv1SetDispatcherHost = "APIerSv1.SetDispatcherHost" - APIerSv1GetDispatcherHost = "APIerSv1.GetDispatcherHost" - APIerSv1GetDispatcherHostIDs = "APIerSv1.GetDispatcherHostIDs" - APIerSv1RemoveDispatcherHost = "APIerSv1.RemoveDispatcherHost" - APIerSv1GetEventCost = "APIerSv1.GetEventCost" - APIerSv1LoadTariffPlanFromFolder = "APIerSv1.LoadTariffPlanFromFolder" - APIerSv1ExportToFolder = "APIerSv1.ExportToFolder" - APIerSv1GetCost = "APIerSv1.GetCost" - APIerSv1SetBalance = "APIerSv1.SetBalance" - APIerSv1GetFilter = "APIerSv1.GetFilter" - APIerSv1GetFilterIndexes = "APIerSv1.GetFilterIndexes" - APIerSv1RemoveFilterIndexes = "APIerSv1.RemoveFilterIndexes" - APIerSv1RemoveFilter = "APIerSv1.RemoveFilter" - APIerSv1SetFilter = "APIerSv1.SetFilter" - APIerSv1GetFilterIDs = "APIerSv1.GetFilterIDs" - APIerSv1GetRatingProfile = "APIerSv1.GetRatingProfile" - APIerSv1RemoveRatingProfile = "APIerSv1.RemoveRatingProfile" - APIerSv1SetRatingProfile = "APIerSv1.SetRatingProfile" - APIerSv1GetRatingProfileIDs = "APIerSv1.GetRatingProfileIDs" - APIerSv1SetDataDBVersions = "APIerSv1.SetDataDBVersions" - APIerSv1SetStorDBVersions = "APIerSv1.SetStorDBVersions" - APIerSv1GetAccountActionPlan = "APIerSv1.GetAccountActionPlan" - APIerSv1ComputeActionPlanIndexes = "APIerSv1.ComputeActionPlanIndexes" - APIerSv1GetActions = "APIerSv1.GetActions" - APIerSv1GetActionPlan = "APIerSv1.GetActionPlan" - APIerSv1GetActionPlanIDs = "APIerSv1.GetActionPlanIDs" - APIerSv1GetRatingPlanIDs = "APIerSv1.GetRatingPlanIDs" - APIerSv1GetRatingPlan = "APIerSv1.GetRatingPlan" - APIerSv1RemoveRatingPlan = "APIerSv1.RemoveRatingPlan" - APIerSv1GetDestination = "APIerSv1.GetDestination" - APIerSv1RemoveDestination = "APIerSv1.RemoveDestination" - APIerSv1GetReverseDestination = "APIerSv1.GetReverseDestination" - APIerSv1AddBalance = "APIerSv1.AddBalance" - APIerSv1DebitBalance = "APIerSv1.DebitBalance" - APIerSv1SetAccount = "APIerSv1.SetAccount" - APIerSv1GetAccountsCount = "APIerSv1.GetAccountsCount" - APIerSv1GetDataDBVersions = "APIerSv1.GetDataDBVersions" - APIerSv1GetStorDBVersions = "APIerSv1.GetStorDBVersions" - APIerSv1GetCDRs = "APIerSv1.GetCDRs" - APIerSv1GetTPAccountActions = "APIerSv1.GetTPAccountActions" - APIerSv1SetTPAccountActions = "APIerSv1.SetTPAccountActions" - APIerSv1GetTPAccountActionsByLoadId = "APIerSv1.GetTPAccountActionsByLoadId" - APIerSv1GetTPAccountActionLoadIds = "APIerSv1.GetTPAccountActionLoadIds" - APIerSv1GetTPAccountActionIds = "APIerSv1.GetTPAccountActionIds" - APIerSv1RemoveTPAccountActions = "APIerSv1.RemoveTPAccountActions" - APIerSv1GetTPActionPlan = "APIerSv1.GetTPActionPlan" - APIerSv1SetTPActionPlan = "APIerSv1.SetTPActionPlan" - APIerSv1GetTPActionPlanIds = "APIerSv1.GetTPActionPlanIds" - APIerSv1SetTPActionTriggers = "APIerSv1.SetTPActionTriggers" - APIerSv1GetTPActionTriggers = "APIerSv1.GetTPActionTriggers" - APIerSv1RemoveTPActionTriggers = "APIerSv1.RemoveTPActionTriggers" - APIerSv1GetTPActionTriggerIds = "APIerSv1.GetTPActionTriggerIds" - APIerSv1GetTPActions = "APIerSv1.GetTPActions" - APIerSv1RemoveTPActionPlan = "APIerSv1.RemoveTPActionPlan" - APIerSv1GetTPAttributeProfile = "APIerSv1.GetTPAttributeProfile" - APIerSv1SetTPAttributeProfile = "APIerSv1.SetTPAttributeProfile" - APIerSv1GetTPAttributeProfileIds = "APIerSv1.GetTPAttributeProfileIds" - APIerSv1RemoveTPAttributeProfile = "APIerSv1.RemoveTPAttributeProfile" - APIerSv1GetTPCharger = "APIerSv1.GetTPCharger" - APIerSv1SetTPCharger = "APIerSv1.SetTPCharger" - APIerSv1RemoveTPCharger = "APIerSv1.RemoveTPCharger" - APIerSv1GetTPChargerIDs = "APIerSv1.GetTPChargerIDs" - APIerSv1SetTPFilterProfile = "APIerSv1.SetTPFilterProfile" - APIerSv1GetTPFilterProfile = "APIerSv1.GetTPFilterProfile" - APIerSv1GetTPFilterProfileIds = "APIerSv1.GetTPFilterProfileIds" - APIerSv1RemoveTPFilterProfile = "APIerSv1.RemoveTPFilterProfile" - APIerSv1GetTPDestination = "APIerSv1.GetTPDestination" - APIerSv1SetTPDestination = "APIerSv1.SetTPDestination" - APIerSv1GetTPDestinationIDs = "APIerSv1.GetTPDestinationIDs" - APIerSv1RemoveTPDestination = "APIerSv1.RemoveTPDestination" - APIerSv1GetTPResource = "APIerSv1.GetTPResource" - APIerSv1SetTPResource = "APIerSv1.SetTPResource" - APIerSv1RemoveTPResource = "APIerSv1.RemoveTPResource" - APIerSv1SetTPRate = "APIerSv1.SetTPRate" - APIerSv1GetTPRate = "APIerSv1.GetTPRate" - APIerSv1RemoveTPRate = "APIerSv1.RemoveTPRate" - APIerSv1GetTPRateIds = "APIerSv1.GetTPRateIds" - APIerSv1SetTPThreshold = "APIerSv1.SetTPThreshold" - APIerSv1GetTPThreshold = "APIerSv1.GetTPThreshold" - APIerSv1GetTPThresholdIDs = "APIerSv1.GetTPThresholdIDs" - APIerSv1RemoveTPThreshold = "APIerSv1.RemoveTPThreshold" - APIerSv1SetTPStat = "APIerSv1.SetTPStat" - APIerSv1GetTPStat = "APIerSv1.GetTPStat" - APIerSv1RemoveTPStat = "APIerSv1.RemoveTPStat" - APIerSv1GetTPDestinationRate = "APIerSv1.GetTPDestinationRate" - APIerSv1SetTPRouteProfile = "APIerSv1.SetTPRouteProfile" - APIerSv1GetTPRouteProfile = "APIerSv1.GetTPRouteProfile" - APIerSv1GetTPRouteProfileIDs = "APIerSv1.GetTPRouteProfileIDs" - APIerSv1RemoveTPRouteProfile = "APIerSv1.RemoveTPRouteProfile" - APIerSv1GetTPDispatcherProfile = "APIerSv1.GetTPDispatcherProfile" - APIerSv1SetTPDispatcherProfile = "APIerSv1.SetTPDispatcherProfile" - APIerSv1RemoveTPDispatcherProfile = "APIerSv1.RemoveTPDispatcherProfile" - APIerSv1GetTPDispatcherProfileIDs = "APIerSv1.GetTPDispatcherProfileIDs" - APIerSv1GetTPSharedGroups = "APIerSv1.GetTPSharedGroups" - APIerSv1SetTPSharedGroups = "APIerSv1.SetTPSharedGroups" - APIerSv1GetTPSharedGroupIds = "APIerSv1.GetTPSharedGroupIds" - APIerSv1RemoveTPSharedGroups = "APIerSv1.RemoveTPSharedGroups" - APIerSv1ExportCDRs = "APIerSv1.ExportCDRs" - APIerSv1GetTPRatingPlan = "APIerSv1.GetTPRatingPlan" - APIerSv1SetTPRatingPlan = "APIerSv1.SetTPRatingPlan" - APIerSv1GetTPRatingPlanIds = "APIerSv1.GetTPRatingPlanIds" - APIerSv1RemoveTPRatingPlan = "APIerSv1.RemoveTPRatingPlan" - APIerSv1SetTPActions = "APIerSv1.SetTPActions" - APIerSv1GetTPActionIds = "APIerSv1.GetTPActionIds" - APIerSv1RemoveTPActions = "APIerSv1.RemoveTPActions" - APIerSv1SetActionPlan = "APIerSv1.SetActionPlan" - APIerSv1ExecuteAction = "APIerSv1.ExecuteAction" - APIerSv1SetTPRatingProfile = "APIerSv1.SetTPRatingProfile" - APIerSv1GetTPRatingProfile = "APIerSv1.GetTPRatingProfile" - APIerSv1RemoveTPRatingProfile = "APIerSv1.RemoveTPRatingProfile" - APIerSv1SetTPDestinationRate = "APIerSv1.SetTPDestinationRate" - APIerSv1GetTPRatingProfileLoadIds = "APIerSv1.GetTPRatingProfileLoadIds" - APIerSv1GetTPRatingProfilesByLoadID = "APIerSv1.GetTPRatingProfilesByLoadID" - APIerSv1GetTPRatingProfileIds = "APIerSv1.GetTPRatingProfileIds" - APIerSv1GetTPDestinationRateIds = "APIerSv1.GetTPDestinationRateIds" - APIerSv1RemoveTPDestinationRate = "APIerSv1.RemoveTPDestinationRate" - APIerSv1ImportTariffPlanFromFolder = "APIerSv1.ImportTariffPlanFromFolder" - APIerSv1ExportTPToFolder = "APIerSv1.ExportTPToFolder" - APIerSv1LoadRatingPlan = "APIerSv1.LoadRatingPlan" - APIerSv1LoadRatingProfile = "APIerSv1.LoadRatingProfile" - APIerSv1LoadAccountActions = "APIerSv1.LoadAccountActions" - APIerSv1SetActions = "APIerSv1.SetActions" - APIerSv1AddTriggeredAction = "APIerSv1.AddTriggeredAction" - APIerSv1GetAccountActionTriggers = "APIerSv1.GetAccountActionTriggers" - APIerSv1AddAccountActionTriggers = "APIerSv1.AddAccountActionTriggers" - APIerSv1ResetAccountActionTriggers = "APIerSv1.ResetAccountActionTriggers" - APIerSv1SetAccountActionTriggers = "APIerSv1.SetAccountActionTriggers" - APIerSv1RemoveAccountActionTriggers = "APIerSv1.RemoveAccountActionTriggers" - APIerSv1GetScheduledActions = "APIerSv1.GetScheduledActions" - APIerSv1RemoveActionTiming = "APIerSv1.RemoveActionTiming" - APIerSv1ComputeReverseDestinations = "APIerSv1.ComputeReverseDestinations" - APIerSv1ComputeAccountActionPlans = "APIerSv1.ComputeAccountActionPlans" - APIerSv1SetDestination = "APIerSv1.SetDestination" - APIerSv1GetDataCost = "APIerSv1.GetDataCost" - APIerSv1ReplayFailedPosts = "APIerSv1.ReplayFailedPosts" - APIerSv1RemoveAccount = "APIerSv1.RemoveAccount" - APIerSv1DebitUsage = "APIerSv1.DebitUsage" - APIerSv1GetCacheStats = "APIerSv1.GetCacheStats" - APIerSv1ReloadCache = "APIerSv1.ReloadCache" - APIerSv1GetActionTriggers = "APIerSv1.GetActionTriggers" - APIerSv1SetActionTrigger = "APIerSv1.SetActionTrigger" - APIerSv1RemoveActionPlan = "APIerSv1.RemoveActionPlan" - APIerSv1RemoveActions = "APIerSv1.RemoveActions" - APIerSv1RemoveBalances = "APIerSv1.RemoveBalances" - APIerSv1GetLoadHistory = "APIerSv1.GetLoadHistory" - APIerSv1GetLoadIDs = "APIerSv1.GetLoadIDs" - APIerSv1GetLoadTimes = "APIerSv1.GetLoadTimes" - APIerSv1ExecuteScheduledActions = "APIerSv1.ExecuteScheduledActions" - APIerSv1GetSharedGroup = "APIerSv1.GetSharedGroup" - APIerSv1RemoveActionTrigger = "APIerSv1.RemoveActionTrigger" - APIerSv1GetAccount = "APIerSv1.GetAccount" - APIerSv1GetAttributeProfileCount = "APIerSv1.GetAttributeProfileCount" - APIerSv1GetMaxUsage = "APIerSv1.GetMaxUsage" - APIerSv1GetTiming = "APIerSv1.GetTiming" - APIerSv1SetTiming = "APIerSv1.SetTiming" - APIerSv1RemoveTiming = "APIerSv1.RemoveTiming" + ApierV1 = "ApierV1" + ApierV2 = "ApierV2" + APIerSv1 = "APIerSv1" + APIerSv1ComputeFilterIndexes = "APIerSv1.ComputeFilterIndexes" + APIerSv1ComputeFilterIndexIDs = "APIerSv1.ComputeFilterIndexIDs" + APIerSv1GetAccountActionPlansIndexHealth = "APIerSv1.GetAccountActionPlansIndexHealth" + APIerSv1Ping = "APIerSv1.Ping" + APIerSv1SetDispatcherProfile = "APIerSv1.SetDispatcherProfile" + APIerSv1GetDispatcherProfile = "APIerSv1.GetDispatcherProfile" + APIerSv1GetDispatcherProfileIDs = "APIerSv1.GetDispatcherProfileIDs" + APIerSv1RemoveDispatcherProfile = "APIerSv1.RemoveDispatcherProfile" + APIerSv1SetBalances = "APIerSv1.SetBalances" + APIerSv1SetDispatcherHost = "APIerSv1.SetDispatcherHost" + APIerSv1GetDispatcherHost = "APIerSv1.GetDispatcherHost" + APIerSv1GetDispatcherHostIDs = "APIerSv1.GetDispatcherHostIDs" + APIerSv1RemoveDispatcherHost = "APIerSv1.RemoveDispatcherHost" + APIerSv1GetEventCost = "APIerSv1.GetEventCost" + APIerSv1LoadTariffPlanFromFolder = "APIerSv1.LoadTariffPlanFromFolder" + APIerSv1ExportToFolder = "APIerSv1.ExportToFolder" + APIerSv1GetCost = "APIerSv1.GetCost" + APIerSv1SetBalance = "APIerSv1.SetBalance" + APIerSv1GetFilter = "APIerSv1.GetFilter" + APIerSv1GetFilterIndexes = "APIerSv1.GetFilterIndexes" + APIerSv1RemoveFilterIndexes = "APIerSv1.RemoveFilterIndexes" + APIerSv1RemoveFilter = "APIerSv1.RemoveFilter" + APIerSv1SetFilter = "APIerSv1.SetFilter" + APIerSv1GetFilterIDs = "APIerSv1.GetFilterIDs" + APIerSv1GetRatingProfile = "APIerSv1.GetRatingProfile" + APIerSv1RemoveRatingProfile = "APIerSv1.RemoveRatingProfile" + APIerSv1SetRatingProfile = "APIerSv1.SetRatingProfile" + APIerSv1GetRatingProfileIDs = "APIerSv1.GetRatingProfileIDs" + APIerSv1SetDataDBVersions = "APIerSv1.SetDataDBVersions" + APIerSv1SetStorDBVersions = "APIerSv1.SetStorDBVersions" + APIerSv1GetAccountActionPlan = "APIerSv1.GetAccountActionPlan" + APIerSv1ComputeActionPlanIndexes = "APIerSv1.ComputeActionPlanIndexes" + APIerSv1GetActions = "APIerSv1.GetActions" + APIerSv1GetActionPlan = "APIerSv1.GetActionPlan" + APIerSv1GetActionPlanIDs = "APIerSv1.GetActionPlanIDs" + APIerSv1GetRatingPlanIDs = "APIerSv1.GetRatingPlanIDs" + APIerSv1GetRatingPlan = "APIerSv1.GetRatingPlan" + APIerSv1RemoveRatingPlan = "APIerSv1.RemoveRatingPlan" + APIerSv1GetDestination = "APIerSv1.GetDestination" + APIerSv1RemoveDestination = "APIerSv1.RemoveDestination" + APIerSv1GetReverseDestination = "APIerSv1.GetReverseDestination" + APIerSv1AddBalance = "APIerSv1.AddBalance" + APIerSv1DebitBalance = "APIerSv1.DebitBalance" + APIerSv1SetAccount = "APIerSv1.SetAccount" + APIerSv1GetAccountsCount = "APIerSv1.GetAccountsCount" + APIerSv1GetDataDBVersions = "APIerSv1.GetDataDBVersions" + APIerSv1GetStorDBVersions = "APIerSv1.GetStorDBVersions" + APIerSv1GetCDRs = "APIerSv1.GetCDRs" + APIerSv1GetTPAccountActions = "APIerSv1.GetTPAccountActions" + APIerSv1SetTPAccountActions = "APIerSv1.SetTPAccountActions" + APIerSv1GetTPAccountActionsByLoadId = "APIerSv1.GetTPAccountActionsByLoadId" + APIerSv1GetTPAccountActionLoadIds = "APIerSv1.GetTPAccountActionLoadIds" + APIerSv1GetTPAccountActionIds = "APIerSv1.GetTPAccountActionIds" + APIerSv1RemoveTPAccountActions = "APIerSv1.RemoveTPAccountActions" + APIerSv1GetTPActionPlan = "APIerSv1.GetTPActionPlan" + APIerSv1SetTPActionPlan = "APIerSv1.SetTPActionPlan" + APIerSv1GetTPActionPlanIds = "APIerSv1.GetTPActionPlanIds" + APIerSv1SetTPActionTriggers = "APIerSv1.SetTPActionTriggers" + APIerSv1GetTPActionTriggers = "APIerSv1.GetTPActionTriggers" + APIerSv1RemoveTPActionTriggers = "APIerSv1.RemoveTPActionTriggers" + APIerSv1GetTPActionTriggerIds = "APIerSv1.GetTPActionTriggerIds" + APIerSv1GetTPActions = "APIerSv1.GetTPActions" + APIerSv1RemoveTPActionPlan = "APIerSv1.RemoveTPActionPlan" + APIerSv1GetTPAttributeProfile = "APIerSv1.GetTPAttributeProfile" + APIerSv1SetTPAttributeProfile = "APIerSv1.SetTPAttributeProfile" + APIerSv1GetTPAttributeProfileIds = "APIerSv1.GetTPAttributeProfileIds" + APIerSv1RemoveTPAttributeProfile = "APIerSv1.RemoveTPAttributeProfile" + APIerSv1GetTPCharger = "APIerSv1.GetTPCharger" + APIerSv1SetTPCharger = "APIerSv1.SetTPCharger" + APIerSv1RemoveTPCharger = "APIerSv1.RemoveTPCharger" + APIerSv1GetTPChargerIDs = "APIerSv1.GetTPChargerIDs" + APIerSv1SetTPFilterProfile = "APIerSv1.SetTPFilterProfile" + APIerSv1GetTPFilterProfile = "APIerSv1.GetTPFilterProfile" + APIerSv1GetTPFilterProfileIds = "APIerSv1.GetTPFilterProfileIds" + APIerSv1RemoveTPFilterProfile = "APIerSv1.RemoveTPFilterProfile" + APIerSv1GetTPDestination = "APIerSv1.GetTPDestination" + APIerSv1SetTPDestination = "APIerSv1.SetTPDestination" + APIerSv1GetTPDestinationIDs = "APIerSv1.GetTPDestinationIDs" + APIerSv1RemoveTPDestination = "APIerSv1.RemoveTPDestination" + APIerSv1GetTPResource = "APIerSv1.GetTPResource" + APIerSv1SetTPResource = "APIerSv1.SetTPResource" + APIerSv1RemoveTPResource = "APIerSv1.RemoveTPResource" + APIerSv1SetTPRate = "APIerSv1.SetTPRate" + APIerSv1GetTPRate = "APIerSv1.GetTPRate" + APIerSv1RemoveTPRate = "APIerSv1.RemoveTPRate" + APIerSv1GetTPRateIds = "APIerSv1.GetTPRateIds" + APIerSv1SetTPThreshold = "APIerSv1.SetTPThreshold" + APIerSv1GetTPThreshold = "APIerSv1.GetTPThreshold" + APIerSv1GetTPThresholdIDs = "APIerSv1.GetTPThresholdIDs" + APIerSv1RemoveTPThreshold = "APIerSv1.RemoveTPThreshold" + APIerSv1SetTPStat = "APIerSv1.SetTPStat" + APIerSv1GetTPStat = "APIerSv1.GetTPStat" + APIerSv1RemoveTPStat = "APIerSv1.RemoveTPStat" + APIerSv1GetTPDestinationRate = "APIerSv1.GetTPDestinationRate" + APIerSv1SetTPRouteProfile = "APIerSv1.SetTPRouteProfile" + APIerSv1GetTPRouteProfile = "APIerSv1.GetTPRouteProfile" + APIerSv1GetTPRouteProfileIDs = "APIerSv1.GetTPRouteProfileIDs" + APIerSv1RemoveTPRouteProfile = "APIerSv1.RemoveTPRouteProfile" + APIerSv1GetTPDispatcherProfile = "APIerSv1.GetTPDispatcherProfile" + APIerSv1SetTPDispatcherProfile = "APIerSv1.SetTPDispatcherProfile" + APIerSv1RemoveTPDispatcherProfile = "APIerSv1.RemoveTPDispatcherProfile" + APIerSv1GetTPDispatcherProfileIDs = "APIerSv1.GetTPDispatcherProfileIDs" + APIerSv1GetTPSharedGroups = "APIerSv1.GetTPSharedGroups" + APIerSv1SetTPSharedGroups = "APIerSv1.SetTPSharedGroups" + APIerSv1GetTPSharedGroupIds = "APIerSv1.GetTPSharedGroupIds" + APIerSv1RemoveTPSharedGroups = "APIerSv1.RemoveTPSharedGroups" + APIerSv1ExportCDRs = "APIerSv1.ExportCDRs" + APIerSv1GetTPRatingPlan = "APIerSv1.GetTPRatingPlan" + APIerSv1SetTPRatingPlan = "APIerSv1.SetTPRatingPlan" + APIerSv1GetTPRatingPlanIds = "APIerSv1.GetTPRatingPlanIds" + APIerSv1RemoveTPRatingPlan = "APIerSv1.RemoveTPRatingPlan" + APIerSv1SetTPActions = "APIerSv1.SetTPActions" + APIerSv1GetTPActionIds = "APIerSv1.GetTPActionIds" + APIerSv1RemoveTPActions = "APIerSv1.RemoveTPActions" + APIerSv1SetActionPlan = "APIerSv1.SetActionPlan" + APIerSv1ExecuteAction = "APIerSv1.ExecuteAction" + APIerSv1SetTPRatingProfile = "APIerSv1.SetTPRatingProfile" + APIerSv1GetTPRatingProfile = "APIerSv1.GetTPRatingProfile" + APIerSv1RemoveTPRatingProfile = "APIerSv1.RemoveTPRatingProfile" + APIerSv1SetTPDestinationRate = "APIerSv1.SetTPDestinationRate" + APIerSv1GetTPRatingProfileLoadIds = "APIerSv1.GetTPRatingProfileLoadIds" + APIerSv1GetTPRatingProfilesByLoadID = "APIerSv1.GetTPRatingProfilesByLoadID" + APIerSv1GetTPRatingProfileIds = "APIerSv1.GetTPRatingProfileIds" + APIerSv1GetTPDestinationRateIds = "APIerSv1.GetTPDestinationRateIds" + APIerSv1RemoveTPDestinationRate = "APIerSv1.RemoveTPDestinationRate" + APIerSv1ImportTariffPlanFromFolder = "APIerSv1.ImportTariffPlanFromFolder" + APIerSv1ExportTPToFolder = "APIerSv1.ExportTPToFolder" + APIerSv1LoadRatingPlan = "APIerSv1.LoadRatingPlan" + APIerSv1LoadRatingProfile = "APIerSv1.LoadRatingProfile" + APIerSv1LoadAccountActions = "APIerSv1.LoadAccountActions" + APIerSv1SetActions = "APIerSv1.SetActions" + APIerSv1AddTriggeredAction = "APIerSv1.AddTriggeredAction" + APIerSv1GetAccountActionTriggers = "APIerSv1.GetAccountActionTriggers" + APIerSv1AddAccountActionTriggers = "APIerSv1.AddAccountActionTriggers" + APIerSv1ResetAccountActionTriggers = "APIerSv1.ResetAccountActionTriggers" + APIerSv1SetAccountActionTriggers = "APIerSv1.SetAccountActionTriggers" + APIerSv1RemoveAccountActionTriggers = "APIerSv1.RemoveAccountActionTriggers" + APIerSv1GetScheduledActions = "APIerSv1.GetScheduledActions" + APIerSv1RemoveActionTiming = "APIerSv1.RemoveActionTiming" + APIerSv1ComputeReverseDestinations = "APIerSv1.ComputeReverseDestinations" + APIerSv1ComputeAccountActionPlans = "APIerSv1.ComputeAccountActionPlans" + APIerSv1SetDestination = "APIerSv1.SetDestination" + APIerSv1GetDataCost = "APIerSv1.GetDataCost" + APIerSv1ReplayFailedPosts = "APIerSv1.ReplayFailedPosts" + APIerSv1RemoveAccount = "APIerSv1.RemoveAccount" + APIerSv1DebitUsage = "APIerSv1.DebitUsage" + APIerSv1GetCacheStats = "APIerSv1.GetCacheStats" + APIerSv1ReloadCache = "APIerSv1.ReloadCache" + APIerSv1GetActionTriggers = "APIerSv1.GetActionTriggers" + APIerSv1SetActionTrigger = "APIerSv1.SetActionTrigger" + APIerSv1RemoveActionPlan = "APIerSv1.RemoveActionPlan" + APIerSv1RemoveActions = "APIerSv1.RemoveActions" + APIerSv1RemoveBalances = "APIerSv1.RemoveBalances" + APIerSv1GetLoadHistory = "APIerSv1.GetLoadHistory" + APIerSv1GetLoadIDs = "APIerSv1.GetLoadIDs" + APIerSv1GetLoadTimes = "APIerSv1.GetLoadTimes" + APIerSv1ExecuteScheduledActions = "APIerSv1.ExecuteScheduledActions" + APIerSv1GetSharedGroup = "APIerSv1.GetSharedGroup" + APIerSv1RemoveActionTrigger = "APIerSv1.RemoveActionTrigger" + APIerSv1GetAccount = "APIerSv1.GetAccount" + APIerSv1GetAttributeProfileCount = "APIerSv1.GetAttributeProfileCount" + APIerSv1GetMaxUsage = "APIerSv1.GetMaxUsage" + APIerSv1GetTiming = "APIerSv1.GetTiming" + APIerSv1SetTiming = "APIerSv1.SetTiming" + APIerSv1RemoveTiming = "APIerSv1.RemoveTiming" ) // APIerSv1 TP APIs