mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Updated redis itnerface for rates
This commit is contained in:
committed by
Dan Christian Bogos
parent
d4b65ef86a
commit
e84b89186c
@@ -626,7 +626,7 @@ func (rplSv1 *ReplicatorSv1) SetActionProfile(ctx *context.Context, sp *engine.A
|
||||
}
|
||||
|
||||
func (rplSv1 *ReplicatorSv1) RemoveRateProfile(ctx *context.Context, args *utils.TenantIDWithAPIOpts, reply *string) (err error) {
|
||||
if err = rplSv1.dm.DataDB().RemoveRateProfileDrv(ctx, args.Tenant, args.ID); err != nil {
|
||||
if err = rplSv1.dm.DataDB().RemoveRateProfileDrv(ctx, args.Tenant, args.ID, []string{}); err != nil {
|
||||
return
|
||||
}
|
||||
if err = rplSv1.v1.CallCache(ctx, utils.IfaceAsString(args.APIOpts[utils.MetaCache]),
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
// CGRateS Configuration file
|
||||
// will be used in apis/attributes_it_test.go
|
||||
|
||||
"general": {
|
||||
"node_id": "id", // identifier of this instance in the cluster, if empty it will be autogenerated
|
||||
"log_level": 7,
|
||||
},
|
||||
|
||||
"data_db": { // database used to store runtime data (eg: accounts, cdr stats)
|
||||
"db_type": "redis", // data_db type: <redis|mongo>
|
||||
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
)
|
||||
|
||||
type DataDBMock struct {
|
||||
RemoveRateProfileDrvF func(ctx *context.Context, str1 string, str2 string) error
|
||||
RemoveRateProfileDrvF func(ctx *context.Context, str1 string, str2 string, rateIDs []string) error
|
||||
SetRateProfileDrvF func(*context.Context, *utils.RateProfile) error
|
||||
GetRateProfileDrvF func(*context.Context, string, string) (*utils.RateProfile, error)
|
||||
GetKeysForPrefixF func(*context.Context, string) ([]string, error)
|
||||
@@ -382,9 +382,9 @@ func (dbM *DataDBMock) SetRateProfileDrv(ctx *context.Context, rt *utils.RatePro
|
||||
return utils.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (dbM *DataDBMock) RemoveRateProfileDrv(ctx *context.Context, str1 string, str2 string) error {
|
||||
func (dbM *DataDBMock) RemoveRateProfileDrv(ctx *context.Context, str1 string, str2 string, rateIDs []string) error {
|
||||
if dbM.RemoveRateProfileDrvF != nil {
|
||||
return dbM.RemoveRateProfileDrvF(ctx, str1, str2)
|
||||
return dbM.RemoveRateProfileDrvF(ctx, str1, str2, []string{})
|
||||
}
|
||||
return utils.ErrNotImplemented
|
||||
}
|
||||
|
||||
@@ -2028,7 +2028,7 @@ func (dm *DataManager) RemoveRateProfile(ctx *context.Context, tenant, id string
|
||||
if err != nil && err != utils.ErrNotFound {
|
||||
return
|
||||
}
|
||||
if err = dm.DataDB().RemoveRateProfileDrv(ctx, tenant, id); err != nil {
|
||||
if err = dm.DataDB().RemoveRateProfileDrv(ctx, tenant, id, []string{}); err != nil {
|
||||
return
|
||||
}
|
||||
if oldRpp == nil {
|
||||
@@ -2103,8 +2103,8 @@ func (dm *DataManager) RemoveRateProfileRates(ctx *context.Context, tenant, id s
|
||||
delete(oldRpp.Rates, rateID)
|
||||
}
|
||||
}
|
||||
if err = dm.DataDB().SetRateProfileDrv(ctx, oldRpp); err != nil {
|
||||
return err
|
||||
if err = dm.DataDB().RemoveRateProfileDrv(ctx, tenant, id, rateIDs); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaRateProfiles]; itm.Replicate {
|
||||
|
||||
@@ -95,7 +95,7 @@ type DataDB interface {
|
||||
RemoveDispatcherHostDrv(*context.Context, string, string) error
|
||||
GetRateProfileDrv(*context.Context, string, string) (*utils.RateProfile, error)
|
||||
SetRateProfileDrv(*context.Context, *utils.RateProfile) error
|
||||
RemoveRateProfileDrv(*context.Context, string, string) error
|
||||
RemoveRateProfileDrv(*context.Context, string, string, []string) error
|
||||
GetActionProfileDrv(*context.Context, string, string) (*ActionProfile, error)
|
||||
SetActionProfileDrv(*context.Context, *ActionProfile) error
|
||||
RemoveActionProfileDrv(*context.Context, string, string) error
|
||||
|
||||
@@ -485,7 +485,7 @@ func (iDB *InternalDB) SetRateProfileDrv(_ *context.Context, rpp *utils.RateProf
|
||||
return
|
||||
}
|
||||
|
||||
func (iDB *InternalDB) RemoveRateProfileDrv(_ *context.Context, tenant, id string) (err error) {
|
||||
func (iDB *InternalDB) RemoveRateProfileDrv(_ *context.Context, tenant, id string, rateIDs []string) (err error) {
|
||||
iDB.db.Remove(utils.CacheRateProfiles, utils.ConcatenatedKey(tenant, id),
|
||||
true, utils.NonTransactional)
|
||||
return
|
||||
|
||||
@@ -1228,7 +1228,7 @@ func (ms *MongoStorage) SetRateProfileDrv(ctx *context.Context, rpp *utils.RateP
|
||||
})
|
||||
}
|
||||
|
||||
func (ms *MongoStorage) RemoveRateProfileDrv(ctx *context.Context, tenant, id string) (err error) {
|
||||
func (ms *MongoStorage) RemoveRateProfileDrv(ctx *context.Context, tenant, id string, rateIDs []string) (err error) {
|
||||
return ms.query(ctx, func(sctx mongo.SessionContext) (err error) {
|
||||
dr, err := ms.getCol(ColRpp).DeleteOne(sctx, bson.M{"tenant": tenant, "id": id})
|
||||
if dr.DeletedCount == 0 {
|
||||
|
||||
@@ -64,6 +64,7 @@ const (
|
||||
redisHGET = "HGET"
|
||||
redisRENAME = "RENAME"
|
||||
redisHMSET = "HMSET"
|
||||
redisHSET = "HSET"
|
||||
|
||||
redisLoadError = "Redis is loading the dataset in memory"
|
||||
RedisLimit = 524287 // https://github.com/StackExchange/StackExchange.Redis/issues/201#issuecomment-98639005
|
||||
@@ -727,6 +728,7 @@ func (rs *RedisStorage) RemoveLoadIDsDrv() (err error) {
|
||||
return rs.Cmd(nil, redisDEL, utils.LoadIDs)
|
||||
}
|
||||
|
||||
/*
|
||||
func (rs *RedisStorage) GetRateProfileDrv(ctx *context.Context, tenant, id string) (rpp *utils.RateProfile, err error) {
|
||||
var values []byte
|
||||
if err = rs.Cmd(&values, redisGET, utils.RateProfilePrefix+utils.ConcatenatedKey(tenant, id)); err != nil {
|
||||
@@ -739,6 +741,7 @@ func (rs *RedisStorage) GetRateProfileDrv(ctx *context.Context, tenant, id strin
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
func (rs *RedisStorage) SetRateProfileDrv(ctx *context.Context, rpp *utils.RateProfile) (err error) {
|
||||
var result []byte
|
||||
if result, err = rs.ms.Marshal(rpp); err != nil {
|
||||
@@ -746,8 +749,40 @@ func (rs *RedisStorage) SetRateProfileDrv(ctx *context.Context, rpp *utils.RateP
|
||||
}
|
||||
return rs.Cmd(nil, redisSET, utils.RateProfilePrefix+utils.ConcatenatedKey(rpp.Tenant, rpp.ID), string(result))
|
||||
}
|
||||
*/
|
||||
|
||||
func (rs *RedisStorage) RemoveRateProfileDrv(ctx *context.Context, tenant, id string) (err error) {
|
||||
func (rs *RedisStorage) SetRateProfileDrv(ctx *context.Context, rpp *utils.RateProfile) (err error) {
|
||||
rpMap, err := rpp.AsDataDBMap()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for key, val := range rpMap {
|
||||
if err = rs.FlatCmd(nil, redisHSET, utils.RateProfilePrefix+utils.ConcatenatedKey(rpp.Tenant, rpp.ID), key, val); err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (rs *RedisStorage) GetRateProfileDrv(ctx *context.Context, tenant, id string) (rpp *utils.RateProfile, err error) {
|
||||
mapRP := make(map[string]interface{})
|
||||
if err = rs.Cmd(&mapRP, redisHGETALL, utils.RateProfilePrefix+utils.ConcatenatedKey(tenant, id)); err != nil {
|
||||
return
|
||||
} else if len(mapRP) == 0 {
|
||||
err = utils.ErrNotFound
|
||||
return
|
||||
}
|
||||
rpp, err = utils.NewRateProfileFromMapDataDBMap(tenant, id, mapRP)
|
||||
return
|
||||
}
|
||||
|
||||
func (rs *RedisStorage) RemoveRateProfileDrv(ctx *context.Context, tenant, id string, rateIDs []string) (err error) {
|
||||
if len(rateIDs) != 0 {
|
||||
tntID := utils.ConcatenatedKey(tenant, id)
|
||||
for _, rateID := range rateIDs {
|
||||
return rs.Cmd(nil, redisHDEL, utils.RateProfilePrefix+tntID, utils.Rates+utils.InInFieldSep+rateID)
|
||||
}
|
||||
}
|
||||
return rs.Cmd(nil, redisDEL, utils.RateProfilePrefix+utils.ConcatenatedKey(tenant, id))
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
package utils
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
@@ -909,3 +910,91 @@ func (iR *IntervalRate) FieldAsInterface(fldPath []string) (_ interface{}, err e
|
||||
return iR.Increment, nil
|
||||
}
|
||||
}
|
||||
|
||||
// AsDataDBMap is used to is a convert method in order to properly set trough a hasmap in redis server our rate profile
|
||||
func (rp *RateProfile) AsDataDBMap() (mp map[string]interface{}, err error) {
|
||||
mp = map[string]interface{}{
|
||||
MaxCostStrategy: rp.MaxCostStrategy,
|
||||
}
|
||||
if len(rp.FilterIDs) != 0 {
|
||||
var fltrs string
|
||||
for idx, fltr := range rp.FilterIDs {
|
||||
fltrs += fltr
|
||||
if idx != len(rp.FilterIDs)-1 {
|
||||
fltrs += InfieldSep
|
||||
}
|
||||
}
|
||||
mp[FilterIDs] = fltrs
|
||||
}
|
||||
if rp.Weights != nil {
|
||||
mp[Weights] = rp.Weights.String(InfieldSep, ANDSep)
|
||||
}
|
||||
if rp.MinCost != nil {
|
||||
minCostBts, err := rp.MinCost.MarshalBinary()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mp[MinCost] = minCostBts
|
||||
}
|
||||
if rp.MaxCost != nil {
|
||||
maxCostBts, err := rp.MaxCost.MarshalBinary()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mp[MaxCost] = maxCostBts
|
||||
}
|
||||
for rateID, rt := range rp.Rates {
|
||||
var result []byte
|
||||
if result, err = json.Marshal(rt); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fldKey := ConcatenatedKey(Rates, rateID)
|
||||
mp[fldKey] = result
|
||||
}
|
||||
return mp, nil
|
||||
}
|
||||
|
||||
// NewRateProfileFromMapDataDBMap will convert a RateProfile map into a RatePRofile struct. This is used when we get the map from redis database
|
||||
func NewRateProfileFromMapDataDBMap(tnt, id string, mapRP map[string]interface{}) (rp *RateProfile, err error) {
|
||||
rp = &RateProfile{
|
||||
ID: id,
|
||||
Tenant: tnt,
|
||||
MaxCostStrategy: IfaceAsString(mapRP[MaxCostStrategy]),
|
||||
Rates: make(map[string]*Rate),
|
||||
}
|
||||
if fltrsIDs, has := mapRP[FilterIDs]; has {
|
||||
fltrs := strings.Split(IfaceAsString(fltrsIDs), InfieldSep)
|
||||
rp.FilterIDs = make([]string, len(fltrs))
|
||||
for idx, fltr := range fltrs {
|
||||
rp.FilterIDs[idx] = fltr
|
||||
}
|
||||
}
|
||||
if weights, has := mapRP[Weights]; has {
|
||||
rp.Weights, err = NewDynamicWeightsFromString(IfaceAsString(weights), InfieldSep, ANDSep)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if minCost, has := mapRP[MinCost]; has {
|
||||
rp.MinCost, err = NewDecimalFromString(IfaceAsString(minCost))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if maxCost, has := mapRP[MaxCost]; has {
|
||||
rp.MaxCost, err = NewDecimalFromString(IfaceAsString(maxCost))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
for keyID, rateStr := range mapRP {
|
||||
if strings.HasPrefix(keyID, Rates+ConcatenatedKeySep) {
|
||||
var rate *Rate
|
||||
if err := json.Unmarshal([]byte(IfaceAsString(rateStr)), &rate); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rp.Rates[strings.TrimPrefix(keyID, Rates+ConcatenatedKeySep)] = rate
|
||||
}
|
||||
}
|
||||
return rp, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user