From fd5cf12eacfea15318304a348db1ce8b00745874 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 23 Nov 2021 16:58:24 +0200 Subject: [PATCH] Updated all the loaders types --- apis/loaders_it_test.go | 2 +- apis/loaders_test.go | 2 +- engine/actionprofile.go | 114 +++++++++++ engine/dispatcherprfl.go | 101 ++++++++++ engine/libchargers.go | 23 +++ engine/resources.go | 2 +- loaders/libloader.go | 16 +- loaders/libloader_test.go | 53 ++--- loaders/loader.go | 413 ++++++++++++++++---------------------- loaders/loader_test.go | 247 +++++++++++------------ loaders/loaders.go | 12 +- loaders/loaders_test.go | 10 +- services/loaders.go | 6 +- services/loaders_test.go | 2 +- utils/account.go | 146 ++++++++++++++ utils/consts.go | 16 ++ utils/librates.go | 104 ++++++++++ 17 files changed, 833 insertions(+), 436 deletions(-) diff --git a/apis/loaders_it_test.go b/apis/loaders_it_test.go index 98f27a517..6414a56c1 100644 --- a/apis/loaders_it_test.go +++ b/apis/loaders_it_test.go @@ -1122,7 +1122,7 @@ func TestLoadersLoad(t *testing.T) { data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) dm := engine.NewDataManager(data, cfg.CacheCfg(), nil) fltrs := engine.NewFilterS(cfg, nil, dm) - ldrS := loaders.NewLoaderService(cfg, dm, "", fltrs, nil) + ldrS := loaders.NewLoaderService(cfg, dm, fltrs, nil) lSv1 := NewLoaderSv1(ldrS) args := &loaders.ArgsProcessFolder{ diff --git a/apis/loaders_test.go b/apis/loaders_test.go index a912a72ad..92dc01603 100644 --- a/apis/loaders_test.go +++ b/apis/loaders_test.go @@ -32,7 +32,7 @@ func TestLoadersNewLoaderSv1(t *testing.T) { data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) dm := engine.NewDataManager(data, cfg.CacheCfg(), nil) fltrs := engine.NewFilterS(cfg, nil, dm) - ldrS := loaders.NewLoaderService(cfg, dm, "", fltrs, nil) + ldrS := loaders.NewLoaderService(cfg, dm, fltrs, nil) exp := &LoaderSv1{ ldrS: ldrS, diff --git a/engine/actionprofile.go b/engine/actionprofile.go index ced7a527b..358959547 100644 --- a/engine/actionprofile.go +++ b/engine/actionprofile.go @@ -20,6 +20,7 @@ package engine import ( "sort" + "strings" "time" "github.com/cgrates/cgrates/config" @@ -85,3 +86,116 @@ type ActionProfileWithAPIOpts struct { *ActionProfile APIOpts map[string]interface{} } + +func (aP *ActionProfile) Set(path []string, val interface{}, newBranch bool, _ string) (err error) { + switch len(path) { + case 0: + return utils.ErrWrongPath + case 1: + switch path[0] { + default: + if strings.HasPrefix(path[0], utils.Targets) && + path[0][7] == '[' && path[0][len(path[0])-1] == ']' { + var valA []string + valA, err = utils.IfaceAsStringSlice(val) + aP.Targets[path[0][8:len(path[0])-1]] = utils.NewStringSet(valA) + return + } + return utils.ErrWrongPath + case utils.Tenant: + aP.Tenant = utils.IfaceAsString(val) + case utils.ID: + aP.ID = utils.IfaceAsString(val) + case utils.Schedule: + aP.Schedule = utils.IfaceAsString(val) + case utils.FilterIDs: + aP.FilterIDs, err = utils.IfaceAsStringSlice(val) + case utils.Weight: + aP.Weight, err = utils.IfaceAsFloat64(val) + } + return + case 2: + if path[0] == utils.Targets { + var valA []string + valA, err = utils.IfaceAsStringSlice(val) + aP.Targets[path[1]] = utils.NewStringSet(valA) + return + } + default: + } + + var acID string + if strings.HasPrefix(path[0], utils.Actions) && + path[0][5] == '[' && path[0][len(path[0])-1] == ']' { + acID = path[0][6 : len(path[0])-1] + } else if path[0] == utils.Actions { + acID = path[1] + path = path[1:] + } + if acID == utils.EmptyString { + return utils.ErrWrongPath + } + + var ac *APAction + for _, a := range aP.Actions { + if a.ID == acID { + ac = a + break + } + } + if ac == nil { + ac = &APAction{ID: acID, Opts: make(map[string]interface{})} + aP.Actions = append(aP.Actions, ac) + } + + return ac.Set(path[1:], val, newBranch) +} + +func (aP *APAction) Set(path []string, val interface{}, newBranch bool) (err error) { + switch len(path) { + default: + if path[0] == utils.Opts { + return utils.MapStorage(aP.Opts).Set(path[1:], val) + } + return utils.ErrWrongPath + case 0: + return utils.ErrWrongPath + case 1: + switch path[0] { + default: + if strings.HasPrefix(path[0], utils.Opts) && + path[0][4] == '[' && path[0][len(path[0])-1] == ']' { + aP.Opts[path[0][5:len(path[0])-1]] = val + } + return utils.ErrWrongPath + case utils.ID: + aP.ID = utils.IfaceAsString(val) + case utils.Type: + aP.Type = utils.IfaceAsString(val) + case utils.FilterIDs: + aP.FilterIDs, err = utils.IfaceAsStringSlice(val) + case utils.Blocker: + aP.Blocker, err = utils.IfaceAsBool(val) + case utils.TTL: + aP.TTL, err = utils.IfaceAsDuration(val) + } + case 2: + switch path[0] { + default: + return utils.ErrWrongPath + case utils.Opts: + return utils.MapStorage(aP.Opts).Set(path[1:], val) + case utils.Diktats: + if len(aP.Diktats) == 0 || newBranch { + aP.Diktats = append(aP.Diktats, new(APDiktat)) + } + switch path[1] { + case utils.Path: + aP.Diktats[len(aP.Diktats)-1].Path = utils.IfaceAsString(val) + case utils.Value: + aP.Diktats[len(aP.Diktats)-1].Value = utils.IfaceAsString(val) + } + } + } + return +} diff --git a/engine/dispatcherprfl.go b/engine/dispatcherprfl.go index 944309213..a9954066f 100644 --- a/engine/dispatcherprfl.go +++ b/engine/dispatcherprfl.go @@ -21,6 +21,7 @@ package engine import ( "math/rand" "sort" + "strings" "github.com/cgrates/birpc" "github.com/cgrates/birpc/context" @@ -187,3 +188,103 @@ func (dHPrflIDs DispatcherHostIDs) Clone() (cln DispatcherHostIDs) { copy(cln, dHPrflIDs) return } + +func (dP *DispatcherProfile) Set(path []string, val interface{}, newBranch bool, _ string) (err error) { + switch len(path) { + default: + return utils.ErrWrongPath + case 1: + switch path[0] { + default: + if strings.HasPrefix(path[0], utils.StrategyParams) && + path[0][14] == '[' && path[0][len(path[0])-1] == ']' { + dP.StrategyParams[path[0][15:len(path[0])-1]] = val + return + } + return utils.ErrWrongPath + case utils.Tenant: + dP.Tenant = utils.IfaceAsString(val) + case utils.ID: + dP.ID = utils.IfaceAsString(val) + case utils.FilterIDs: + dP.FilterIDs, err = utils.IfaceAsStringSlice(val) + case utils.Strategy: + dP.Strategy = utils.IfaceAsString(val) + case utils.Weight: + dP.Weight, err = utils.IfaceAsFloat64(val) + } + case 2: + switch path[0] { + default: + return utils.ErrWrongPath + case utils.StrategyParams: + dP.StrategyParams[path[1]] = val + case utils.Hosts: + if len(dP.Hosts) == 0 || newBranch { + dP.Hosts = append(dP.Hosts, &DispatcherHostProfile{Params: make(map[string]interface{})}) + } + switch path[1] { + case utils.ID: + dP.Hosts[len(dP.Hosts)-1].ID = utils.IfaceAsString(val) + case utils.FilterIDs: + dP.Hosts[len(dP.Hosts)-1].FilterIDs, err = utils.IfaceAsStringSlice(val) + case utils.Weights: + dP.Hosts[len(dP.Hosts)-1].Weight, err = utils.IfaceAsFloat64(val) + case utils.Blocker: + dP.Hosts[len(dP.Hosts)-1].Blocker, err = utils.IfaceAsBool(val) + default: + if strings.HasPrefix(path[0], utils.Params) && + path[0][6] == '[' && path[0][len(path[0])-1] == ']' { + dP.Hosts[len(dP.Hosts)-1].Params[path[0][7:len(path[0])-1]] = val + return + } + return utils.ErrWrongPath + } + } + case 3: + if path[0] != utils.Hosts || + path[1] != utils.Params { + return utils.ErrWrongPath + } + if len(dP.Hosts) == 0 || newBranch { + dP.Hosts = append(dP.Hosts, new(DispatcherHostProfile)) + } + dP.Hosts[len(dP.Hosts)-1].Params[path[2]] = val + } + return +} + +func (dH *DispatcherHost) Set(path []string, val interface{}, newBranch bool, _ string) (err error) { + if len(path) != 1 { + return utils.ErrWrongPath + } + switch path[0] { + default: + return utils.ErrWrongPath + case utils.Tenant: + dH.Tenant = utils.IfaceAsString(val) + case utils.ID: + dH.ID = utils.IfaceAsString(val) + case utils.Address: + dH.Address = utils.IfaceAsString(val) + case utils.Transport: + dH.Transport = utils.IfaceAsString(val) + case utils.ClientKey: + dH.ClientKey = utils.IfaceAsString(val) + case utils.ClientCertificate: + dH.ClientCertificate = utils.IfaceAsString(val) + case utils.CaCertificate: + dH.CaCertificate = utils.IfaceAsString(val) + case utils.ConnectAttempts: + dH.ConnectAttempts, err = utils.IfaceAsTInt(val) + case utils.Reconnects: + dH.Reconnects, err = utils.IfaceAsTInt(val) + case utils.ConnectTimeout: + dH.ConnectTimeout, err = utils.IfaceAsDuration(val) + case utils.ReplyTimeout: + dH.ReplyTimeout, err = utils.IfaceAsDuration(val) + case utils.TLS: + dH.TLS, err = utils.IfaceAsBool(val) + } + return +} diff --git a/engine/libchargers.go b/engine/libchargers.go index dd806b76a..f494b43cb 100644 --- a/engine/libchargers.go +++ b/engine/libchargers.go @@ -51,3 +51,26 @@ type ChargerProfiles []*ChargerProfile func (cps ChargerProfiles) Sort() { sort.Slice(cps, func(i, j int) bool { return cps[i].Weight > cps[j].Weight }) } + +func (cp *ChargerProfile) Set(path []string, val interface{}, newBranch bool, _ string) (err error) { + if len(path) != 1 { + return utils.ErrWrongPath + } + switch path[0] { + default: + return utils.ErrWrongPath + case utils.Tenant: + cp.Tenant = utils.IfaceAsString(val) + case utils.ID: + cp.ID = utils.IfaceAsString(val) + case utils.FilterIDs: + cp.FilterIDs, err = utils.IfaceAsStringSlice(val) + case utils.RunID: + cp.RunID = utils.IfaceAsString(val) + case utils.AttributeIDs: + cp.AttributeIDs, err = utils.IfaceAsStringSlice(val) + case utils.Weight: + cp.Weight, err = utils.IfaceAsFloat64(val) + } + return +} diff --git a/engine/resources.go b/engine/resources.go index 636a23232..f10281c40 100644 --- a/engine/resources.go +++ b/engine/resources.go @@ -1023,7 +1023,7 @@ func (rS *ResourceS) V1GetResourceWithConfig(ctx *context.Context, arg *utils.Te } func (rp *ResourceProfile) Set(path []string, val interface{}, _ bool, _ string) (err error) { - if len(path) != 0 { + if len(path) != 1 { return utils.ErrWrongPath } switch path[0] { diff --git a/loaders/libloader.go b/loaders/libloader.go index 86010b188..35db6f441 100644 --- a/loaders/libloader.go +++ b/loaders/libloader.go @@ -66,10 +66,12 @@ func (r *record) FieldAsString(path []string) (str string, err error) { return utils.IfaceAsString(val), nil } -func TenantIDFromMap(data utils.MapStorage) *utils.TenantID { +func TenantIDFromDataProvider(data utils.DataProvider) *utils.TenantID { + tnt, _ := data.FieldAsString([]string{utils.Tenant}) + id, _ := data.FieldAsString([]string{utils.ID}) return &utils.TenantID{ - Tenant: utils.IfaceAsString(data[utils.Tenant]), - ID: utils.IfaceAsString(data[utils.ID]), + Tenant: tnt, + ID: id, } } @@ -196,7 +198,7 @@ func (ar *record) SetFields(ctx *context.Context, tmpls []*config.FCTemplate, fi func (ar *record) SetAsSlice(fullPath *utils.FullPath, nm *utils.DataLeaf) (err error) { switch fullPath.PathSlice[0] { default: - return ar.data.Set(fullPath, []*utils.DataNode{{Type: utils.NMDataType, Value: nm}}) + return ar.data.SetAsSlice(fullPath, []*utils.DataNode{{Type: utils.NMDataType, Value: nm}}) case utils.MetaTmp: _, err = ar.tmp.Set(fullPath.PathSlice[1:], []*utils.DataNode{{Type: utils.NMDataType, Value: nm}}) return @@ -292,16 +294,18 @@ type profile interface { func prepareData(prf profile, lData []*utils.OrderedNavigableMap, rsrSep string) (err error) { for _, mp := range lData { + newRow := true for el := mp.GetFirstElement(); el != nil; el = el.Next() { path := el.Value nmIt, _ := mp.Field(path) if nmIt == nil { continue // all attributes, not writable to diameter packet } - path = path[:len(path)-1] // remove the last index - if err = prf.Set(path, nmIt.Data, nmIt.NewBranch, rsrSep); err != nil { + // path = path[:len(path)-1] // remove the last index + if err = prf.Set(path, nmIt.Data, nmIt.NewBranch || newRow, rsrSep); err != nil { return } + newRow = false } } return diff --git a/loaders/libloader_test.go b/loaders/libloader_test.go index 6da30de96..3705e414a 100644 --- a/loaders/libloader_test.go +++ b/loaders/libloader_test.go @@ -31,7 +31,7 @@ import ( func TestTenantIDFromMap(t *testing.T) { exp := utils.NewTenantID("cgrates.org:ATTR1") - r := TenantIDFromMap(utils.MapStorage{ + r := TenantIDFromDataProvider(utils.MapStorage{ utils.Tenant: exp.Tenant, utils.ID: exp.ID, }) @@ -73,49 +73,13 @@ func TestNewRecord(t *testing.T) { if err != nil { t.Fatal(err) } - exp := utils.MapStorage{} + exp := utils.NewOrderedNavigableMap() if !reflect.DeepEqual(r, exp) { t.Errorf("Expected %+v, received %+q", exp, r) } } -func TestNewRecordErrors(t *testing.T) { - cfg := config.NewDefaultCGRConfig() - fs := engine.NewFilterS(cfg, nil, nil) - expErrMsg := "unsupported type: " - if _, err := newRecord(context.Background(), utils.MapStorage{}, - []*config.FCTemplate{ - {Type: "notSupported"}, - }, - "cgrates.org", fs, cfg, ltcache.NewCache(-1, 0, false, nil)); err == nil || err.Error() != expErrMsg { - t.Errorf("Expeceted: %q, received: %v", expErrMsg, err) - } - - r := &record{ - data: utils.MapStorage{ - "Tenant": []string{}, - }, - req: utils.MapStorage{}, - cfg: cfg.GetDataProvider(), - cache: ltcache.NewCache(-1, 0, false, nil), - } - if exp, rply := "{}", r.String(); exp != rply { - t.Errorf("Expected %q, received %q", exp, rply) - } - fc := []*config.FCTemplate{ - {Type: utils.MetaComposed, Path: "Tenant", Value: config.NewRSRParsersMustCompile("~*cfg.general.node_id", ";")}, - {Type: utils.MetaComposed, Path: "Tenant.NewID", Value: config.NewRSRParsersMustCompile("10", ";")}, - } - for _, f := range fc { - f.ComputePath() - } - if err := r.parseTemplates(context.Background(), fc, - "cgrates.org", fs, 0, "", ";"); err != utils.ErrWrongPath { - t.Errorf("Expeceted: %q, received: %v", utils.ErrWrongPath, err) - } -} - func TestNewRecordWithCahe(t *testing.T) { cfg := config.NewDefaultCGRConfig() fs := engine.NewFilterS(cfg, nil, nil) @@ -128,12 +92,16 @@ func TestNewRecordWithCahe(t *testing.T) { for _, f := range fc { f.ComputePath() } - exp := utils.MapStorage{"ID": "Attr1", "Tenant": "cgrates.org", "Value": "0"} + exp := utils.NewOrderedNavigableMap() + exp.SetAsSlice(utils.NewFullPath(utils.Tenant), []*utils.DataNode{{Type: utils.NMDataType, Value: &utils.DataLeaf{Data: "cgrates.org"}}}) + exp.SetAsSlice(utils.NewFullPath(utils.ID), []*utils.DataNode{{Type: utils.NMDataType, Value: &utils.DataLeaf{Data: "Attr1"}}}) + exp.SetAsSlice(utils.NewFullPath(utils.Value), []*utils.DataNode{{Type: utils.NMDataType, Value: &utils.DataLeaf{Data: "0"}}}) if r, err := newRecord(context.Background(), config.NewSliceDP([]string{"cgrates.org", "Attr1"}, nil), fc, "cgrates.org", fs, cfg, ltcache.NewCache(-1, 0, false, nil)); err != nil { t.Error(err) } else if !reflect.DeepEqual(r, exp) { - t.Errorf("Expected %+v, received %+q", exp, r) + t.Errorf("Expected %+v, received %+v", exp, r) + t.Errorf("Expected %+v, received %+v", utils.ToJSON(exp.GetOrder()), utils.ToJSON(r.GetOrder())) } } @@ -149,7 +117,10 @@ func TestNewRecordWithTmp(t *testing.T) { for _, f := range fc { f.ComputePath() } - exp := utils.MapStorage{"ID": "Attr1", "Tenant": "cgrates.org", "Value": "0"} + exp := utils.NewOrderedNavigableMap() + exp.SetAsSlice(utils.NewFullPath(utils.Tenant), []*utils.DataNode{{Type: utils.NMDataType, Value: &utils.DataLeaf{Data: "cgrates.org"}}}) + exp.SetAsSlice(utils.NewFullPath(utils.ID), []*utils.DataNode{{Type: utils.NMDataType, Value: &utils.DataLeaf{Data: "Attr1"}}}) + exp.SetAsSlice(utils.NewFullPath(utils.Value), []*utils.DataNode{{Type: utils.NMDataType, Value: &utils.DataLeaf{Data: "0"}}}) if r, err := newRecord(context.Background(), config.NewSliceDP([]string{"cgrates.org", "Attr1"}, nil), fc, "cgrates.org", fs, cfg, ltcache.NewCache(-1, 0, false, nil)); err != nil { t.Error(err) diff --git a/loaders/loader.go b/loaders/loader.go index cc56b706c..2eff8d03a 100644 --- a/loaders/loader.go +++ b/loaders/loader.go @@ -73,7 +73,7 @@ func removeFromDB(ctx *context.Context, dm *engine.DataManager, lType, tnt, id s return } -func setToDB(ctx *context.Context, dm *engine.DataManager, lType, rsrSep, tmz string, tntID *utils.TenantID, lDataSet []*utils.OrderedNavigableMap, withIndex, ratesPartial bool) (err error) { +func setToDB(ctx *context.Context, dm *engine.DataManager, lType, rsrSep string, tntID *utils.TenantID, lDataSet []*utils.OrderedNavigableMap, withIndex, ratesPartial bool) (err error) { switch lType { case utils.MetaAttributes: apf := &engine.AttributeProfile{ @@ -115,14 +115,14 @@ func setToDB(ctx *context.Context, dm *engine.DataManager, lType, rsrSep, tmz st } return dm.SetStatQueueProfile(ctx, stsPrf, withIndex) case utils.MetaThresholds: - tpTh := &engine.ThresholdProfile{ + thPrf := &engine.ThresholdProfile{ Tenant: tntID.Tenant, ID: tntID.ID, } - if err = prepareData(tpTh, lDataSet, rsrSep); err != nil { + if err = prepareData(thPrf, lDataSet, rsrSep); err != nil { return } - return dm.SetThresholdProfile(ctx, tpTh, withIndex) + return dm.SetThresholdProfile(ctx, thPrf, withIndex) case utils.MetaRoutes: spPrf := &engine.RouteProfile{ Tenant: tntID.Tenant, @@ -133,304 +133,236 @@ func setToDB(ctx *context.Context, dm *engine.DataManager, lType, rsrSep, tmz st } return dm.SetRouteProfile(ctx, spPrf, withIndex) case utils.MetaChargers: - cppModels := make(engine.ChargerMdls, len(lDataSet)) - for i, ld := range lDataSet { - cppModels[i] = new(engine.ChargerMdl) - if err = utils.UpdateStructWithIfaceMap(cppModels[i], ld); err != nil { - return - } + cpPrf := &engine.ChargerProfile{ + Tenant: tntID.Tenant, + ID: tntID.ID, } - - for _, tpCPP := range cppModels.AsTPChargers() { - if err = dm.SetChargerProfile(ctx, engine.APItoChargerProfile(tpCPP, tmz), withIndex); err != nil { - return - } + if err = prepareData(cpPrf, lDataSet, rsrSep); err != nil { + return } + return dm.SetChargerProfile(ctx, cpPrf, withIndex) case utils.MetaDispatchers: - dispModels := make(engine.DispatcherProfileMdls, len(lDataSet)) - for i, ld := range lDataSet { - dispModels[i] = new(engine.DispatcherProfileMdl) - if err = utils.UpdateStructWithIfaceMap(dispModels[i], ld); err != nil { - return - } + dpPrf := &engine.DispatcherProfile{ + Tenant: tntID.Tenant, + ID: tntID.ID, + StrategyParams: make(map[string]interface{}), } - for _, tpDsp := range dispModels.AsTPDispatcherProfiles() { - if err = dm.SetDispatcherProfile(ctx, engine.APItoDispatcherProfile(tpDsp, tmz), withIndex); err != nil { - return - } + if err = prepareData(dpPrf, lDataSet, rsrSep); err != nil { + return } + return dm.SetDispatcherProfile(ctx, dpPrf, withIndex) case utils.MetaDispatcherHosts: - dispModels := make(engine.DispatcherHostMdls, len(lDataSet)) - for i, ld := range lDataSet { - dispModels[i] = new(engine.DispatcherHostMdl) - if err = utils.UpdateStructWithIfaceMap(dispModels[i], ld); err != nil { - return - } + dpPrf := &engine.DispatcherHost{ + Tenant: tntID.Tenant, + RemoteHost: &config.RemoteHost{ + ID: tntID.ID, + Transport: utils.MetaJSON, + }, } - var tpDsps []*utils.TPDispatcherHost - if tpDsps, err = dispModels.AsTPDispatcherHosts(); err != nil { + if err = prepareData(dpPrf, lDataSet, rsrSep); err != nil { return } - for _, tpDsp := range tpDsps { - if err = dm.SetDispatcherHost(ctx, engine.APItoDispatcherHost(tpDsp)); err != nil { - return - } - } + return dm.SetDispatcherHost(ctx, dpPrf) case utils.MetaRateProfiles: - rpMdls := make(engine.RateProfileMdls, len(lDataSet)) - for i, ld := range lDataSet { - rpMdls[i] = new(engine.RateProfileMdl) - if err = utils.UpdateStructWithIfaceMap(rpMdls[i], ld); err != nil { - return - } + rpl := &utils.RateProfile{ + Tenant: tntID.Tenant, + ID: tntID.ID, + Rates: make(map[string]*utils.Rate), + MinCost: utils.NewDecimal(0, 0), + MaxCost: utils.NewDecimal(0, 0), } - for _, tpRpl := range rpMdls.AsTPRateProfile() { - var rpl *utils.RateProfile - if rpl, err = engine.APItoRateProfile(tpRpl, tmz); err != nil { - return - } - if ratesPartial { - err = dm.SetRateProfileRates(ctx, rpl, true) - } else { - err = dm.SetRateProfile(ctx, rpl, true) - } - if err != nil { - return - } - } - case utils.MetaActionProfiles: - acpsModels := make(engine.ActionProfileMdls, len(lDataSet)) - for i, ld := range lDataSet { - acpsModels[i] = new(engine.ActionProfileMdl) - if err = utils.UpdateStructWithIfaceMap(acpsModels[i], ld); err != nil { - return - } - } - - for _, tpAcp := range acpsModels.AsTPActionProfile() { - var acp *engine.ActionProfile - if acp, err = engine.APItoActionProfile(tpAcp, tmz); err != nil { - return - } - if err = dm.SetActionProfile(ctx, acp, true); err != nil { - return - } - } - case utils.MetaAccounts: - acpsModels := make(engine.AccountMdls, len(lDataSet)) - for i, ld := range lDataSet { - acpsModels[i] = new(engine.AccountMdl) - if err = utils.UpdateStructWithIfaceMap(acpsModels[i], ld); err != nil { - return - } - } - var accountTPModels []*utils.TPAccount - if accountTPModels, err = acpsModels.AsTPAccount(); err != nil { + if err = prepareData(rpl, lDataSet, rsrSep); err != nil { return } - for _, tpAcp := range accountTPModels { - var acp *utils.Account - if acp, err = engine.APItoAccount(tpAcp, tmz); err != nil { - return - } - if err = dm.SetAccount(ctx, acp, true); err != nil { - return - } + if ratesPartial { + err = dm.SetRateProfileRates(ctx, rpl, true) + } else { + err = dm.SetRateProfile(ctx, rpl, true) } + return + case utils.MetaActionProfiles: + acp := &engine.ActionProfile{ + Tenant: tntID.Tenant, + ID: tntID.ID, + Targets: make(map[string]utils.StringSet), + } + if err = prepareData(acp, lDataSet, rsrSep); err != nil { + return + } + return dm.SetActionProfile(ctx, acp, withIndex) + case utils.MetaAccounts: + acp := &utils.Account{ + Tenant: tntID.Tenant, + ID: tntID.ID, + Opts: make(map[string]interface{}), + Balances: make(map[string]*utils.Balance), + } + if err = prepareData(acp, lDataSet, rsrSep); err != nil { + return + } + return dm.SetAccount(ctx, acp, withIndex) } return } -func dryRun(ctx *context.Context, lType, rsrSep, tmz, ldrID string, tntID *utils.TenantID, lDataSet []utils.MapStorage) (err error) { +func dryRun(ctx *context.Context, lType, rsrSep, ldrID string, tntID *utils.TenantID, lDataSet []*utils.OrderedNavigableMap) (err error) { switch lType { case utils.MetaAttributes: - var apf *engine.AttributeProfile - if apf, err = NewAttributeProfile(tntID, lDataSet, rsrSep); err != nil { + apf := &engine.AttributeProfile{ + Tenant: tntID.Tenant, + ID: tntID.ID, + } + if err = prepareData(apf, lDataSet, rsrSep); err != nil { return } utils.Logger.Info( fmt.Sprintf("<%s-%s> DRY_RUN: AttributeProfile: %s", utils.LoaderS, ldrID, utils.ToJSON(apf))) case utils.MetaResources: - var res *engine.ResourceProfile - if res, err = NewResourceProfile(tntID, lDataSet); err != nil { + res := &engine.ResourceProfile{ + Tenant: tntID.Tenant, + ID: tntID.ID, + } + if err = prepareData(res, lDataSet, rsrSep); err != nil { return } utils.Logger.Info( fmt.Sprintf("<%s-%s> DRY_RUN: ResourceProfile: %s", utils.LoaderS, ldrID, utils.ToJSON(res))) case utils.MetaFilters: - var fltrPrf *engine.Filter - if fltrPrf, err = NewFilter(tntID, lDataSet); err != nil { + fltr := &engine.Filter{ + Tenant: tntID.Tenant, + ID: tntID.ID, + } + if err = prepareData(fltr, lDataSet, rsrSep); err != nil { + return + } + if err = fltr.Compile(); err != nil { return } utils.Logger.Info( fmt.Sprintf("<%s-%s> DRY_RUN: Filter: %s", - utils.LoaderS, ldrID, utils.ToJSON(fltrPrf))) + utils.LoaderS, ldrID, utils.ToJSON(fltr))) case utils.MetaStats: - stsModels := make(engine.StatMdls, len(lDataSet)) - for i, ld := range lDataSet { - stsModels[i] = new(engine.StatMdl) - if err = utils.UpdateStructWithIfaceMap(stsModels[i], ld); err != nil { - return - } + stsPrf := &engine.StatQueueProfile{ + Tenant: tntID.Tenant, + ID: tntID.ID, } - for _, tpSts := range stsModels.AsTPStats() { - var stsPrf *engine.StatQueueProfile - if stsPrf, err = engine.APItoStats(tpSts, tmz); err != nil { - return - } - utils.Logger.Info( - fmt.Sprintf("<%s-%s> DRY_RUN: StatsQueueProfile: %s", - utils.LoaderS, ldrID, utils.ToJSON(stsPrf))) + if err = prepareData(stsPrf, lDataSet, rsrSep); err != nil { + return } + utils.Logger.Info( + fmt.Sprintf("<%s-%s> DRY_RUN: StatsQueueProfile: %s", + utils.LoaderS, ldrID, utils.ToJSON(stsPrf))) case utils.MetaThresholds: - thModels := make(engine.ThresholdMdls, len(lDataSet)) - for i, ld := range lDataSet { - thModels[i] = new(engine.ThresholdMdl) - if err = utils.UpdateStructWithIfaceMap(thModels[i], ld); err != nil { - return - } + thPrf := &engine.ThresholdProfile{ + Tenant: tntID.Tenant, + ID: tntID.ID, } - for _, tpTh := range thModels.AsTPThreshold() { - var thPrf *engine.ThresholdProfile - if thPrf, err = engine.APItoThresholdProfile(tpTh, tmz); err != nil { - return - } - utils.Logger.Info( - fmt.Sprintf("<%s-%s> DRY_RUN: ThresholdProfile: %s", - utils.LoaderS, ldrID, utils.ToJSON(thPrf))) + if err = prepareData(thPrf, lDataSet, rsrSep); err != nil { + return } + utils.Logger.Info( + fmt.Sprintf("<%s-%s> DRY_RUN: ThresholdProfile: %s", + utils.LoaderS, ldrID, utils.ToJSON(thPrf))) case utils.MetaRoutes: - sppModels := make(engine.RouteMdls, len(lDataSet)) - for i, ld := range lDataSet { - sppModels[i] = new(engine.RouteMdl) - if err = utils.UpdateStructWithIfaceMap(sppModels[i], ld); err != nil { - return - } + spPrf := &engine.RouteProfile{ + Tenant: tntID.Tenant, + ID: tntID.ID, } - - for _, tpSpp := range sppModels.AsTPRouteProfile() { - var spPrf *engine.RouteProfile - if spPrf, err = engine.APItoRouteProfile(tpSpp, tmz); err != nil { - return - } - utils.Logger.Info( - fmt.Sprintf("<%s-%s> DRY_RUN: RouteProfile: %s", - utils.LoaderS, ldrID, utils.ToJSON(spPrf))) + if err = prepareData(spPrf, lDataSet, rsrSep); err != nil { + return } + utils.Logger.Info( + fmt.Sprintf("<%s-%s> DRY_RUN: RouteProfile: %s", + utils.LoaderS, ldrID, utils.ToJSON(spPrf))) case utils.MetaChargers: - cppModels := make(engine.ChargerMdls, len(lDataSet)) - for i, ld := range lDataSet { - cppModels[i] = new(engine.ChargerMdl) - if err = utils.UpdateStructWithIfaceMap(cppModels[i], ld); err != nil { - return - } + cpPrf := &engine.ChargerProfile{ + Tenant: tntID.Tenant, + ID: tntID.ID, } - - for _, tpCPP := range cppModels.AsTPChargers() { - utils.Logger.Info( - fmt.Sprintf("<%s-%s> DRY_RUN: ChargerProfile: %s", - utils.LoaderS, ldrID, utils.ToJSON(engine.APItoChargerProfile(tpCPP, tmz)))) + if err = prepareData(cpPrf, lDataSet, rsrSep); err != nil { + return } + utils.Logger.Info( + fmt.Sprintf("<%s-%s> DRY_RUN: ChargerProfile: %s", + utils.LoaderS, ldrID, utils.ToJSON(cpPrf))) case utils.MetaDispatchers: - dispModels := make(engine.DispatcherProfileMdls, len(lDataSet)) - for i, ld := range lDataSet { - dispModels[i] = new(engine.DispatcherProfileMdl) - if err = utils.UpdateStructWithIfaceMap(dispModels[i], ld); err != nil { - return - } + dpPrf := &engine.DispatcherProfile{ + Tenant: tntID.Tenant, + ID: tntID.ID, + StrategyParams: make(map[string]interface{}), } - for _, tpDsp := range dispModels.AsTPDispatcherProfiles() { - utils.Logger.Info( - fmt.Sprintf("<%s-%s> DRY_RUN: DispatcherProfile: %s", - utils.LoaderS, ldrID, utils.ToJSON(engine.APItoDispatcherProfile(tpDsp, tmz)))) + if err = prepareData(dpPrf, lDataSet, rsrSep); err != nil { + return } + utils.Logger.Info( + fmt.Sprintf("<%s-%s> DRY_RUN: DispatcherProfile: %s", + utils.LoaderS, ldrID, utils.ToJSON(dpPrf))) case utils.MetaDispatcherHosts: - dispModels := make(engine.DispatcherHostMdls, len(lDataSet)) - for i, ld := range lDataSet { - dispModels[i] = new(engine.DispatcherHostMdl) - if err = utils.UpdateStructWithIfaceMap(dispModels[i], ld); err != nil { - return - } + dpPrf := &engine.DispatcherHost{ + Tenant: tntID.Tenant, + RemoteHost: &config.RemoteHost{ + ID: tntID.ID, + Transport: utils.MetaJSON, + }, } - var tpDsps []*utils.TPDispatcherHost - if tpDsps, err = dispModels.AsTPDispatcherHosts(); err != nil { + if err = prepareData(dpPrf, lDataSet, rsrSep); err != nil { return } - for _, tpDsp := range tpDsps { - utils.Logger.Info( - fmt.Sprintf("<%s-%s> DRY_RUN: DispatcherHost: %s", - utils.LoaderS, ldrID, utils.ToJSON(engine.APItoDispatcherHost(tpDsp)))) - } + utils.Logger.Info( + fmt.Sprintf("<%s-%s> DRY_RUN: DispatcherHost: %s", + utils.LoaderS, ldrID, utils.ToJSON(dpPrf))) case utils.MetaRateProfiles: - rpMdls := make(engine.RateProfileMdls, len(lDataSet)) - for i, ld := range lDataSet { - rpMdls[i] = new(engine.RateProfileMdl) - if err = utils.UpdateStructWithIfaceMap(rpMdls[i], ld); err != nil { - return - } + rpl := &utils.RateProfile{ + Tenant: tntID.Tenant, + ID: tntID.ID, + Rates: make(map[string]*utils.Rate), + MinCost: utils.NewDecimal(0, 0), + MaxCost: utils.NewDecimal(0, 0), } - for _, tpRpl := range rpMdls.AsTPRateProfile() { - var rpl *utils.RateProfile - if rpl, err = engine.APItoRateProfile(tpRpl, tmz); err != nil { - return - } - utils.Logger.Info( - fmt.Sprintf("<%s-%s> DRY_RUN: RateProfile: %s", - utils.LoaderS, ldrID, utils.ToJSON(rpl))) - - } - case utils.MetaActionProfiles: - acpsModels := make(engine.ActionProfileMdls, len(lDataSet)) - for i, ld := range lDataSet { - acpsModels[i] = new(engine.ActionProfileMdl) - if err = utils.UpdateStructWithIfaceMap(acpsModels[i], ld); err != nil { - return - } - } - - for _, tpAcp := range acpsModels.AsTPActionProfile() { - var acp *engine.ActionProfile - if acp, err = engine.APItoActionProfile(tpAcp, tmz); err != nil { - return - } - utils.Logger.Info( - fmt.Sprintf("<%s-%s> DRY_RUN: ActionProfile: %s", - utils.LoaderS, ldrID, utils.ToJSON(acp))) - } - case utils.MetaAccounts: - acpsModels := make(engine.AccountMdls, len(lDataSet)) - for i, ld := range lDataSet { - acpsModels[i] = new(engine.AccountMdl) - if err = utils.UpdateStructWithIfaceMap(acpsModels[i], ld); err != nil { - return - } - } - var accountTPModels []*utils.TPAccount - if accountTPModels, err = acpsModels.AsTPAccount(); err != nil { + if err = prepareData(rpl, lDataSet, rsrSep); err != nil { return } - for _, tpAcp := range accountTPModels { - var acp *utils.Account - if acp, err = engine.APItoAccount(tpAcp, tmz); err != nil { - return - } - utils.Logger.Info( - fmt.Sprintf("<%s-%s> DRY_RUN: Accounts: %s", - utils.LoaderS, ldrID, utils.ToJSON(acp))) + utils.Logger.Info( + fmt.Sprintf("<%s-%s> DRY_RUN: RateProfile: %s", + utils.LoaderS, ldrID, utils.ToJSON(rpl))) + + case utils.MetaActionProfiles: + acp := &engine.ActionProfile{ + Tenant: tntID.Tenant, + ID: tntID.ID, + Targets: make(map[string]utils.StringSet), } + if err = prepareData(acp, lDataSet, rsrSep); err != nil { + return + } + utils.Logger.Info( + fmt.Sprintf("<%s-%s> DRY_RUN: ActionProfile: %s", + utils.LoaderS, ldrID, utils.ToJSON(acp))) + case utils.MetaAccounts: + acp := &utils.Account{ + Tenant: tntID.Tenant, + ID: tntID.ID, + Opts: make(map[string]interface{}), + Balances: make(map[string]*utils.Balance), + } + if err = prepareData(acp, lDataSet, rsrSep); err != nil { + return + } + utils.Logger.Info( + fmt.Sprintf("<%s-%s> DRY_RUN: Accounts: %s", + utils.LoaderS, ldrID, utils.ToJSON(acp))) } return } func newLoader(cfg *config.CGRConfig, ldrCfg *config.LoaderSCfg, dm *engine.DataManager, dataCache map[string]*ltcache.Cache, - timezone string, filterS *engine.FilterS, connMgr *engine.ConnManager, cacheConns []string) *loader { + filterS *engine.FilterS, connMgr *engine.ConnManager, cacheConns []string) *loader { return &loader{ cfg: cfg, ldrCfg: ldrCfg, dm: dm, - timezone: timezone, filterS: filterS, connMgr: connMgr, cacheConns: cacheConns, @@ -443,7 +375,6 @@ type loader struct { cfg *config.CGRConfig ldrCfg *config.LoaderSCfg dm *engine.DataManager - timezone string filterS *engine.FilterS connMgr *engine.ConnManager cacheConns []string @@ -452,14 +383,14 @@ type loader struct { Locker } -func (l *loader) process(ctx *context.Context, tntID *utils.TenantID, lDataSet []utils.MapStorage, lType, action, caching string, withIndex, partialRates bool) (err error) { +func (l *loader) process(ctx *context.Context, tntID *utils.TenantID, lDataSet []*utils.OrderedNavigableMap, lType, action, caching string, withIndex, partialRates bool) (err error) { switch action { case utils.MetaParse: return case utils.MetaDryRun: - return dryRun(ctx, lType, l.cfg.GeneralCfg().RSRSep, l.timezone, l.ldrCfg.ID, tntID, lDataSet) + return dryRun(ctx, lType, l.cfg.GeneralCfg().RSRSep, l.ldrCfg.ID, tntID, lDataSet) case utils.MetaStore: - err = setToDB(ctx, l.dm, lType, l.cfg.GeneralCfg().RSRSep, l.timezone, tntID, lDataSet, withIndex, partialRates) + err = setToDB(ctx, l.dm, lType, l.cfg.GeneralCfg().RSRSep, tntID, lDataSet, withIndex, partialRates) case utils.MetaRemove: err = removeFromDB(ctx, l.dm, lType, tntID.Tenant, tntID.ID, withIndex, partialRates, lDataSet[0]) default: @@ -516,7 +447,7 @@ func (l *loader) process(ctx *context.Context, tntID *utils.TenantID, lDataSet [ func (l *loader) processData(ctx *context.Context, csv CSVReader, tmpls []*config.FCTemplate, lType, action, caching string, withIndex, partialRates bool) (err error) { var prevTntID *utils.TenantID - var lData []utils.MapStorage + var lData []*utils.OrderedNavigableMap for lineNr := 1; ; lineNr++ { var record []string if record, err = csv.Read(); err != nil { @@ -529,14 +460,14 @@ func (l *loader) processData(ctx *context.Context, csv CSVReader, tmpls []*confi utils.LoaderS, l.ldrCfg.ID, csv.Path(), lineNr, err)) return } - var data utils.MapStorage + var data *utils.OrderedNavigableMap if data, err = newRecord(ctx, config.NewSliceDP(record, nil), tmpls, l.ldrCfg.Tenant, l.filterS, l.cfg, l.dataCache[lType]); err != nil { utils.Logger.Warning( fmt.Sprintf("<%s> <%s> file<%s> line: %d, error: %s", utils.LoaderS, l.ldrCfg.ID, csv.Path(), lineNr, err)) return } - tntID := TenantIDFromMap(data) + tntID := TenantIDFromDataProvider(data) if !prevTntID.Equal(tntID) { if prevTntID != nil { if err = l.process(ctx, prevTntID, lData, lType, action, caching, withIndex, partialRates); err != nil { @@ -544,7 +475,7 @@ func (l *loader) processData(ctx *context.Context, csv CSVReader, tmpls []*confi } } prevTntID = tntID - lData = make([]utils.MapStorage, 0, 1) + lData = make([]*utils.OrderedNavigableMap, 0, 1) } lData = append(lData, data) } diff --git a/loaders/loader_test.go b/loaders/loader_test.go index 571ec99eb..3372ab6fd 100644 --- a/loaders/loader_test.go +++ b/loaders/loader_test.go @@ -70,18 +70,28 @@ func testDryRunWithData(lType string, data []utils.MapStorage) (string, error) { var buf bytes.Buffer utils.Logger = utils.NewStdLoggerWithWriter(&buf, "", 7) - err := dryRun(context.Background(), lType, utils.InfieldSep, "", "test", TenantIDFromMap(data[0]), data) + err := dryRun(context.Background(), lType, utils.InfieldSep, "test", TenantIDFromDataProvider(data[0]), data) return buf.String(), err } func testDryRun(t *testing.T, lType string) string { - buf, err := testDryRunWithData(lType, []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID"}}) + data := utils.NewOrderedNavigableMap() + data.Set(utils.NewFullPath(utils.Tenant), "cgrates.org") + data.Set(utils.NewFullPath(utils.ID), "ID") + buf, err := testDryRunWithData(lType, []*utils.OrderedNavigableMap{data}) if err != nil { - t.Fatal(err) + t.Fatal(lType, err) } return buf } +func newOrderNavMap(mp utils.MapStorage) (o *utils.OrderedNavigableMap) { + o = utils.NewOrderedNavigableMap() + for k, v := range mp { + o.Set(utils.NewFullPath(k), v) + } + return +} func TestDryRun(t *testing.T) { if expLog, rplyLog := "[INFO] DRY_RUN: AttributeProfile: {\"Tenant\":\"cgrates.org\",\"ID\":\"ID\",\"FilterIDs\":null,\"Attributes\":null,\"Blocker\":false,\"Weight\":0}", testDryRun(t, utils.MetaAttributes); !strings.Contains(rplyLog, expLog) { @@ -95,41 +105,41 @@ func TestDryRun(t *testing.T) { testDryRun(t, utils.MetaFilters); !strings.Contains(rplyLog, expLog) { t.Errorf("Expected %+q, received %+q", expLog, rplyLog) } - if expLog, rplyLog := "[INFO] DRY_RUN: StatsQueueProfile: {\"Tenant\":\"cgrates.org\",\"ID\":\"ID\",\"FilterIDs\":[],\"QueueLength\":0,\"TTL\":0,\"MinItems\":0,\"Metrics\":[],\"Stored\":false,\"Blocker\":false,\"Weight\":0,\"ThresholdIDs\":[]}", + if expLog, rplyLog := "[INFO] DRY_RUN: StatsQueueProfile: {\"Tenant\":\"cgrates.org\",\"ID\":\"ID\",\"FilterIDs\":null,\"QueueLength\":0,\"TTL\":0,\"MinItems\":0,\"Metrics\":null,\"Stored\":false,\"Blocker\":false,\"Weight\":0,\"ThresholdIDs\":null}", testDryRun(t, utils.MetaStats); !strings.Contains(rplyLog, expLog) { t.Errorf("Expected %+q, received %+q", expLog, rplyLog) } - if expLog, rplyLog := "[INFO] DRY_RUN: ThresholdProfile: {\"Tenant\":\"cgrates.org\",\"ID\":\"ID\",\"FilterIDs\":[],\"MaxHits\":0,\"MinHits\":0,\"MinSleep\":0,\"Blocker\":false,\"Weight\":0,\"ActionProfileIDs\":[],\"Async\":false}", + if expLog, rplyLog := "[INFO] DRY_RUN: ThresholdProfile: {\"Tenant\":\"cgrates.org\",\"ID\":\"ID\",\"FilterIDs\":null,\"MaxHits\":0,\"MinHits\":0,\"MinSleep\":0,\"Blocker\":false,\"Weight\":0,\"ActionProfileIDs\":null,\"Async\":false}", testDryRun(t, utils.MetaThresholds); !strings.Contains(rplyLog, expLog) { t.Errorf("Expected %+q, received %+q", expLog, rplyLog) } - if expLog, rplyLog := "[INFO] DRY_RUN: RouteProfile: {\"Tenant\":\"cgrates.org\",\"ID\":\"ID\",\"FilterIDs\":[],\"Sorting\":\"\",\"SortingParameters\":[],\"Routes\":[],\"Weights\":null}", + if expLog, rplyLog := "[INFO] DRY_RUN: RouteProfile: {\"Tenant\":\"cgrates.org\",\"ID\":\"ID\",\"FilterIDs\":null,\"Sorting\":\"\",\"SortingParameters\":null,\"Routes\":null,\"Weights\":null}", testDryRun(t, utils.MetaRoutes); !strings.Contains(rplyLog, expLog) { t.Errorf("Expected %+q, received %+q", expLog, rplyLog) } - if expLog, rplyLog := "[INFO] DRY_RUN: ChargerProfile: {\"Tenant\":\"cgrates.org\",\"ID\":\"ID\",\"FilterIDs\":[],\"RunID\":\"\",\"AttributeIDs\":[],\"Weight\":0}", + if expLog, rplyLog := "[INFO] DRY_RUN: ChargerProfile: {\"Tenant\":\"cgrates.org\",\"ID\":\"ID\",\"FilterIDs\":null,\"RunID\":\"\",\"AttributeIDs\":null,\"Weight\":0}", testDryRun(t, utils.MetaChargers); !strings.Contains(rplyLog, expLog) { t.Errorf("Expected %+q, received %+q", expLog, rplyLog) } - if expLog, rplyLog := "[INFO] DRY_RUN: DispatcherProfile: {\"Tenant\":\"cgrates.org\",\"ID\":\"ID\",\"FilterIDs\":[],\"Strategy\":\"\",\"StrategyParams\":{},\"Weight\":0,\"Hosts\":[]}", + if expLog, rplyLog := "[INFO] DRY_RUN: DispatcherProfile: {\"Tenant\":\"cgrates.org\",\"ID\":\"ID\",\"FilterIDs\":null,\"Strategy\":\"\",\"StrategyParams\":{},\"Weight\":0,\"Hosts\":null}", testDryRun(t, utils.MetaDispatchers); !strings.Contains(rplyLog, expLog) { t.Errorf("Expected %+q, received %+q", expLog, rplyLog) } - if expLog, rplyLog := "[INFO] DRY_RUN: RateProfile: {\"Tenant\":\"cgrates.org\",\"ID\":\"ID\",\"FilterIDs\":[],\"Weights\":null,\"MinCost\":0,\"MaxCost\":0,\"MaxCostStrategy\":\"\",\"Rates\":{}}", + if expLog, rplyLog := "[INFO] DRY_RUN: RateProfile: {\"Tenant\":\"cgrates.org\",\"ID\":\"ID\",\"FilterIDs\":null,\"Weights\":null,\"MinCost\":0,\"MaxCost\":0,\"MaxCostStrategy\":\"\",\"Rates\":{}}", testDryRun(t, utils.MetaRateProfiles); !strings.Contains(rplyLog, expLog) { t.Errorf("Expected %+q, received %+q", expLog, rplyLog) } - if expLog, rplyLog := "[INFO] DRY_RUN: ActionProfile: {\"Tenant\":\"cgrates.org\",\"ID\":\"ID\",\"FilterIDs\":[],\"Weight\":0,\"Schedule\":\"\",\"Targets\":{},\"Actions\":[]}", + if expLog, rplyLog := "[INFO] DRY_RUN: ActionProfile: {\"Tenant\":\"cgrates.org\",\"ID\":\"ID\",\"FilterIDs\":null,\"Weight\":0,\"Schedule\":\"\",\"Targets\":{},\"Actions\":null}", testDryRun(t, utils.MetaActionProfiles); !strings.Contains(rplyLog, expLog) { t.Errorf("Expected %+q, received %+q", expLog, rplyLog) } - if expLog, rplyLog := "[INFO] DRY_RUN: Accounts: {\"Tenant\":\"cgrates.org\",\"ID\":\"ID\",\"FilterIDs\":[],\"Weights\":null,\"Opts\":null,\"Balances\":{},\"ThresholdIDs\":[]}", + if expLog, rplyLog := "[INFO] DRY_RUN: Accounts: {\"Tenant\":\"cgrates.org\",\"ID\":\"ID\",\"FilterIDs\":null,\"Weights\":null,\"Opts\":{},\"Balances\":{},\"ThresholdIDs\":null}", testDryRun(t, utils.MetaAccounts); !strings.Contains(rplyLog, expLog) { t.Errorf("Expected %+q, received %+q", expLog, rplyLog) } - rplyLog, err := testDryRunWithData(utils.MetaDispatcherHosts, []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID", utils.Address: "127.0.0.1"}}) + rplyLog, err := testDryRunWithData(utils.MetaDispatcherHosts, []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID", utils.Address: "127.0.0.1"})}) if err != nil { t.Fatal(err) } @@ -140,226 +150,205 @@ func TestDryRun(t *testing.T) { func TestDryRunWithUpdateStructErrors(t *testing.T) { expErrMsg := `strconv.ParseFloat: parsing "notWeight": invalid syntax` - if _, err := testDryRunWithData(utils.MetaAttributes, []utils.MapStorage{{utils.Weight: "notWeight"}}); err == nil || err.Error() != expErrMsg { + if _, err := testDryRunWithData(utils.MetaAttributes, []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Weight: "notWeight"})}); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } - if _, err := testDryRunWithData(utils.MetaResources, []utils.MapStorage{{utils.Weight: "notWeight"}}); err == nil || err.Error() != expErrMsg { + if _, err := testDryRunWithData(utils.MetaResources, []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Weight: "notWeight"})}); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } - if _, err := testDryRunWithData(utils.MetaStats, []utils.MapStorage{{utils.Weight: "notWeight"}}); err == nil || err.Error() != expErrMsg { + if _, err := testDryRunWithData(utils.MetaStats, []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Weight: "notWeight"})}); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } - if _, err := testDryRunWithData(utils.MetaThresholds, []utils.MapStorage{{utils.Weight: "notWeight"}}); err == nil || err.Error() != expErrMsg { + if _, err := testDryRunWithData(utils.MetaThresholds, []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Weight: "notWeight"})}); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } - if _, err := testDryRunWithData(utils.MetaChargers, []utils.MapStorage{{utils.Weight: "notWeight"}}); err == nil || err.Error() != expErrMsg { + if _, err := testDryRunWithData(utils.MetaChargers, []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Weight: "notWeight"})}); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } - if _, err := testDryRunWithData(utils.MetaDispatchers, []utils.MapStorage{{utils.Weight: "notWeight"}}); err == nil || err.Error() != expErrMsg { + if _, err := testDryRunWithData(utils.MetaDispatchers, []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Weight: "notWeight"})}); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } - if _, err := testDryRunWithData(utils.MetaActionProfiles, []utils.MapStorage{{utils.Weight: "notWeight"}}); err == nil || err.Error() != expErrMsg { + if _, err := testDryRunWithData(utils.MetaActionProfiles, []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Weight: "notWeight"})}); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } expErrMsg = `cannot update unsupported struct field: 0` - if _, err := testDryRunWithData(utils.MetaRoutes, []utils.MapStorage{{"PK": "notWeight"}}); err == nil || err.Error() != expErrMsg { + if _, err := testDryRunWithData(utils.MetaRoutes, []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{"PK": "notWeight"})}); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } - if _, err := testDryRunWithData(utils.MetaDispatcherHosts, []utils.MapStorage{{"PK": "notWeight"}}); err == nil || err.Error() != expErrMsg { + if _, err := testDryRunWithData(utils.MetaDispatcherHosts, []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{"PK": "notWeight"})}); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } - if _, err := testDryRunWithData(utils.MetaRateProfiles, []utils.MapStorage{{"PK": "notWeight"}}); err == nil || err.Error() != expErrMsg { + if _, err := testDryRunWithData(utils.MetaRateProfiles, []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{"PK": "notWeight"})}); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } - if _, err := testDryRunWithData(utils.MetaAccounts, []utils.MapStorage{{"PK": "notWeight"}}); err == nil || err.Error() != expErrMsg { + if _, err := testDryRunWithData(utils.MetaAccounts, []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{"PK": "notWeight"})}); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } } func TestDryRunWithModelsErrors(t *testing.T) { - expErrMsg := `Closed unspilit syntax` - if _, err := testDryRunWithData(utils.MetaAttributes, []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID", utils.Attributes: utils.MapStorage{"Value": "`", "Path": "Test"}}}); err == nil || err.Error() != expErrMsg { - t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) - } - - expErrMsg = `strconv.ParseFloat: parsing "float": invalid syntax` - if _, err := testDryRunWithData(utils.MetaResources, []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID", "Limit": "float"}}); err == nil || err.Error() != expErrMsg { - t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) - } - - expErrMsg = `emtpy RSRParser in rule: <>` - if _, err := testDryRunWithData(utils.MetaFilters, []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID", utils.Rules: utils.MapStorage{"Values": "`;", "Type": utils.MetaRSR}}}); err == nil || err.Error() != expErrMsg { + expErrMsg := `strconv.ParseFloat: parsing "float": invalid syntax` + if _, err := testDryRunWithData(utils.MetaResources, []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID", "Limit": "float"})}); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } expErrMsg = `time: invalid duration "float"` - if _, err := testDryRunWithData(utils.MetaStats, []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID", "TTL": "float"}}); err == nil || err.Error() != expErrMsg { + if _, err := testDryRunWithData(utils.MetaStats, []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID", "TTL": "float"})}); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } - if _, err := testDryRunWithData(utils.MetaThresholds, []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID", "MinSleep": "float"}}); err == nil || err.Error() != expErrMsg { + if _, err := testDryRunWithData(utils.MetaThresholds, []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID", "MinSleep": "float"})}); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } expErrMsg = `invalid Weight in string: <;float>` - if _, err := testDryRunWithData(utils.MetaRoutes, []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID", "Weights": ";float"}}); err == nil || err.Error() != expErrMsg { + if _, err := testDryRunWithData(utils.MetaRoutes, []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID", "Weights": ";float"})}); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } - if _, err := testDryRunWithData(utils.MetaRateProfiles, []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID", "Weights": ";float"}}); err == nil || err.Error() != expErrMsg { + if _, err := testDryRunWithData(utils.MetaRateProfiles, []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID", "Weights": ";float"})}); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } - if _, err := testDryRunWithData(utils.MetaAccounts, []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID", "Weights": ";float"}}); err == nil || err.Error() != expErrMsg { + if _, err := testDryRunWithData(utils.MetaAccounts, []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID", "Weights": ";float"})}); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } expErrMsg = `time: invalid duration "float"` - if _, err := testDryRunWithData(utils.MetaDispatcherHosts, []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID", "ReplyTimeout": "float", "Address": "127.0.0.1"}}); err == nil || err.Error() != expErrMsg { + if _, err := testDryRunWithData(utils.MetaDispatcherHosts, []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID", "ReplyTimeout": "float", "Address": "127.0.0.1"})}); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } - if _, err := testDryRunWithData(utils.MetaActionProfiles, []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID", "ActionTTL": "float", "ActionID": "ACCT"}}); err == nil || err.Error() != expErrMsg { + if _, err := testDryRunWithData(utils.MetaActionProfiles, []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID", "ActionTTL": "float", "ActionID": "ACCT"})}); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } expErrMsg = `invalid key: <1> for BalanceCostIncrements` - if _, err := testDryRunWithData(utils.MetaAccounts, []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID", "BalanceCostIncrements": "1", "BalanceID": "BalID"}}); err == nil || err.Error() != expErrMsg { + if _, err := testDryRunWithData(utils.MetaAccounts, []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID", "BalanceCostIncrements": "1", "BalanceID": "BalID"})}); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } } func TestSetToDBWithUpdateStructErrors(t *testing.T) { expErrMsg := `strconv.ParseFloat: parsing "notWeight": invalid syntax` - if err := setToDB(context.Background(), nil, utils.MetaAttributes, utils.InfieldSep, "", utils.NewTenantID(""), []utils.MapStorage{{utils.Weight: "notWeight"}}, true, false); err == nil || err.Error() != expErrMsg { + if err := setToDB(context.Background(), nil, utils.MetaAttributes, utils.InfieldSep, utils.NewTenantID(""), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Weight: "notWeight"})}, true, false); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } - if err := setToDB(context.Background(), nil, utils.MetaResources, utils.InfieldSep, "", utils.NewTenantID(""), []utils.MapStorage{{utils.Weight: "notWeight"}}, true, false); err == nil || err.Error() != expErrMsg { + if err := setToDB(context.Background(), nil, utils.MetaResources, utils.InfieldSep, utils.NewTenantID(""), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Weight: "notWeight"})}, true, false); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } - if err := setToDB(context.Background(), nil, utils.MetaStats, utils.InfieldSep, "", utils.NewTenantID(""), []utils.MapStorage{{utils.Weight: "notWeight"}}, true, false); err == nil || err.Error() != expErrMsg { + if err := setToDB(context.Background(), nil, utils.MetaStats, utils.InfieldSep, utils.NewTenantID(""), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Weight: "notWeight"})}, true, false); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } - if err := setToDB(context.Background(), nil, utils.MetaThresholds, utils.InfieldSep, "", utils.NewTenantID(""), []utils.MapStorage{{utils.Weight: "notWeight"}}, true, false); err == nil || err.Error() != expErrMsg { + if err := setToDB(context.Background(), nil, utils.MetaThresholds, utils.InfieldSep, utils.NewTenantID(""), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Weight: "notWeight"})}, true, false); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } - if err := setToDB(context.Background(), nil, utils.MetaChargers, utils.InfieldSep, "", utils.NewTenantID(""), []utils.MapStorage{{utils.Weight: "notWeight"}}, true, false); err == nil || err.Error() != expErrMsg { + if err := setToDB(context.Background(), nil, utils.MetaChargers, utils.InfieldSep, utils.NewTenantID(""), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Weight: "notWeight"})}, true, false); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } - if err := setToDB(context.Background(), nil, utils.MetaDispatchers, utils.InfieldSep, "", utils.NewTenantID(""), []utils.MapStorage{{utils.Weight: "notWeight"}}, true, false); err == nil || err.Error() != expErrMsg { + if err := setToDB(context.Background(), nil, utils.MetaDispatchers, utils.InfieldSep, utils.NewTenantID(""), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Weight: "notWeight"})}, true, false); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } - if err := setToDB(context.Background(), nil, utils.MetaActionProfiles, utils.InfieldSep, "", utils.NewTenantID(""), []utils.MapStorage{{utils.Weight: "notWeight"}}, true, false); err == nil || err.Error() != expErrMsg { + if err := setToDB(context.Background(), nil, utils.MetaActionProfiles, utils.InfieldSep, utils.NewTenantID(""), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Weight: "notWeight"})}, true, false); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } expErrMsg = `cannot update unsupported struct field: 0` - if err := setToDB(context.Background(), nil, utils.MetaRoutes, utils.InfieldSep, "", utils.NewTenantID(""), []utils.MapStorage{{"PK": "notWeight"}}, true, false); err == nil || err.Error() != expErrMsg { + if err := setToDB(context.Background(), nil, utils.MetaRoutes, utils.InfieldSep, utils.NewTenantID(""), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{"PK": "notWeight"})}, true, false); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } - if err := setToDB(context.Background(), nil, utils.MetaDispatcherHosts, utils.InfieldSep, "", utils.NewTenantID(""), []utils.MapStorage{{"PK": "notWeight"}}, true, false); err == nil || err.Error() != expErrMsg { + if err := setToDB(context.Background(), nil, utils.MetaDispatcherHosts, utils.InfieldSep, utils.NewTenantID(""), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{"PK": "notWeight"})}, true, false); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } - if err := setToDB(context.Background(), nil, utils.MetaRateProfiles, utils.InfieldSep, "", utils.NewTenantID(""), []utils.MapStorage{{"PK": "notWeight"}}, true, false); err == nil || err.Error() != expErrMsg { + if err := setToDB(context.Background(), nil, utils.MetaRateProfiles, utils.InfieldSep, utils.NewTenantID(""), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{"PK": "notWeight"})}, true, false); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } - if err := setToDB(context.Background(), nil, utils.MetaAccounts, utils.InfieldSep, "", utils.NewTenantID(""), []utils.MapStorage{{"PK": "notWeight"}}, true, false); err == nil || err.Error() != expErrMsg { + if err := setToDB(context.Background(), nil, utils.MetaAccounts, utils.InfieldSep, utils.NewTenantID(""), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{"PK": "notWeight"})}, true, false); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } } func TestSetToDBWithModelsErrors(t *testing.T) { - expErrMsg := `Closed unspilit syntax` - if err := setToDB(context.Background(), nil, utils.MetaAttributes, utils.InfieldSep, "", utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID", utils.Attributes: utils.MapStorage{"Value": "`", "Path": "Test"}}}, true, false); err == nil || err.Error() != expErrMsg { + expErrMsg := `strconv.ParseFloat: parsing "float": invalid syntax` + if err := setToDB(context.Background(), nil, utils.MetaResources, utils.InfieldSep, utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID", "Limit": "float"})}, true, false); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } - - expErrMsg = `strconv.ParseFloat: parsing "float": invalid syntax` - if err := setToDB(context.Background(), nil, utils.MetaResources, utils.InfieldSep, "", utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID", "Limit": "float"}}, true, false); err == nil || err.Error() != expErrMsg { - t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) - } - - expErrMsg = `emtpy RSRParser in rule: <>` - if err := setToDB(context.Background(), nil, utils.MetaFilters, utils.InfieldSep, "", utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID", utils.Rules: utils.MapStorage{"Values": "`;", "Type": utils.MetaRSR}}}, true, false); err == nil || err.Error() != expErrMsg { - t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) - } - expErrMsg = `time: invalid duration "float"` - if err := setToDB(context.Background(), nil, utils.MetaStats, utils.InfieldSep, "", utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID", "TTL": "float"}}, true, false); err == nil || err.Error() != expErrMsg { + if err := setToDB(context.Background(), nil, utils.MetaStats, utils.InfieldSep, utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID", "TTL": "float"})}, true, false); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } - if err := setToDB(context.Background(), nil, utils.MetaThresholds, utils.InfieldSep, "", utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID", "MinSleep": "float"}}, true, false); err == nil || err.Error() != expErrMsg { + if err := setToDB(context.Background(), nil, utils.MetaThresholds, utils.InfieldSep, utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID", "MinSleep": "float"})}, true, false); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } expErrMsg = `invalid Weight in string: <;float>` - if err := setToDB(context.Background(), nil, utils.MetaRoutes, utils.InfieldSep, "", utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID", "Weights": ";float"}}, true, false); err == nil || err.Error() != expErrMsg { + if err := setToDB(context.Background(), nil, utils.MetaRoutes, utils.InfieldSep, utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID", "Weights": ";float"})}, true, false); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } - if err := setToDB(context.Background(), nil, utils.MetaRateProfiles, utils.InfieldSep, "", utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID", "Weights": ";float"}}, true, false); err == nil || err.Error() != expErrMsg { + if err := setToDB(context.Background(), nil, utils.MetaRateProfiles, utils.InfieldSep, utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID", "Weights": ";float"})}, true, false); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } - if err := setToDB(context.Background(), nil, utils.MetaAccounts, utils.InfieldSep, "", utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID", "Weights": ";float"}}, true, false); err == nil || err.Error() != expErrMsg { + if err := setToDB(context.Background(), nil, utils.MetaAccounts, utils.InfieldSep, utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID", "Weights": ";float"})}, true, false); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } expErrMsg = `time: invalid duration "float"` - if err := setToDB(context.Background(), nil, utils.MetaDispatcherHosts, utils.InfieldSep, "", utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID", "ReplyTimeout": "float", "Address": "127.0.0.1"}}, true, false); err == nil || err.Error() != expErrMsg { + if err := setToDB(context.Background(), nil, utils.MetaDispatcherHosts, utils.InfieldSep, utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID", "ReplyTimeout": "float", "Address": "127.0.0.1"})}, true, false); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } - if err := setToDB(context.Background(), nil, utils.MetaActionProfiles, utils.InfieldSep, "", utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID", "ActionTTL": "float", "ActionID": "ACCT"}}, true, false); err == nil || err.Error() != expErrMsg { + if err := setToDB(context.Background(), nil, utils.MetaActionProfiles, utils.InfieldSep, utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID", "ActionTTL": "float", "ActionID": "ACCT"})}, true, false); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } expErrMsg = `invalid key: <1> for BalanceCostIncrements` - if err := setToDB(context.Background(), nil, utils.MetaAccounts, utils.InfieldSep, "", utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID", "BalanceCostIncrements": "1", "BalanceID": "BalID"}}, true, false); err == nil || err.Error() != expErrMsg { + if err := setToDB(context.Background(), nil, utils.MetaAccounts, utils.InfieldSep, utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID", "BalanceCostIncrements": "1", "BalanceID": "BalID"})}, true, false); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } } func TestSetToDBWithDBError(t *testing.T) { - if err := setToDB(context.Background(), nil, utils.MetaAttributes, utils.InfieldSep, "", utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID"}}, true, false); err != utils.ErrNoDatabaseConn { + if err := setToDB(context.Background(), nil, utils.MetaAttributes, utils.InfieldSep, utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, true, false); err != utils.ErrNoDatabaseConn { t.Fatal(err) } - if err := setToDB(context.Background(), nil, utils.MetaResources, utils.InfieldSep, "", utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID"}}, true, false); err != utils.ErrNoDatabaseConn { + if err := setToDB(context.Background(), nil, utils.MetaResources, utils.InfieldSep, utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, true, false); err != utils.ErrNoDatabaseConn { t.Fatal(err) } - if err := setToDB(context.Background(), nil, utils.MetaStats, utils.InfieldSep, "", utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID"}}, true, false); err != utils.ErrNoDatabaseConn { + if err := setToDB(context.Background(), nil, utils.MetaStats, utils.InfieldSep, utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, true, false); err != utils.ErrNoDatabaseConn { t.Fatal(err) } - if err := setToDB(context.Background(), nil, utils.MetaThresholds, utils.InfieldSep, "", utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID"}}, true, false); err != utils.ErrNoDatabaseConn { + if err := setToDB(context.Background(), nil, utils.MetaThresholds, utils.InfieldSep, utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, true, false); err != utils.ErrNoDatabaseConn { t.Fatal(err) } - if err := setToDB(context.Background(), nil, utils.MetaChargers, utils.InfieldSep, "", utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID"}}, true, false); err != utils.ErrNoDatabaseConn { + if err := setToDB(context.Background(), nil, utils.MetaChargers, utils.InfieldSep, utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, true, false); err != utils.ErrNoDatabaseConn { t.Fatal(err) } - if err := setToDB(context.Background(), nil, utils.MetaDispatchers, utils.InfieldSep, "", utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID"}}, true, false); err != utils.ErrNoDatabaseConn { + if err := setToDB(context.Background(), nil, utils.MetaDispatchers, utils.InfieldSep, utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, true, false); err != utils.ErrNoDatabaseConn { t.Fatal(err) } - if err := setToDB(context.Background(), nil, utils.MetaActionProfiles, utils.InfieldSep, "", utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID"}}, true, false); err != utils.ErrNoDatabaseConn { + if err := setToDB(context.Background(), nil, utils.MetaActionProfiles, utils.InfieldSep, utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, true, false); err != utils.ErrNoDatabaseConn { t.Fatal(err) } - if err := setToDB(context.Background(), nil, utils.MetaFilters, utils.InfieldSep, "", utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID"}}, true, false); err != utils.ErrNoDatabaseConn { + if err := setToDB(context.Background(), nil, utils.MetaFilters, utils.InfieldSep, utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, true, false); err != utils.ErrNoDatabaseConn { t.Fatal(err) } - if err := setToDB(context.Background(), nil, utils.MetaRoutes, utils.InfieldSep, "", utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID"}}, true, false); err != utils.ErrNoDatabaseConn { + if err := setToDB(context.Background(), nil, utils.MetaRoutes, utils.InfieldSep, utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, true, false); err != utils.ErrNoDatabaseConn { t.Fatal(err) } - if err := setToDB(context.Background(), nil, utils.MetaDispatcherHosts, utils.InfieldSep, "", utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID", "Address": "127.0.0.1"}}, true, false); err != utils.ErrNoDatabaseConn { + if err := setToDB(context.Background(), nil, utils.MetaDispatcherHosts, utils.InfieldSep, utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID", "Address": "127.0.0.1"})}, true, false); err != utils.ErrNoDatabaseConn { t.Fatal(err) } - if err := setToDB(context.Background(), nil, utils.MetaRateProfiles, utils.InfieldSep, "", utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID"}}, true, false); err != utils.ErrNoDatabaseConn { + if err := setToDB(context.Background(), nil, utils.MetaRateProfiles, utils.InfieldSep, utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, true, false); err != utils.ErrNoDatabaseConn { t.Fatal(err) } - if err := setToDB(context.Background(), nil, utils.MetaRateProfiles, utils.InfieldSep, "", utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID", utils.RateIDs: "RT1;RT2"}}, true, true); err != utils.ErrNoDatabaseConn { + if err := setToDB(context.Background(), nil, utils.MetaRateProfiles, utils.InfieldSep, utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID", utils.RateIDs: "RT1;RT2"})}, true, true); err != utils.ErrNoDatabaseConn { t.Fatal(err) } - if err := setToDB(context.Background(), nil, utils.MetaAccounts, utils.InfieldSep, "", utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID"}}, true, false); err != utils.ErrNoDatabaseConn { + if err := setToDB(context.Background(), nil, utils.MetaAccounts, utils.InfieldSep, utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, true, false); err != utils.ErrNoDatabaseConn { t.Fatal(err) } } @@ -367,7 +356,7 @@ func TestSetToDBWithDBError(t *testing.T) { func TestSetToDB(t *testing.T) { cfg := config.NewDefaultCGRConfig() dm := engine.NewDataManager(engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items), cfg.CacheCfg(), nil) - if err := setToDB(context.Background(), dm, utils.MetaAttributes, utils.InfieldSep, "", utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID"}}, true, false); err != nil { + if err := setToDB(context.Background(), dm, utils.MetaAttributes, utils.InfieldSep, utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, true, false); err != nil { t.Fatal(err) } v1 := &engine.AttributeProfile{Tenant: "cgrates.org", ID: "ID"} @@ -377,7 +366,7 @@ func TestSetToDB(t *testing.T) { t.Errorf("Expeceted: %v, received: %v", utils.ToJSON(v1), utils.ToJSON(prf)) } - if err := setToDB(context.Background(), dm, utils.MetaResources, utils.InfieldSep, "", utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID"}}, true, false); err != nil { + if err := setToDB(context.Background(), dm, utils.MetaResources, utils.InfieldSep, utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, true, false); err != nil { t.Fatal(err) } v2 := &engine.ResourceProfile{Tenant: "cgrates.org", ID: "ID"} @@ -387,7 +376,7 @@ func TestSetToDB(t *testing.T) { t.Errorf("Expeceted: %v, received: %v", utils.ToJSON(v2), utils.ToJSON(prf)) } - if err := setToDB(context.Background(), dm, utils.MetaStats, utils.InfieldSep, "", utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID"}}, true, false); err != nil { + if err := setToDB(context.Background(), dm, utils.MetaStats, utils.InfieldSep, utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, true, false); err != nil { t.Fatal(err) } v3 := &engine.StatQueueProfile{Tenant: "cgrates.org", ID: "ID", FilterIDs: []string{}, ThresholdIDs: []string{}, Metrics: []*engine.MetricWithFilters{}} @@ -397,7 +386,7 @@ func TestSetToDB(t *testing.T) { t.Errorf("Expeceted: %v, received: %v", utils.ToJSON(v3), utils.ToJSON(prf)) } - if err := setToDB(context.Background(), dm, utils.MetaThresholds, utils.InfieldSep, "", utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID"}}, true, false); err != nil { + if err := setToDB(context.Background(), dm, utils.MetaThresholds, utils.InfieldSep, utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, true, false); err != nil { t.Fatal(err) } v4 := &engine.ThresholdProfile{Tenant: "cgrates.org", ID: "ID", FilterIDs: []string{}, ActionProfileIDs: []string{}} @@ -407,7 +396,7 @@ func TestSetToDB(t *testing.T) { t.Errorf("Expeceted: %v, received: %v", utils.ToJSON(v4), utils.ToJSON(prf)) } - if err := setToDB(context.Background(), dm, utils.MetaChargers, utils.InfieldSep, "", utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID"}}, true, false); err != nil { + if err := setToDB(context.Background(), dm, utils.MetaChargers, utils.InfieldSep, utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, true, false); err != nil { t.Fatal(err) } v5 := &engine.ChargerProfile{Tenant: "cgrates.org", ID: "ID", FilterIDs: []string{}, AttributeIDs: []string{}} @@ -417,7 +406,7 @@ func TestSetToDB(t *testing.T) { t.Errorf("Expeceted: %v, received: %v", utils.ToJSON(v5), utils.ToJSON(prf)) } - if err := setToDB(context.Background(), dm, utils.MetaDispatchers, utils.InfieldSep, "", utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID"}}, true, false); err != nil { + if err := setToDB(context.Background(), dm, utils.MetaDispatchers, utils.InfieldSep, utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, true, false); err != nil { t.Fatal(err) } v6 := &engine.DispatcherProfile{Tenant: "cgrates.org", ID: "ID", FilterIDs: []string{}, StrategyParams: make(map[string]interface{}), Hosts: engine.DispatcherHostProfiles{}} @@ -427,7 +416,7 @@ func TestSetToDB(t *testing.T) { t.Errorf("Expeceted: %v, received: %v", utils.ToJSON(v6), utils.ToJSON(prf)) } - if err := setToDB(context.Background(), dm, utils.MetaActionProfiles, utils.InfieldSep, "", utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID"}}, true, false); err != nil { + if err := setToDB(context.Background(), dm, utils.MetaActionProfiles, utils.InfieldSep, utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, true, false); err != nil { t.Fatal(err) } v7 := &engine.ActionProfile{Tenant: "cgrates.org", ID: "ID", FilterIDs: []string{}, Targets: map[string]utils.StringSet{}, Actions: []*engine.APAction{}} @@ -437,7 +426,7 @@ func TestSetToDB(t *testing.T) { t.Errorf("Expeceted: %v, received: %v", utils.ToJSON(v7), utils.ToJSON(prf)) } - if err := setToDB(context.Background(), dm, utils.MetaFilters, utils.InfieldSep, "", utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID"}}, true, false); err != nil { + if err := setToDB(context.Background(), dm, utils.MetaFilters, utils.InfieldSep, utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, true, false); err != nil { t.Fatal(err) } v8 := &engine.Filter{Tenant: "cgrates.org", ID: "ID"} @@ -448,7 +437,7 @@ func TestSetToDB(t *testing.T) { t.Errorf("Expeceted: %v, received: %v", utils.ToJSON(v8), utils.ToJSON(prf)) } - if err := setToDB(context.Background(), dm, utils.MetaRoutes, utils.InfieldSep, "", utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID"}}, true, false); err != nil { + if err := setToDB(context.Background(), dm, utils.MetaRoutes, utils.InfieldSep, utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, true, false); err != nil { t.Fatal(err) } v9 := &engine.RouteProfile{Tenant: "cgrates.org", ID: "ID", FilterIDs: []string{}, SortingParameters: []string{}, Routes: []*engine.Route{}} @@ -458,7 +447,7 @@ func TestSetToDB(t *testing.T) { t.Errorf("Expeceted: %v, received: %v", utils.ToJSON(v9), utils.ToJSON(prf)) } - if err := setToDB(context.Background(), dm, utils.MetaDispatcherHosts, utils.InfieldSep, "", utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID", "Address": "127.0.0.1"}}, true, false); err != nil { + if err := setToDB(context.Background(), dm, utils.MetaDispatcherHosts, utils.InfieldSep, utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID", "Address": "127.0.0.1"})}, true, false); err != nil { t.Fatal(err) } v10 := &engine.DispatcherHost{Tenant: "cgrates.org", RemoteHost: &config.RemoteHost{ID: "ID", Address: "127.0.0.1", Transport: utils.MetaJSON}} @@ -468,7 +457,7 @@ func TestSetToDB(t *testing.T) { t.Errorf("Expeceted: %v, received: %v", utils.ToJSON(v10), utils.ToJSON(prf)) } - if err := setToDB(context.Background(), dm, utils.MetaRateProfiles, utils.InfieldSep, "", utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID"}}, true, false); err != nil { + if err := setToDB(context.Background(), dm, utils.MetaRateProfiles, utils.InfieldSep, utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, true, false); err != nil { t.Fatal(err) } v11 := &utils.RateProfile{Tenant: "cgrates.org", ID: "ID", FilterIDs: []string{}, Rates: map[string]*utils.Rate{}, MinCost: utils.NewDecimal(0, 0), MaxCost: utils.NewDecimal(0, 0)} @@ -478,7 +467,7 @@ func TestSetToDB(t *testing.T) { t.Errorf("Expeceted: %v, received: %v", utils.ToJSON(v11), utils.ToJSON(prf)) } - if err := setToDB(context.Background(), dm, utils.MetaAccounts, utils.InfieldSep, "", utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID"}}, true, false); err != nil { + if err := setToDB(context.Background(), dm, utils.MetaAccounts, utils.InfieldSep, utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, true, false); err != nil { t.Fatal(err) } v12 := &utils.Account{Tenant: "cgrates.org", ID: "ID", FilterIDs: []string{}, Balances: map[string]*utils.Balance{}, ThresholdIDs: []string{}} @@ -498,7 +487,7 @@ func TestLoaderProcess(t *testing.T) { for k, cfg := range cfg.LoaderCfg()[0].Cache { cache[k] = ltcache.NewCache(cfg.Limit, cfg.TTL, cfg.StaticTTL, nil) } - ld := newLoader(cfg, cfg.LoaderCfg()[0], dm, cache, "", fS, cM, nil) + ld := newLoader(cfg, cfg.LoaderCfg()[0], dm, cache, fS, cM, nil) if expLd := (&loader{ cfg: cfg, ldrCfg: cfg.LoaderCfg()[0], @@ -512,11 +501,11 @@ func TestLoaderProcess(t *testing.T) { } expErrMsg := `unsupported loader action: <"notSupported">` - if err := ld.process(context.Background(), utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{}, utils.MetaAttributes, "notSupported", utils.MetaNone, true, false); err == nil || err.Error() != expErrMsg { + if err := ld.process(context.Background(), utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{}, utils.MetaAttributes, "notSupported", utils.MetaNone, true, false); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) } - if err := ld.process(context.Background(), utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{}, utils.MetaAttributes, utils.MetaParse, utils.MetaNone, true, false); err != nil { + if err := ld.process(context.Background(), utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{}, utils.MetaAttributes, utils.MetaParse, utils.MetaNone, true, false); err != nil { t.Error(err) } @@ -527,7 +516,7 @@ func TestLoaderProcess(t *testing.T) { var buf bytes.Buffer utils.Logger = utils.NewStdLoggerWithWriter(&buf, "", 7) - if err := ld.process(context.Background(), utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID"}}, utils.MetaAttributes, utils.MetaDryRun, utils.MetaNone, true, false); err != nil { + if err := ld.process(context.Background(), utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, utils.MetaAttributes, utils.MetaDryRun, utils.MetaNone, true, false); err != nil { t.Error(err) } @@ -536,7 +525,7 @@ func TestLoaderProcess(t *testing.T) { t.Errorf("Expected %+q, received %+q", expLog, rplyLog) } - if err := ld.process(context.Background(), utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID"}}, utils.MetaAttributes, utils.MetaStore, utils.MetaNone, true, false); err != nil { + if err := ld.process(context.Background(), utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, utils.MetaAttributes, utils.MetaStore, utils.MetaNone, true, false); err != nil { t.Error(err) } v1 := &engine.AttributeProfile{Tenant: "cgrates.org", ID: "ID"} @@ -545,7 +534,7 @@ func TestLoaderProcess(t *testing.T) { } else if !reflect.DeepEqual(v1, prf) { t.Errorf("Expeceted: %v, received: %v", utils.ToJSON(v1), utils.ToJSON(prf)) } - if err := ld.process(context.Background(), utils.NewTenantID("cgrates.org:ID"), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID"}}, utils.MetaAttributes, utils.MetaRemove, utils.MetaNone, true, false); err != nil { + if err := ld.process(context.Background(), utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, utils.MetaAttributes, utils.MetaRemove, utils.MetaNone, true, false); err != nil { t.Error(err) } if _, err := dm.GetAttributeProfile(context.Background(), "cgrates.org", "ID", false, true, utils.NonTransactional); err != utils.ErrNotFound { @@ -580,9 +569,9 @@ func TestLoaderProcessCallCahe(t *testing.T) { for k, cfg := range cfg.LoaderCfg()[0].Cache { cache[k] = ltcache.NewCache(cfg.Limit, cfg.TTL, cfg.StaticTTL, nil) } - ld := newLoader(cfg, cfg.LoaderCfg()[0], dm, cache, "", fS, cM, []string{connID}) + ld := newLoader(cfg, cfg.LoaderCfg()[0], dm, cache, fS, cM, []string{connID}) - if err := ld.process(context.Background(), utils.NewTenantID(tntID), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID"}}, utils.MetaAttributes, utils.MetaStore, utils.MetaReload, true, false); err != nil { + if err := ld.process(context.Background(), utils.NewTenantID(tntID), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, utils.MetaAttributes, utils.MetaStore, utils.MetaReload, true, false); err != nil { t.Error(err) } if prf, err := dm.GetAttributeProfile(context.Background(), "cgrates.org", "ID", false, true, utils.NonTransactional); err != nil { @@ -597,7 +586,7 @@ func TestLoaderProcessCallCahe(t *testing.T) { t.Errorf("Expeceted: %v, received: %v", utils.ToJSON(exp), utils.ToJSON(clearCache)) } - if err := ld.process(context.Background(), utils.NewTenantID(tntID), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID"}}, utils.MetaResources, utils.MetaStore, utils.MetaReload, true, false); err != nil { + if err := ld.process(context.Background(), utils.NewTenantID(tntID), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, utils.MetaResources, utils.MetaStore, utils.MetaReload, true, false); err != nil { t.Error(err) } if prf, err := dm.GetResourceProfile(context.Background(), "cgrates.org", "ID", false, true, utils.NonTransactional); err != nil { @@ -612,7 +601,7 @@ func TestLoaderProcessCallCahe(t *testing.T) { t.Errorf("Expeceted: %v, received: %v", utils.ToJSON(exp), utils.ToJSON(clearCache)) } - if err := ld.process(context.Background(), utils.NewTenantID(tntID), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID"}}, utils.MetaStats, utils.MetaStore, utils.MetaReload, true, false); err != nil { + if err := ld.process(context.Background(), utils.NewTenantID(tntID), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, utils.MetaStats, utils.MetaStore, utils.MetaReload, true, false); err != nil { t.Error(err) } if prf, err := dm.GetStatQueueProfile(context.Background(), "cgrates.org", "ID", false, true, utils.NonTransactional); err != nil { @@ -627,7 +616,7 @@ func TestLoaderProcessCallCahe(t *testing.T) { t.Errorf("Expeceted: %v, received: %v", utils.ToJSON(exp), utils.ToJSON(clearCache)) } - if err := ld.process(context.Background(), utils.NewTenantID(tntID), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID"}}, utils.MetaThresholds, utils.MetaStore, utils.MetaReload, true, false); err != nil { + if err := ld.process(context.Background(), utils.NewTenantID(tntID), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, utils.MetaThresholds, utils.MetaStore, utils.MetaReload, true, false); err != nil { t.Error(err) } if prf, err := dm.GetThresholdProfile(context.Background(), "cgrates.org", "ID", false, true, utils.NonTransactional); err != nil { @@ -642,7 +631,7 @@ func TestLoaderProcessCallCahe(t *testing.T) { t.Errorf("Expeceted: %v, received: %v", utils.ToJSON(exp), utils.ToJSON(clearCache)) } - if err := ld.process(context.Background(), utils.NewTenantID(tntID), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID"}}, utils.MetaRoutes, utils.MetaStore, utils.MetaReload, true, false); err != nil { + if err := ld.process(context.Background(), utils.NewTenantID(tntID), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, utils.MetaRoutes, utils.MetaStore, utils.MetaReload, true, false); err != nil { t.Error(err) } if prf, err := dm.GetRouteProfile(context.Background(), "cgrates.org", "ID", false, true, utils.NonTransactional); err != nil { @@ -657,7 +646,7 @@ func TestLoaderProcessCallCahe(t *testing.T) { t.Errorf("Expeceted: %v, received: %v", utils.ToJSON(exp), utils.ToJSON(clearCache)) } - if err := ld.process(context.Background(), utils.NewTenantID(tntID), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID"}}, utils.MetaChargers, utils.MetaStore, utils.MetaReload, true, false); err != nil { + if err := ld.process(context.Background(), utils.NewTenantID(tntID), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, utils.MetaChargers, utils.MetaStore, utils.MetaReload, true, false); err != nil { t.Error(err) } if prf, err := dm.GetChargerProfile(context.Background(), "cgrates.org", "ID", false, true, utils.NonTransactional); err != nil { @@ -672,7 +661,7 @@ func TestLoaderProcessCallCahe(t *testing.T) { t.Errorf("Expeceted: %v, received: %v", utils.ToJSON(exp), utils.ToJSON(clearCache)) } - if err := ld.process(context.Background(), utils.NewTenantID(tntID), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID"}}, utils.MetaDispatchers, utils.MetaStore, utils.MetaReload, true, false); err != nil { + if err := ld.process(context.Background(), utils.NewTenantID(tntID), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, utils.MetaDispatchers, utils.MetaStore, utils.MetaReload, true, false); err != nil { t.Error(err) } if prf, err := dm.GetDispatcherProfile(context.Background(), "cgrates.org", "ID", false, true, utils.NonTransactional); err != nil { @@ -687,7 +676,7 @@ func TestLoaderProcessCallCahe(t *testing.T) { t.Errorf("Expeceted: %v, received: %v", utils.ToJSON(exp), utils.ToJSON(clearCache)) } - if err := ld.process(context.Background(), utils.NewTenantID(tntID), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID"}}, utils.MetaRateProfiles, utils.MetaStore, utils.MetaReload, true, false); err != nil { + if err := ld.process(context.Background(), utils.NewTenantID(tntID), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, utils.MetaRateProfiles, utils.MetaStore, utils.MetaReload, true, false); err != nil { t.Error(err) } if prf, err := dm.GetRateProfile(context.Background(), "cgrates.org", "ID", false, true, utils.NonTransactional); err != nil { @@ -702,7 +691,7 @@ func TestLoaderProcessCallCahe(t *testing.T) { t.Errorf("Expeceted: %v, received: %v", utils.ToJSON(exp), utils.ToJSON(clearCache)) } - if err := ld.process(context.Background(), utils.NewTenantID(tntID), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID"}}, utils.MetaActionProfiles, utils.MetaStore, utils.MetaReload, true, false); err != nil { + if err := ld.process(context.Background(), utils.NewTenantID(tntID), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, utils.MetaActionProfiles, utils.MetaStore, utils.MetaReload, true, false); err != nil { t.Error(err) } if prf, err := dm.GetActionProfile(context.Background(), "cgrates.org", "ID", false, true, utils.NonTransactional); err != nil { @@ -719,7 +708,7 @@ func TestLoaderProcessCallCahe(t *testing.T) { reloadCache, clearCache = nil, nil - if err := ld.process(context.Background(), utils.NewTenantID(tntID), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID"}}, utils.MetaFilters, utils.MetaStore, utils.MetaReload, true, false); err != nil { + if err := ld.process(context.Background(), utils.NewTenantID(tntID), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, utils.MetaFilters, utils.MetaStore, utils.MetaReload, true, false); err != nil { t.Error(err) } if prf, err := dm.GetFilter(context.Background(), "cgrates.org", "ID", false, true, utils.NonTransactional); err != nil { @@ -734,7 +723,7 @@ func TestLoaderProcessCallCahe(t *testing.T) { t.Errorf("Expeceted: %v, received: %v", utils.ToJSON(nil), utils.ToJSON(clearCache)) } - if err := ld.process(context.Background(), utils.NewTenantID(tntID), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID", "Address": "127.0.0.1"}}, utils.MetaDispatcherHosts, utils.MetaStore, utils.MetaReload, true, false); err != nil { + if err := ld.process(context.Background(), utils.NewTenantID(tntID), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID", "Address": "127.0.0.1"})}, utils.MetaDispatcherHosts, utils.MetaStore, utils.MetaReload, true, false); err != nil { t.Error(err) } if prf, err := dm.GetDispatcherHost(context.Background(), "cgrates.org", "ID", false, true, utils.NonTransactional); err != nil { @@ -751,7 +740,7 @@ func TestLoaderProcessCallCahe(t *testing.T) { reloadCache, clearCache = nil, nil - if err := ld.process(context.Background(), utils.NewTenantID(tntID), []utils.MapStorage{{utils.Tenant: "cgrates.org", utils.ID: "ID"}}, utils.MetaAccounts, utils.MetaStore, utils.MetaReload, true, false); err != nil { + if err := ld.process(context.Background(), utils.NewTenantID(tntID), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, utils.MetaAccounts, utils.MetaStore, utils.MetaReload, true, false); err != nil { t.Error(err) } if prf, err := dm.GetAccount(context.Background(), "cgrates.org", "ID"); err != nil { @@ -776,7 +765,7 @@ func TestLoaderProcessData(t *testing.T) { for k, cfg := range cfg.LoaderCfg()[0].Cache { cache[k] = ltcache.NewCache(cfg.Limit, cfg.TTL, cfg.StaticTTL, nil) } - ld := newLoader(cfg, cfg.LoaderCfg()[0], dm, cache, "", fS, cM, nil) + ld := newLoader(cfg, cfg.LoaderCfg()[0], dm, cache, fS, cM, nil) fc := []*config.FCTemplate{ {Path: utils.Tenant, Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("~*req.0", utils.RSRConstSep)}, @@ -816,7 +805,7 @@ func TestLoaderProcessDataErrors(t *testing.T) { for k, cfg := range cfg.LoaderCfg()[0].Cache { cache[k] = ltcache.NewCache(cfg.Limit, cfg.TTL, cfg.StaticTTL, nil) } - ld := newLoader(cfg, cfg.LoaderCfg()[0], dm, cache, "", fS, cM, nil) + ld := newLoader(cfg, cfg.LoaderCfg()[0], dm, cache, fS, cM, nil) fc := []*config.FCTemplate{ {Filters: []string{"*string"}}, @@ -857,7 +846,7 @@ func TestLoaderProcessFileURL(t *testing.T) { for k, cfg := range cfg.LoaderCfg()[0].Cache { cache[k] = ltcache.NewCache(cfg.Limit, cfg.TTL, cfg.StaticTTL, nil) } - ld := newLoader(cfg, cfg.LoaderCfg()[0], dm, cache, "", fS, cM, nil) + ld := newLoader(cfg, cfg.LoaderCfg()[0], dm, cache, fS, cM, nil) fc := []*config.FCTemplate{ {Path: utils.Tenant, Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("~*req.0", utils.RSRConstSep)}, @@ -948,7 +937,7 @@ func TestLoaderProcessIFile(t *testing.T) { WithIndex: true, Cache: utils.MetaNone, }, - }, dm, cache, "", fS, cM, nil) + }, dm, cache, fS, cM, nil) expErrMsg := fmt.Sprintf(`rename %s/Chargers.csv %s/Chargers.csv: no such file or directory`, tmpIn, tmpOut) if err := ld.processIFile(utils.EmptyString, utils.ChargersCsv); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) @@ -1035,7 +1024,7 @@ func TestLoaderProcessFolder(t *testing.T) { WithIndex: true, Cache: utils.MetaNone, }, - }, dm, cache, "", fS, cM, nil) + }, dm, cache, fS, cM, nil) f, err := os.Create(path.Join(tmpIn, utils.AttributesCsv)) if err != nil { @@ -1141,7 +1130,7 @@ func TestLoaderProcessFolderErrors(t *testing.T) { WithIndex: true, Cache: utils.MetaNone, }, - }, dm, cache, "", fS, cM, nil) + }, dm, cache, fS, cM, nil) f, err := os.Create(path.Join(tmpIn, utils.AttributesCsv)) if err != nil { @@ -1198,7 +1187,7 @@ func TestLoaderMoveUnprocessedFilesErrors(t *testing.T) { ID: "test", Enabled: true, TpInDir: "notAFolder", - }, nil, nil, "", nil, nil, nil) + }, nil, nil, nil, nil, nil) expErrMsg := "open notAFolder: no such file or directory" if err := ld.moveUnprocessedFiles(); err == nil || err.Error() != expErrMsg { @@ -1233,7 +1222,7 @@ func TestLoaderHandleFolder(t *testing.T) { RunDelay: time.Nanosecond, TpInDir: "/tmp/TestLoaderHandleFolder", Opts: &config.LoaderSOptsCfg{}, - }, nil, nil, "", nil, nil, nil) + }, nil, nil, nil, nil, nil) ld.Locker = mockLock{} stop := make(chan struct{}) close(stop) @@ -1261,7 +1250,7 @@ func TestLoaderListenAndServe(t *testing.T) { RunDelay: time.Nanosecond, TpInDir: "/tmp/TestLoaderListenAndServe", Opts: &config.LoaderSOptsCfg{}, - }, nil, nil, "", nil, nil, nil) + }, nil, nil, nil, nil, nil) ld.Locker = mockLock{} stop := make(chan struct{}) close(stop) @@ -1290,7 +1279,7 @@ func TestLoaderListenAndServeI(t *testing.T) { TpInDir: "/tmp/TestLoaderListenAndServeI", RunDelay: -1, Opts: &config.LoaderSOptsCfg{}, - }, nil, nil, "", nil, nil, nil) + }, nil, nil, nil, nil, nil) ld.Locker = mockLock{} stop := make(chan struct{}) close(stop) diff --git a/loaders/loaders.go b/loaders/loaders.go index 7f87d1ae9..6ed6e3969 100644 --- a/loaders/loaders.go +++ b/loaders/loaders.go @@ -31,13 +31,13 @@ import ( ) func NewLoaderService(cfg *config.CGRConfig, dm *engine.DataManager, - timezone string, filterS *engine.FilterS, + filterS *engine.FilterS, connMgr *engine.ConnManager) (ldrS *LoaderS) { ldrS = &LoaderS{cfg: cfg, cache: make(map[string]*ltcache.Cache)} for k, cfg := range cfg.LoaderCfg()[0].Cache { ldrS.cache[k] = ltcache.NewCache(cfg.Limit, cfg.TTL, cfg.StaticTTL, nil) } - ldrS.createLoaders(dm, timezone, filterS, connMgr) + ldrS.createLoaders(dm, filterS, connMgr) return } @@ -121,19 +121,19 @@ func (ldrS *LoaderS) V1Run(ctx *context.Context, args *ArgsProcessFolder, // Reload recreates the loaders map thread safe func (ldrS *LoaderS) Reload(dm *engine.DataManager, - timezone string, filterS *engine.FilterS, connMgr *engine.ConnManager) { + filterS *engine.FilterS, connMgr *engine.ConnManager) { ldrS.Lock() - ldrS.createLoaders(dm, timezone, filterS, connMgr) + ldrS.createLoaders(dm, filterS, connMgr) ldrS.Unlock() } // Reload recreates the loaders map thread safe func (ldrS *LoaderS) createLoaders(dm *engine.DataManager, - timezone string, filterS *engine.FilterS, connMgr *engine.ConnManager) { + filterS *engine.FilterS, connMgr *engine.ConnManager) { ldrS.ldrs = make(map[string]*loader) for _, ldrCfg := range ldrS.cfg.LoaderCfg() { if ldrCfg.Enabled { - ldrS.ldrs[ldrCfg.ID] = newLoader(ldrS.cfg, ldrCfg, dm, ldrS.cache, timezone, filterS, connMgr, ldrCfg.CacheSConns) + ldrS.ldrs[ldrCfg.ID] = newLoader(ldrS.cfg, ldrCfg, dm, ldrS.cache, filterS, connMgr, ldrCfg.CacheSConns) } } } diff --git a/loaders/loaders_test.go b/loaders/loaders_test.go index ac10fbc68..36bb97c2d 100644 --- a/loaders/loaders_test.go +++ b/loaders/loaders_test.go @@ -47,7 +47,7 @@ func TestNewLoaderService(t *testing.T) { for k, cfg := range cfg.LoaderCfg()[0].Cache { cache[k] = ltcache.NewCache(cfg.Limit, cfg.TTL, cfg.StaticTTL, nil) } - ld := NewLoaderService(cfg, dm, "", fS, cM) + ld := NewLoaderService(cfg, dm, fS, cM) if exp := (&LoaderS{ cfg: cfg, cache: cache, @@ -90,7 +90,7 @@ func TestNewLoaderService(t *testing.T) { } cfg.LoaderCfg()[0].Enabled = false - ld.Reload(dm, "", fS, cM) + ld.Reload(dm, fS, cM) if ld.Enabled() { t.Error("Expected loader to not be enabled") } @@ -145,7 +145,7 @@ func TestLoaderServiceV1Run(t *testing.T) { dm := engine.NewDataManager(engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items), cfg.CacheCfg(), cM) fS := engine.NewFilterS(cfg, cM, dm) - ld := NewLoaderService(cfg, dm, "", fS, cM) + ld := NewLoaderService(cfg, dm, fS, cM) var rply string if err := ld.V1Run(context.Background(), &ArgsProcessFolder{ APIOpts: map[string]interface{}{ @@ -221,7 +221,7 @@ func TestLoaderServiceV1RunErrors(t *testing.T) { dm := engine.NewDataManager(engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items), cfg.CacheCfg(), cM) fS := engine.NewFilterS(cfg, cM, dm) - ld := NewLoaderService(cfg, dm, "", fS, cM) + ld := NewLoaderService(cfg, dm, fS, cM) var rply string expErrMsg := "SERVER_ERROR: inline parse error for string: <*string>" @@ -296,7 +296,7 @@ func TestLoaderServiceV1RunErrors(t *testing.T) { } cfg.LoaderCfg()[0].Enabled = false - ld.Reload(dm, "", fS, cM) + ld.Reload(dm, fS, cM) expErrMsg = `UNKNOWN_LOADER: *default` if err := ld.V1Run(context.Background(), &ArgsProcessFolder{}, &rply); err == nil || err.Error() != expErrMsg { t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) diff --git a/services/loaders.go b/services/loaders.go index 4dfe8ecd8..a94b0a020 100644 --- a/services/loaders.go +++ b/services/loaders.go @@ -83,8 +83,7 @@ func (ldrs *LoaderService) Start(ctx *context.Context, _ context.CancelFunc) (er ldrs.Lock() defer ldrs.Unlock() - ldrs.ldrs = loaders.NewLoaderService(ldrs.cfg, datadb, - ldrs.cfg.GeneralCfg().DefaultTimezone, filterS, ldrs.connMgr) + ldrs.ldrs = loaders.NewLoaderService(ldrs.cfg, datadb, filterS, ldrs.connMgr) if !ldrs.ldrs.Enabled() { return @@ -119,8 +118,7 @@ func (ldrs *LoaderService) Reload(ctx *context.Context, _ context.CancelFunc) er ldrs.RLock() defer ldrs.RUnlock() - ldrs.ldrs.Reload(datadb, ldrs.cfg.GeneralCfg().DefaultTimezone, - filterS, ldrs.connMgr) + ldrs.ldrs.Reload(datadb, filterS, ldrs.connMgr) return ldrs.ldrs.ListenAndServe(ldrs.stopChan) } diff --git a/services/loaders_test.go b/services/loaders_test.go index 14cbdacb6..622515505 100644 --- a/services/loaders_test.go +++ b/services/loaders_test.go @@ -63,7 +63,7 @@ func TestLoaderSCoverage(t *testing.T) { t.Errorf("Expected service to be down") } srv.ldrs = loaders.NewLoaderService(cfg, &engine.DataManager{}, - "", &engine.FilterS{}, nil) + &engine.FilterS{}, nil) if !srv.IsRunning() { t.Errorf("Expected service to be running") } diff --git a/utils/account.go b/utils/account.go index f2ef20622..83ae47a9d 100644 --- a/utils/account.go +++ b/utils/account.go @@ -20,6 +20,7 @@ package utils import ( "sort" + "strings" "time" "github.com/ericlagergren/decimal" @@ -640,3 +641,148 @@ type ArgsActRemoveBalances struct { BalanceIDs []string APIOpts map[string]interface{} } + +func (ap *Account) Set(path []string, val interface{}, newBranch bool, _ string) (err error) { + switch len(path) { + case 0: + return ErrWrongPath + case 1: + switch path[0] { + default: + if strings.HasPrefix(path[0], Opts) && + path[0][4] == '[' && path[0][len(path[0])-1] == ']' { + ap.Opts[path[0][5:len(path[0])-1]] = val + } + if strings.HasPrefix(path[0], Balances) && + path[0][8] == '[' && path[0][len(path[0])-1] == ']' { + id := path[0][9 : len(path[0])-1] + if _, has := ap.Balances[id]; !has { + ap.Balances[id] = &Balance{ID: id, Opts: make(map[string]interface{}), Units: NewDecimal(0, 0)} + } + return ap.Balances[id].Set(path[1:], val, newBranch) + } + return ErrWrongPath + case Tenant: + ap.Tenant = IfaceAsString(val) + case ID: + ap.ID = IfaceAsString(val) + case FilterIDs: + ap.FilterIDs, err = IfaceAsStringSlice(val) + case ThresholdIDs: + ap.ThresholdIDs, err = IfaceAsStringSlice(val) + case Weights: + ap.Weights, err = NewDynamicWeightsFromString(IfaceAsString(val), InfieldSep, ANDSep) + } + return + default: + } + if strings.HasPrefix(path[0], Opts) && + path[0][4] == '[' && path[0][len(path[0])-1] == ']' { + return MapStorage(ap.Opts).Set(append([]string{path[0][5 : len(path[0])-1]}, path[1:]...), val) + } + if path[0] == Opts { + return MapStorage(ap.Opts).Set(path[1:], val) + } + var id string + if strings.HasPrefix(path[0], Balances) && + path[0][8] == '[' && path[0][len(path[0])-1] == ']' { + id = path[0][9 : len(path[0])-1] + } else if path[0] == Balances { + id = path[1] + path = path[1:] + } + if id == EmptyString { + if _, has := ap.Balances[id]; !has { + ap.Balances[id] = &Balance{ID: path[0], Opts: make(map[string]interface{}), Units: NewDecimal(0, 0)} + } + return ap.Balances[id].Set(path[1:], val, newBranch) + } + return ErrWrongPath +} + +func (bL *Balance) Set(path []string, val interface{}, newBranch bool) (err error) { + switch len(path) { + default: + case 0: + return ErrWrongPath + case 1: + switch path[0] { + default: + if strings.HasPrefix(path[0], Opts) && + path[0][4] == '[' && path[0][len(path[0])-1] == ']' { + bL.Opts[path[0][5:len(path[0])-1]] = val + } + return ErrWrongPath + case ID: + bL.ID = IfaceAsString(val) + case Type: + bL.Type = IfaceAsString(val) + case FilterIDs: + bL.FilterIDs, err = IfaceAsStringSlice(val) + case AttributeIDs: + bL.AttributeIDs, err = IfaceAsStringSlice(val) + case RateProfileIDs: + bL.RateProfileIDs, err = IfaceAsStringSlice(val) + case Units: + var valB *decimal.Big + valB, err = IfaceAsBig(val) + bL.Units = &Decimal{valB} + case Weights: + bL.Weights, err = NewDynamicWeightsFromString(IfaceAsString(val), InfieldSep, ANDSep) + } + return + case 2: + switch path[0] { + default: + case UnitFactors: + if len(bL.UnitFactors) == 0 || newBranch { + bL.UnitFactors = append(bL.UnitFactors, &UnitFactor{Factor: NewDecimal(0, 0)}) + } + uf := bL.UnitFactors[len(bL.UnitFactors)-1] + switch path[1] { + default: + return ErrWrongPath + case FilterIDs: + uf.FilterIDs, err = IfaceAsStringSlice(val) + case Factor: + var valB *decimal.Big + valB, err = IfaceAsBig(val) + uf.Factor = &Decimal{valB} + } + return + case CostIncrements: + if len(bL.CostIncrements) == 0 || newBranch { + bL.CostIncrements = append(bL.CostIncrements, new(CostIncrement)) + } + cI := bL.CostIncrements[len(bL.CostIncrements)-1] + switch path[1] { + default: + return ErrWrongPath + case FilterIDs: + cI.FilterIDs, err = IfaceAsStringSlice(val) + case Increment: + var valB *decimal.Big + valB, err = IfaceAsBig(val) + cI.Increment = &Decimal{valB} + case FixedFee: + var valB *decimal.Big + valB, err = IfaceAsBig(val) + cI.FixedFee = &Decimal{valB} + case RecurrentFee: + var valB *decimal.Big + valB, err = IfaceAsBig(val) + cI.RecurrentFee = &Decimal{valB} + } + return + } + } + + if strings.HasPrefix(path[0], Opts) && + path[0][4] == '[' && path[0][len(path[0])-1] == ']' { + return MapStorage(bL.Opts).Set(append([]string{path[0][5 : len(path[0])-1]}, path[1:]...), val) + } + if path[0] == Opts { + return MapStorage(bL.Opts).Set(path[1:], val) + } + return ErrWrongPath +} diff --git a/utils/consts.go b/utils/consts.go index 86e325a27..ad7c670cd 100644 --- a/utils/consts.go +++ b/utils/consts.go @@ -423,6 +423,13 @@ const ( Address = "Address" Addresses = "Addresses" Transport = "Transport" + ClientKey = "ClientKey" + ClientCertificate = "ClientCertificate" + CaCertificate = "CaCertificate" + ConnectAttempts = "ConnectAttempts" + Reconnects = "Reconnects" + ConnectTimeout = "ConnectTimeout" + ReplyTimeout = "ReplyTimeout" TLS = "TLS" Strategy = "Strategy" StrategyParameters = "StrategyParameters" @@ -495,6 +502,7 @@ const ( RatingSubject = "RatingSubject" Categories = "Categories" Blocker = "Blocker" + Params = "Params" RatingPlanID = "RatingPlanID" StartTime = "StartTime" AccountSummary = "AccountSummary" @@ -566,6 +574,8 @@ const ( MetricFilterIDs = "MetricFilterIDs" FieldName = "FieldName" Path = "Path" + Hosts = "Hosts" + StrategyParams = "StrategyParams" MetaRound = "*round" Pong = "Pong" MetaEventCost = "*event_cost" @@ -784,6 +794,12 @@ const ( MetaUsage = "*usage" MetaStartTime = "*startTime" Weights = "Weights" + ActivationTimes = "ActivationTimes" + IntervalRates = "IntervalRates" + IntervalStart = "IntervalStart" + Unit = "Unit" + Targets = "Targets" + Balances = "Balances" UnitFactors = "UnitFactors" CostIncrements = "CostIncrements" Factor = "Factor" diff --git a/utils/librates.go b/utils/librates.go index bfa579117..75fa2f463 100644 --- a/utils/librates.go +++ b/utils/librates.go @@ -21,6 +21,7 @@ package utils import ( "fmt" "sort" + "strings" "time" "github.com/cgrates/cron" @@ -566,3 +567,106 @@ type RemoveRPrfRates struct { RateIDs []string APIOpts map[string]interface{} } + +func (rp *RateProfile) Set(path []string, val interface{}, newBranch bool, _ string) (err error) { + if len(path) == 0 { + return ErrWrongPath + } + var rtID string + if strings.HasPrefix(path[0], Rates) && + path[0][5] == '[' && path[0][len(path[0])-1] == ']' { + rtID = path[0][6 : len(path[0])-1] + } else if len(path) != 1 && path[0] == Rates { + rtID = path[1] + path = path[1:] + } + if rtID != EmptyString { + if _, has := rp.Rates[rtID]; !has { + rp.Rates[rtID] = &Rate{ + ID: rtID, + } + } + return rp.Rates[rtID].Set(path[1:], val, newBranch) + } + if len(path) != 1 { + return ErrWrongPath + } + switch path[0] { + default: + return ErrWrongPath + case Tenant: + rp.Tenant = IfaceAsString(val) + case ID: + rp.ID = IfaceAsString(val) + case FilterIDs: + rp.FilterIDs, err = IfaceAsStringSlice(val) + case Weights: + rp.Weights, err = NewDynamicWeightsFromString(IfaceAsString(val), InfieldSep, ANDSep) + case MinCost: + var valB *decimal.Big + valB, err = IfaceAsBig(val) + rp.MinCost = &Decimal{valB} + case MaxCost: + var valB *decimal.Big + valB, err = IfaceAsBig(val) + rp.MaxCost = &Decimal{valB} + case MaxCostStrategy: + rp.MaxCostStrategy = IfaceAsString(val) + } + return + +} + +func (rt *Rate) Set(path []string, val interface{}, newBranch bool) (err error) { + switch len(path) { + default: + return ErrWrongPath + case 1: + switch path[0] { + default: + return ErrWrongPath + case ID: + rt.ID = IfaceAsString(val) + case FilterIDs: + rt.FilterIDs, err = IfaceAsStringSlice(val) + case Weights: + rt.Weights, err = NewDynamicWeightsFromString(IfaceAsString(val), InfieldSep, ANDSep) + case ActivationTimes: + rt.ActivationTimes = IfaceAsString(val) + case Blocker: + rt.Blocker, err = IfaceAsBool(val) + } + case 2: + if path[0] != IntervalRates { + return ErrWrongPath + } + if len(rt.IntervalRates) == 0 || newBranch { + rt.IntervalRates = append(rt.IntervalRates, new(IntervalRate)) + } + switch path[1] { + case IntervalStart: + var valB *decimal.Big + valB, err = IfaceAsBig(val) + rt.IntervalRates[len(rt.IntervalRates)-1].IntervalStart = &Decimal{valB} + case FixedFee: + var valB *decimal.Big + valB, err = IfaceAsBig(val) + rt.IntervalRates[len(rt.IntervalRates)-1].FixedFee = &Decimal{valB} + case RecurrentFee: + var valB *decimal.Big + valB, err = IfaceAsBig(val) + rt.IntervalRates[len(rt.IntervalRates)-1].RecurrentFee = &Decimal{valB} + case Unit: + var valB *decimal.Big + valB, err = IfaceAsBig(val) + rt.IntervalRates[len(rt.IntervalRates)-1].Unit = &Decimal{valB} + case Increment: + var valB *decimal.Big + valB, err = IfaceAsBig(val) + rt.IntervalRates[len(rt.IntervalRates)-1].Increment = &Decimal{valB} + default: + return ErrWrongPath + } + } + return +}