diff --git a/apier/v1/filter_indexes.go b/apier/v1/filter_indexes.go index 2c6e8c68b..cd066b8ad 100644 --- a/apier/v1/filter_indexes.go +++ b/apier/v1/filter_indexes.go @@ -19,7 +19,6 @@ along with this program. If not, see package v1 import ( - "fmt" "strings" "github.com/cgrates/cgrates/engine" @@ -257,7 +256,7 @@ func (api *APIerSv1) ComputeFilterIndexes(args utils.ArgsComputeFilterIndexes, r //DispatcherProfile Indexes var dspIndexes *engine.FilterIndexer if args.DispatcherS { - dspIndexes, err = api.computeDispatcherIndexes(args.Tenant, args.Context, nil, transactionID) + dspIndexes, err = engine.ComputeDispatcherIndexes(api.DataManager, args.Tenant, args.Context, nil, transactionID) if err != nil && err != utils.ErrNotFound { return utils.APIErrorHandler(err) } @@ -345,7 +344,7 @@ func (api *APIerSv1) ComputeFilterIndexIDs(args utils.ArgsComputeFilterIndexIDs, return utils.APIErrorHandler(err) } //DispatcherProfile Indexes - dspIndexes, err := api.computeDispatcherIndexes(args.Tenant, args.Context, &args.DispatcherIDs, transactionID) + dspIndexes, err := engine.ComputeDispatcherIndexes(api.DataManager, args.Tenant, args.Context, &args.DispatcherIDs, transactionID) if err != nil && err != utils.ErrNotFound { return utils.APIErrorHandler(err) } @@ -460,88 +459,6 @@ func (api *APIerSv1) ComputeFilterIndexIDs(args utils.ArgsComputeFilterIndexIDs, return nil } -func (api *APIerSv1) computeDispatcherIndexes(tenant, context string, dspIDs *[]string, - transactionID string) (filterIndexer *engine.FilterIndexer, err error) { - var dispatcherIDs []string - var dspIndexes *engine.FilterIndexer - if dspIDs == nil { - ids, err := api.DataManager.DataDB().GetKeysForPrefix(utils.DispatcherProfilePrefix) - if err != nil { - return nil, err - } - for _, id := range ids { - dispatcherIDs = append(dispatcherIDs, strings.Split(id, utils.CONCATENATED_KEY_SEP)[1]) - } - // this will be on ComputeIndexes that contains empty indexes - dspIndexes = engine.NewFilterIndexer(api.DataManager, utils.DispatcherProfilePrefix, - utils.ConcatenatedKey(tenant, context)) - } else { - // this will be on ComputeIndexesIDs that contains the old indexes from the next getter - var oldIDx map[string]utils.StringMap - if oldIDx, err = api.DataManager.GetFilterIndexes(utils.PrefixToIndexCache[utils.DispatcherProfilePrefix], - tenant, utils.EmptyString, nil); err != nil || oldIDx == nil { - dspIndexes = engine.NewFilterIndexer(api.DataManager, utils.DispatcherProfilePrefix, - utils.ConcatenatedKey(tenant, context)) - } else { - dspIndexes = engine.NewFilterIndexerWithIndexes(api.DataManager, utils.DispatcherProfilePrefix, - utils.ConcatenatedKey(tenant, context), oldIDx) - } - dispatcherIDs = *dspIDs - transactionID = utils.NonTransactional - } - for _, id := range dispatcherIDs { - dsp, err := api.DataManager.GetDispatcherProfile(tenant, id, true, false, utils.NonTransactional) - if err != nil { - return nil, err - } - if !utils.IsSliceMember(dsp.Subsystems, context) && context != utils.META_ANY { - continue - } - fltrIDs := make([]string, len(dsp.FilterIDs)) - for i, fltrID := range dsp.FilterIDs { - fltrIDs[i] = fltrID - } - if len(fltrIDs) == 0 { - fltrIDs = []string{utils.META_NONE} - } - for _, fltrID := range fltrIDs { - var fltr *engine.Filter - if fltrID == utils.META_NONE { - fltr = &engine.Filter{ - Tenant: dsp.Tenant, - ID: dsp.ID, - Rules: []*engine.FilterRule{ - { - Type: utils.META_NONE, - Element: utils.META_ANY, - Values: []string{utils.META_ANY}, - }, - }, - } - } else if fltr, err = engine.GetFilter(api.DataManager, dsp.Tenant, fltrID, - true, false, utils.NonTransactional); err != nil { - if err == utils.ErrNotFound { - err = fmt.Errorf("broken reference to filter: %+v for dispatcher: %+v", - fltrID, dsp) - } - return nil, err - } - dspIndexes.IndexTPFilter(engine.FilterToTPFilter(fltr), dsp.ID) - } - } - if transactionID == utils.NonTransactional { - if err := dspIndexes.StoreIndexes(true, transactionID); err != nil { - return nil, err - } - return nil, nil - } else { - if err := dspIndexes.StoreIndexes(false, transactionID); err != nil { - return nil, err - } - } - return dspIndexes, nil -} - func (apierSv1 *APIerSv1) GetAccountActionPlansIndexHealth(args *engine.IndexHealthArgsWith2Ch, reply *engine.AccountActionPlanIHReply) error { rp, err := engine.GetAccountActionPlansIndexHealth(apierSv1.DataManager, args.ObjectCacheLimit, args.IndexCacheLimit, args.ObjectCacheTTL, args.IndexCacheTTL, diff --git a/engine/datamanager.go b/engine/datamanager.go index 10183c186..03b3f29da 100644 --- a/engine/datamanager.go +++ b/engine/datamanager.go @@ -2336,12 +2336,20 @@ func (dm *DataManager) SetDispatcherProfile(dpp *DispatcherProfile, withIndex bo } } } + if err = removeReverseFilterIndexForFilter(dm, utils.CacheDispatcherFilterIndexes, + dpp.Tenant, dpp.ID, dpp.FilterIDs); err != nil { + return + } } for _, ctx := range dpp.Subsystems { if err = createAndIndex(utils.DispatcherProfilePrefix, dpp.Tenant, ctx, dpp.ID, dpp.FilterIDs, dm); err != nil { return } } + if err = addReverseFilterIndexForFilter(dm, utils.CacheDispatcherFilterIndexes, + dpp.Tenant, dpp.ID, dpp.FilterIDs); err != nil { + return + } } if config.CgrConfig().DataDbCfg().Items[utils.MetaDispatcherProfiles].Replicate { var reply string @@ -2373,6 +2381,10 @@ func (dm *DataManager) RemoveDispatcherProfile(tenant, id string, return } } + if err = removeReverseFilterIndexForFilter(dm, utils.CacheDispatcherFilterIndexes, + oldDpp.Tenant, oldDpp.ID, oldDpp.FilterIDs); err != nil { + return + } } if config.CgrConfig().DataDbCfg().Items[utils.MetaDispatcherProfiles].Replicate { var reply string diff --git a/engine/filter_indexes.go b/engine/filter_indexes.go index a320cb958..a00d19e14 100644 --- a/engine/filter_indexes.go +++ b/engine/filter_indexes.go @@ -485,3 +485,85 @@ func ComputeAttributeIndexes(dm *DataManager, tenant, context string, attrIDs *[ } return attrIndexers, nil } + +func ComputeDispatcherIndexes(dm *DataManager, tenant, context string, dspIDs *[]string, + transactionID string) (filterIndexer *FilterIndexer, err error) { + var dispatcherIDs []string + var dspIndexes *FilterIndexer + if dspIDs == nil { + ids, err := dm.DataDB().GetKeysForPrefix(utils.DispatcherProfilePrefix) + if err != nil { + return nil, err + } + for _, id := range ids { + dispatcherIDs = append(dispatcherIDs, strings.Split(id, utils.CONCATENATED_KEY_SEP)[1]) + } + // this will be on ComputeIndexes that contains empty indexes + dspIndexes = NewFilterIndexer(dm, utils.DispatcherProfilePrefix, + utils.ConcatenatedKey(tenant, context)) + } else { + // this will be on ComputeIndexesIDs that contains the old indexes from the next getter + var oldIDx map[string]utils.StringMap + if oldIDx, err = dm.GetFilterIndexes(utils.PrefixToIndexCache[utils.DispatcherProfilePrefix], + tenant, utils.EmptyString, nil); err != nil || oldIDx == nil { + dspIndexes = NewFilterIndexer(dm, utils.DispatcherProfilePrefix, + utils.ConcatenatedKey(tenant, context)) + } else { + dspIndexes = NewFilterIndexerWithIndexes(dm, utils.DispatcherProfilePrefix, + utils.ConcatenatedKey(tenant, context), oldIDx) + } + dispatcherIDs = *dspIDs + transactionID = utils.NonTransactional + } + for _, id := range dispatcherIDs { + dsp, err := dm.GetDispatcherProfile(tenant, id, true, false, utils.NonTransactional) + if err != nil { + return nil, err + } + if !utils.IsSliceMember(dsp.Subsystems, context) && context != utils.META_ANY { + continue + } + fltrIDs := make([]string, len(dsp.FilterIDs)) + for i, fltrID := range dsp.FilterIDs { + fltrIDs[i] = fltrID + } + if len(fltrIDs) == 0 { + fltrIDs = []string{utils.META_NONE} + } + for _, fltrID := range fltrIDs { + var fltr *Filter + if fltrID == utils.META_NONE { + fltr = &Filter{ + Tenant: dsp.Tenant, + ID: dsp.ID, + Rules: []*FilterRule{ + { + Type: utils.META_NONE, + Element: utils.META_ANY, + Values: []string{utils.META_ANY}, + }, + }, + } + } else if fltr, err = GetFilter(dm, dsp.Tenant, fltrID, + true, false, utils.NonTransactional); err != nil { + if err == utils.ErrNotFound { + err = fmt.Errorf("broken reference to filter: %+v for dispatcher: %+v", + fltrID, dsp) + } + return nil, err + } + dspIndexes.IndexTPFilter(FilterToTPFilter(fltr), dsp.ID) + } + } + if transactionID == utils.NonTransactional { + if err := dspIndexes.StoreIndexes(true, transactionID); err != nil { + return nil, err + } + return nil, nil + } else { + if err := dspIndexes.StoreIndexes(false, transactionID); err != nil { + return nil, err + } + } + return dspIndexes, nil +} diff --git a/engine/libindex.go b/engine/libindex.go index e31d2c3d0..fc48430a3 100644 --- a/engine/libindex.go +++ b/engine/libindex.go @@ -29,7 +29,8 @@ import ( var ( filterIndexType = utils.StringMap{ utils.MetaString: true, - utils.MetaPrefix: true} + utils.MetaPrefix: true, + } ) // UpdateFilterIndexes will update the indexes for every reference of a filter that exists in a profile. @@ -202,6 +203,27 @@ func UpdateFilterIndexes(dm *DataManager, tnt string, oldFltr *Filter, newFltr * } } } + case utils.CacheDispatcherFilterIndexes: + dispatcherIDs := index.Slice() + for _, dspID := range dispatcherIDs { + var dpp *DispatcherProfile + if dpp, err = dm.GetDispatcherProfile(newFltr.Tenant, dspID, + true, false, utils.NonTransactional); err != nil { + return + } + for _, subsys := range dpp.Subsystems { + tntSubsys := utils.ConcatenatedKey(newFltr.Tenant, subsys) + if err = removeFilterIndexesForFilter(dm, idxItmType, utils.CacheDispatcherProfiles, + tntSubsys, // remove the indexes for the filter + removeIndexKeys, index); err != nil { + return + } + if _, err = ComputeDispatcherIndexes(dm, newFltr.Tenant, subsys, &dispatcherIDs, + utils.NonTransactional); err != nil { + return err + } + } + } } } return nil