Updated SetRateProfile + drivers and tests

This commit is contained in:
porosnicuadrian
2022-03-31 12:30:10 +03:00
committed by Dan Christian Bogos
parent 3baadf5549
commit 28619db53d
14 changed files with 700 additions and 107 deletions

View File

@@ -25,7 +25,7 @@ import (
type DataDBMock struct {
RemoveRateProfileDrvF func(ctx *context.Context, str1 string, str2 string, rateIDs *[]string) error
SetRateProfileDrvF func(*context.Context, *utils.RateProfile) error
SetRateProfileDrvF func(*context.Context, *utils.RateProfile, bool) error
GetRateProfileDrvF func(*context.Context, string, string) (*utils.RateProfile, error)
GetRateProfileRatesDrvF func(*context.Context, string, string, string, bool) ([]string, []*utils.Rate, error)
GetKeysForPrefixF func(*context.Context, string) ([]string, error)
@@ -407,9 +407,9 @@ func (dbM *DataDBMock) GetRateProfileRatesDrv(ctx *context.Context, tnt string,
return nil, nil, utils.ErrNotImplemented
}
func (dbM *DataDBMock) SetRateProfileDrv(ctx *context.Context, rt *utils.RateProfile) error {
func (dbM *DataDBMock) SetRateProfileDrv(ctx *context.Context, rt *utils.RateProfile, optOverwrite bool) error {
if dbM.SetRateProfileDrvF != nil {
return dbM.SetRateProfileDrvF(ctx, rt)
return dbM.SetRateProfileDrvF(ctx, rt, optOverwrite)
}
return utils.ErrNotImplemented
}

View File

@@ -1916,7 +1916,7 @@ func (dm *DataManager) GetRateProfile(ctx *context.Context, tenant, id string, c
config.CgrConfig().GeneralCfg().NodeID)),
}, &rpp); err == nil {
rpp.Sort()
err = dm.dataDB.SetRateProfileDrv(ctx, rpp)
err = dm.dataDB.SetRateProfileDrv(ctx, rpp, false)
}
}
if err != nil {
@@ -1954,7 +1954,8 @@ func (dm *DataManager) SetRateProfile(ctx *context.Context, rpp *utils.RateProfi
if dm == nil {
return utils.ErrNoDatabaseConn
}
if withIndex {
// check if the filters are valid, this can be inline or filter object
if len(rpp.FilterIDs) != 0 {
if err := dm.checkFilters(ctx, rpp.Tenant, rpp.FilterIDs); err != nil {
// if we get a broken filter do not set the profile
return fmt.Errorf("%+s for item with ID: %+v",
@@ -1974,24 +1975,9 @@ func (dm *DataManager) SetRateProfile(ctx *context.Context, rpp *utils.RateProfi
if err != nil && err != utils.ErrNotFound {
return err
}
// in case of overwriting, we will remove the old indexes and the old profile/rates, and will be set the new one, also the fields of the profile are changed too in case of the same tenantID
if optOverwrite && oldRpp != nil && oldRpp.TenantID() == rpp.TenantID() {
// remove indexes for old rates if the rates does not exist in new rate profile
for key, rate := range oldRpp.Rates {
if err = removeIndexFiltersItem(ctx, dm, utils.CacheRateFilterIndexes, oldRpp.Tenant, utils.ConcatenatedKey(key, oldRpp.ID), rate.FilterIDs); err != nil {
return
}
if err = removeItemFromFilterIndex(ctx, dm, utils.CacheRateFilterIndexes,
rpp.Tenant, rpp.ID, key, rate.FilterIDs); err != nil {
return
}
}
if err = dm.DataDB().RemoveRateProfileDrv(ctx, oldRpp.Tenant, oldRpp.ID, nil); err != nil {
return err
}
}
if withIndex {
// remove indexes for old rates if the rates does not exist in new rate profile
var oldRpFltrs *[]string
if oldRpp != nil {
oldRpFltrs = &oldRpp.FilterIDs
@@ -2017,7 +2003,7 @@ func (dm *DataManager) SetRateProfile(ctx *context.Context, rpp *utils.RateProfi
}
}
// if not overwriting, we will add the rates in case the profile is already in database, also the fields of the profile are changed too in case of the same tenantID
if err = dm.DataDB().SetRateProfileDrv(ctx, rpp); err != nil {
if err = dm.DataDB().SetRateProfileDrv(ctx, rpp, optOverwrite); err != nil {
return err
}
if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaRateProfiles]; itm.Replicate {
@@ -2134,56 +2120,6 @@ func (dm *DataManager) RemoveRateProfileRates(ctx *context.Context, tenant, id s
return
}
func (dm *DataManager) SetRateProfileRates(ctx *context.Context, rpp *utils.RateProfile, withIndex bool) (err error) {
if dm == nil {
return utils.ErrNoDatabaseConn
}
if withIndex {
for _, rate := range rpp.Rates {
if err := dm.checkFilters(ctx, rpp.Tenant, rate.FilterIDs); err != nil {
// if we get a broken filter do not update the rates
return fmt.Errorf("%+s for item with ID: %+v",
err, rate.ID)
}
}
}
oldRpp, err := dm.GetRateProfile(ctx, rpp.Tenant, rpp.ID, true, false, utils.NonTransactional)
if err != nil {
return err
}
// create index for each rate
for key, rate := range rpp.Rates {
if withIndex {
var oldRateFiltersIDs *[]string
if oldRate, has := oldRpp.Rates[key]; has {
oldRateFiltersIDs = &oldRate.FilterIDs
}
// when we create the indexes for rates we use RateProfile ID as context
if err := updatedIndexes(ctx, dm, utils.CacheRateFilterIndexes, rpp.Tenant,
rpp.ID, key, oldRateFiltersIDs, rate.FilterIDs, true); err != nil {
return err
}
}
oldRpp.Rates[key] = rate
}
if err = dm.DataDB().SetRateProfileDrv(ctx, oldRpp); err != nil {
return err
}
if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaRateProfiles]; itm.Replicate {
err = replicate(ctx, dm.connMgr, config.CgrConfig().DataDbCfg().RplConns,
config.CgrConfig().DataDbCfg().RplFiltered,
utils.RateProfilePrefix, oldRpp.TenantID(), // this are used to get the host IDs from cache
utils.ReplicatorSv1SetRateProfile,
&utils.RateProfileWithAPIOpts{
RateProfile: oldRpp,
APIOpts: utils.GenerateDBItemOpts(itm.APIKey, itm.RouteID,
config.CgrConfig().DataDbCfg().RplCache, utils.EmptyString)})
}
return
}
func (dm *DataManager) GetActionProfile(ctx *context.Context, tenant, id string, cacheRead, cacheWrite bool,
transactionID string) (ap *ActionProfile, err error) {
tntID := utils.ConcatenatedKey(tenant, id)

View File

@@ -50,7 +50,9 @@ func TestGetFltrIdxHealthForRateRates(t *testing.T) {
},
},
}
dm.SetRateProfileRates(context.Background(), rt, false)
if err := dm.SetRateProfile(context.Background(), rt, false, true); err != nil {
t.Error(err)
}
rply, err := GetFltrIdxHealthForRateRates(context.Background(), dm, ltcache.NewCache(50, 60*time.Second, true, nil),
ltcache.NewCache(40, 30*time.Second, false, nil),
ltcache.NewCache(20, 20*time.Second, true, nil))

View File

@@ -87,7 +87,7 @@ type DataDB interface {
RemoveDispatcherHostDrv(*context.Context, string, string) error
GetRateProfileDrv(*context.Context, string, string) (*utils.RateProfile, error)
GetRateProfileRatesDrv(*context.Context, string, string, string, bool) ([]string, []*utils.Rate, error)
SetRateProfileDrv(*context.Context, *utils.RateProfile) error
SetRateProfileDrv(*context.Context, *utils.RateProfile, bool) error
RemoveRateProfileDrv(*context.Context, string, string, *[]string) error
GetActionProfileDrv(*context.Context, string, string) (*ActionProfile, error)
SetActionProfileDrv(*context.Context, *ActionProfile) error

View File

@@ -480,18 +480,20 @@ func (iDB *InternalDB) GetRateProfileRatesDrv(ctx *context.Context, tenant, prof
return
}
func (iDB *InternalDB) SetRateProfileDrv(_ *context.Context, rpp *utils.RateProfile) (err error) {
func (iDB *InternalDB) SetRateProfileDrv(_ *context.Context, rpp *utils.RateProfile, optOverwrite bool) (err error) {
if err = rpp.Compile(); err != nil {
return
}
// in case of add new rates into our profile
x, ok := iDB.db.Get(utils.CacheRateProfiles, utils.ConcatenatedKey(rpp.Tenant, rpp.ID))
if ok || x != nil {
// mix the old and new rates, in order to add new rates into our profile
oldRp := x.(*utils.RateProfile)
for key, rate := range oldRp.Rates {
if _, has := rpp.Rates[key]; !has {
rpp.Rates[key] = rate
if !optOverwrite {
// in case of add new rates into our profile
x, ok := iDB.db.Get(utils.CacheRateProfiles, utils.ConcatenatedKey(rpp.Tenant, rpp.ID))
if ok || x != nil {
// mix the old and new rates, in order to add new rates into our profile
oldRp := x.(*utils.RateProfile)
for key, rate := range oldRp.Rates {
if _, has := rpp.Rates[key]; !has {
rpp.Rates[key] = rate
}
}
}
}

View File

@@ -1242,12 +1242,17 @@ func (ms *MongoStorage) GetRateProfileRatesDrv(ctx *context.Context, tenant, pro
return
}
func (ms *MongoStorage) SetRateProfileDrv(ctx *context.Context, rpp *utils.RateProfile) (err error) {
func (ms *MongoStorage) SetRateProfileDrv(ctx *context.Context, rpp *utils.RateProfile, optOverwrite bool) (err error) {
rpMap, err := rpp.AsDataDBMap(ms.ms)
if err != nil {
return
}
return ms.query(ctx, func(sctx mongo.SessionContext) (err error) {
if optOverwrite {
if _, err = ms.getCol(ColRpp).DeleteOne(sctx, bson.M{"tenant": rpp.Tenant, "id": rpp.ID}); err != nil {
return
}
}
_, err = ms.getCol(ColRpp).UpdateOne(sctx, bson.M{"tenant": rpp.Tenant, "id": rpp.ID},
bson.M{"$set": rpMap},
options.Update().SetUpsert(true),

View File

@@ -729,11 +729,14 @@ func (rs *RedisStorage) RemoveLoadIDsDrv() (err error) {
return rs.Cmd(nil, redisDEL, utils.LoadIDs)
}
func (rs *RedisStorage) SetRateProfileDrv(ctx *context.Context, rpp *utils.RateProfile) (err error) {
func (rs *RedisStorage) SetRateProfileDrv(ctx *context.Context, rpp *utils.RateProfile, optOverwrite bool) (err error) {
rpMap, err := rpp.AsDataDBMap(rs.ms)
if err != nil {
return
}
if optOverwrite {
rs.Cmd(nil, redisDEL, utils.RateProfilePrefix+utils.ConcatenatedKey(rpp.Tenant, rpp.ID))
}
return rs.FlatCmd(nil, redisHSET, utils.RateProfilePrefix+utils.ConcatenatedKey(rpp.Tenant, rpp.ID), rpMap)
}