New index update case for rate profile rate + tests

This commit is contained in:
porosnicuadrian
2021-03-11 13:58:42 +02:00
committed by Dan Christian Bogos
parent 3188b94df8
commit 73ee1b0dee
2 changed files with 127 additions and 5 deletions

View File

@@ -19,6 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
package engine
import (
"errors"
"fmt"
"strings"
@@ -752,6 +753,53 @@ func UpdateFilterIndex(dm *DataManager, oldFlt, newFlt *Filter) (err error) {
}); err != nil && err != utils.ErrNotFound {
return utils.APIErrorHandler(err)
}
case utils.CacheRateFilterIndexes:
itemIDs := make(map[string]utils.StringSet)
for itemID := range indx {
idSplit := strings.SplitN(itemID, utils.ConcatenatedKeySep, 2)
if len(idSplit) < 2 {
return errors.New("Expected to be 2 values")
}
if itemIDs[idSplit[1]] == nil {
itemIDs[idSplit[1]] = make(utils.StringSet)
}
itemIDs[idSplit[1]].Add(idSplit[0])
}
for rpID, ids := range itemIDs {
tntCtx := utils.ConcatenatedKey(newFlt.Tenant, rpID)
if err = removeFilterIndexesForFilter(dm, idxItmType, tntCtx,
removeIndexKeys, ids); err != nil {
return
}
var rp *RateProfile
if rp, err = dm.GetRateProfile(newFlt.Tenant, rpID, true, false, utils.NonTransactional); err != nil {
return
}
for itemID := range ids {
rate, has := rp.Rates[itemID]
if !has {
return utils.ErrNotFound
}
refID := guardian.Guardian.GuardIDs(utils.EmptyString,
config.CgrConfig().GeneralCfg().LockingTimeout, idxItmType+tntCtx)
var updIdx map[string]utils.StringSet
if updIdx, err = newFilterIndex(dm, idxItmType,
newFlt.Tenant, rpID, itemID, rate.FilterIDs); err != nil {
guardian.Guardian.UnguardIDs(refID)
return
}
for _, idx := range updIdx {
idx.Add(itemID)
}
if err = dm.SetIndexes(idxItmType, tntCtx,
updIdx, false, utils.NonTransactional); err != nil {
guardian.Guardian.UnguardIDs(refID)
return
}
guardian.Guardian.UnguardIDs(refID)
}
}
case utils.CacheAttributeFilterIndexes:
for itemID := range indx {
var ap *AttributeProfile
@@ -843,6 +891,7 @@ func removeFilterIndexesForFilter(dm *DataManager, idxItmType, tnt string,
for idx := range itemIDs {
remIndx[idxKey].Remove(idx)
}
if err = dm.SetIndexes(idxItmType, tnt, remIndx, true, utils.NonTransactional); err != nil {
return
}

View File

@@ -2238,6 +2238,7 @@ func testITIndexRateProfileRateIndexes(t *testing.T) {
t.Errorf("Expecting %+v, received: %+v", utils.ToJSON(eIdxes), utils.ToJSON(rcvIdx))
}
}
// update the RateProfile by adding a new Rate
rPrf = &RateProfile{ // recreate the profile because if we test on internal
Tenant: "cgrates.org", // each update on the original item will update the item from DB
@@ -2305,6 +2306,16 @@ func testITIndexRateProfileRateIndexes(t *testing.T) {
t.Errorf("Expecting %+v, received: %+v", eIdxes, rcvIdx)
}
}
//here we will set a filter
fltr := &Filter{
Tenant: "cgrates.org",
ID: "FLTR",
Rules: []*FilterRule{{Type: utils.MetaString, Element: "Dan", Values: []string{"~*req.Account", "~*req.Destination", "DAN2"}}},
}
if err := dataManager.SetFilter(fltr, true); err != nil {
t.Error(err)
}
rPrf2 := &RateProfile{
Tenant: "cgrates.org",
ID: "RP2",
@@ -2317,7 +2328,7 @@ func testITIndexRateProfileRateIndexes(t *testing.T) {
Rates: map[string]*Rate{
"CUSTOM_RATE1": {
ID: "CUSTOM_RATE1",
FilterIDs: []string{"*string:~*req.Subject:1001"},
FilterIDs: []string{"*string:~*req.Subject:1001", "FLTR"},
Weights: utils.DynamicWeights{
{
Weight: 0,
@@ -2348,16 +2359,78 @@ func testITIndexRateProfileRateIndexes(t *testing.T) {
"*string:*req.Category:call": {
"CUSTOM_RATE2": struct{}{},
},
"*string:*req.Account:Dan": {
"CUSTOM_RATE1": struct{}{},
},
"*string:*req.Destination:Dan": {
"CUSTOM_RATE1": struct{}{},
},
}
if rcvIdx, err := dataManager.GetIndexes(
utils.CacheRateFilterIndexes, "cgrates.org:RP2",
utils.EmptyString, true, true); err != nil {
t.Error(err)
} else {
if !reflect.DeepEqual(eIdxes, rcvIdx) {
t.Errorf("Expecting %+v, received: %+v", eIdxes, rcvIdx)
}
} else if !reflect.DeepEqual(eIdxes, rcvIdx) {
t.Errorf("Expecting %+v, received: %+v", eIdxes, rcvIdx)
}
//here we will check the reverse indexes
eIdxes = map[string]utils.StringSet{
utils.CacheRateFilterIndexes: {
"CUSTOM_RATE1:RP2": struct{}{},
},
}
if rcvIdx, err := dataManager.GetIndexes(
utils.CacheReverseFilterIndexes, "cgrates.org:FLTR",
utils.EmptyString, true, true); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(eIdxes, rcvIdx) {
t.Errorf("Expecting %+v, received: %+v", utils.ToJSON(eIdxes), utils.ToJSON(rcvIdx))
}
//now we will update the filter
fltr = &Filter{
Tenant: "cgrates.org",
ID: "FLTR",
Rules: []*FilterRule{{Type: utils.MetaString, Element: "10m", Values: []string{"~*req.Usage", "~*req.Debited", "DAN2"}}},
}
if err := dataManager.SetFilter(fltr, true); err != nil {
t.Error(err)
}
eIdxes = map[string]utils.StringSet{
"*string:*req.Subject:1001": {
"CUSTOM_RATE1": struct{}{},
"CUSTOM_RATE2": struct{}{},
},
"*string:*req.Category:call": {
"CUSTOM_RATE2": struct{}{},
},
"*string:*req.Usage:10m": {
"CUSTOM_RATE1": struct{}{},
},
"*string:*req.Debited:10m": {
"CUSTOM_RATE1": struct{}{},
},
}
if rcvIdx, err := dataManager.GetIndexes(
utils.CacheRateFilterIndexes, "cgrates.org:RP2",
utils.EmptyString, true, true); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(eIdxes, rcvIdx) {
t.Errorf("Expecting %+v, received: %+v", utils.ToJSON(eIdxes), utils.ToJSON(rcvIdx))
}
//invalid or inexisting tenant:context or index key
eIdxes = nil
if rcvIdx, err := dataManager.GetIndexes(
utils.CacheRateFilterIndexes, "cgrates.org:RP4",
utils.EmptyString, true, true); err == nil || err != utils.ErrNotFound {
t.Errorf("Expected %+v, received %+v", utils.ErrNotFound, err)
} else if !reflect.DeepEqual(eIdxes, rcvIdx) {
t.Errorf("Expecting %+v, received: %+v", utils.ToJSON(eIdxes), utils.ToJSON(rcvIdx))
}
}
func testITIndexRateProfileIndexes(t *testing.T) {