mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-25 17:18:44 +05:00
Moved GetAccountActionPlansIndexHealth in engine
This commit is contained in:
committed by
Dan Christian Bogos
parent
5e7860eede
commit
1fc27c2d5b
@@ -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
|
||||
}
|
||||
|
||||
45
engine/z_libindex_health_test.go
Normal file
45
engine/z_libindex_health_test.go
Normal file
@@ -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 <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
Reference in New Issue
Block a user