diff --git a/engine/actionprofile.go b/engine/actionprofile.go
index 196444a7a..7b90d25d9 100644
--- a/engine/actionprofile.go
+++ b/engine/actionprofile.go
@@ -204,3 +204,25 @@ func (aP *APAction) Set(path []string, val interface{}, newBranch bool) (err err
}
return
}
+
+func (ap *ActionProfile) Merge(v2 interface{}) {
+ vi := v2.(*ActionProfile)
+ if len(vi.Tenant) != 0 {
+ ap.Tenant = vi.Tenant
+ }
+ if len(vi.ID) != 0 {
+ ap.ID = vi.ID
+ }
+ ap.FilterIDs = append(ap.FilterIDs, vi.FilterIDs...)
+ ap.Actions = append(ap.Actions, vi.Actions...)
+
+ if vi.Weight != 0 {
+ ap.Weight = vi.Weight
+ }
+ if len(vi.Schedule) != 0 {
+ ap.Schedule = vi.Schedule
+ }
+ for k, v := range vi.Targets {
+ ap.Targets[k] = v
+ }
+}
diff --git a/engine/dispatcherprfl.go b/engine/dispatcherprfl.go
index 56e39a18c..b8773e4a4 100644
--- a/engine/dispatcherprfl.go
+++ b/engine/dispatcherprfl.go
@@ -296,3 +296,64 @@ func (dH *DispatcherHost) Set(path []string, val interface{}, newBranch bool, _
}
return
}
+
+func (dP *DispatcherProfile) Merge(v2 interface{}) {
+ vi := v2.(*DispatcherProfile)
+ if len(vi.Tenant) != 0 {
+ dP.Tenant = vi.Tenant
+ }
+ if len(vi.ID) != 0 {
+ dP.ID = vi.ID
+ }
+ dP.FilterIDs = append(dP.FilterIDs, vi.FilterIDs...)
+ dP.Hosts = append(dP.Hosts, vi.Hosts...)
+ if vi.Weight != 0 {
+ dP.Weight = vi.Weight
+ }
+ for k, v := range vi.StrategyParams {
+ dP.StrategyParams[k] = v
+ }
+ if len(vi.Strategy) != 0 {
+ dP.Strategy = vi.Strategy
+ }
+}
+
+func (dH *DispatcherHost) Merge(v2 interface{}) {
+ vi := v2.(*DispatcherHost)
+ if len(vi.Tenant) != 0 {
+ dH.Tenant = vi.Tenant
+ }
+ if len(vi.ID) != 0 {
+ dH.ID = vi.ID
+ }
+ if len(vi.Address) != 0 {
+ dH.Address = vi.Address
+ }
+ if len(vi.Transport) != 0 {
+ dH.Transport = vi.Transport
+ }
+ if len(vi.ClientKey) != 0 {
+ dH.ClientKey = vi.ClientKey
+ }
+ if len(vi.ClientCertificate) != 0 {
+ dH.ClientCertificate = vi.ClientCertificate
+ }
+ if len(vi.CaCertificate) != 0 {
+ dH.CaCertificate = vi.CaCertificate
+ }
+ if vi.TLS {
+ dH.TLS = vi.TLS
+ }
+ if vi.ConnectTimeout != 0 {
+ dH.ConnectTimeout = vi.ConnectTimeout
+ }
+ if vi.ReplyTimeout != 0 {
+ dH.ReplyTimeout = vi.ReplyTimeout
+ }
+ if vi.ConnectAttempts != 0 {
+ dH.ConnectAttempts = vi.ConnectAttempts
+ }
+ if vi.Reconnects != 0 {
+ dH.Reconnects = vi.Reconnects
+ }
+}
diff --git a/engine/libchargers.go b/engine/libchargers.go
index 4ac7c016b..6ddeab6da 100644
--- a/engine/libchargers.go
+++ b/engine/libchargers.go
@@ -78,3 +78,21 @@ func (cp *ChargerProfile) Set(path []string, val interface{}, newBranch bool, _
}
return
}
+
+func (cp *ChargerProfile) Merge(v2 interface{}) {
+ vi := v2.(*ChargerProfile)
+ if len(vi.Tenant) != 0 {
+ cp.Tenant = vi.Tenant
+ }
+ if len(vi.ID) != 0 {
+ cp.ID = vi.ID
+ }
+ if len(vi.RunID) != 0 {
+ cp.RunID = vi.RunID
+ }
+ cp.FilterIDs = append(cp.FilterIDs, vi.FilterIDs...)
+ cp.AttributeIDs = append(cp.AttributeIDs, vi.AttributeIDs...)
+ if vi.Weight != 0 {
+ cp.Weight = vi.Weight
+ }
+}
diff --git a/loaders/libloader.go b/loaders/libloader.go
index c2cabb38c..000067392 100644
--- a/loaders/libloader.go
+++ b/loaders/libloader.go
@@ -31,25 +31,22 @@ import (
// UpdateFromCSV will update LoaderData with data received from fileName,
// contained in record and processed with cfgTpl
-func newRecord(ctx *context.Context, req utils.DataProvider, tmpls []*config.FCTemplate, tnt string, filterS *engine.FilterS,
- cfg *config.CGRConfig, cache *ltcache.Cache) (_ *utils.OrderedNavigableMap, err error) {
- r := &record{
- data: utils.NewOrderedNavigableMap(),
+func newRecord(req utils.DataProvider, data profile, tnt string, cfg *config.CGRConfig, cache *ltcache.Cache) *record {
+ return &record{
+ data: data,
+ dp: config.NewObjectDP(data),
tmp: &utils.DataNode{Type: utils.NMMapType, Map: make(map[string]*utils.DataNode)},
req: req,
cfg: cfg.GetDataProvider(),
cache: cache,
tenant: tnt,
}
- if err = r.SetFields(ctx, tmpls, filterS, cfg.GeneralCfg().RoundingDecimals, cfg.GeneralCfg().DefaultTimezone, cfg.GeneralCfg().RSRSep); err != nil {
- return
- }
- return r.data, nil
}
type record struct {
tenant string
- data *utils.OrderedNavigableMap
+ dp utils.DataProvider
+ data profile
tmp *utils.DataNode
req utils.DataProvider
cfg utils.DataProvider
@@ -87,7 +84,7 @@ func RateIDsFromOrderedNavigableMap(data *utils.OrderedNavigableMap) ([]string,
func (ar *record) FieldAsInterface(fldPath []string) (val interface{}, err error) {
switch fldPath[0] {
default:
- val, err = ar.data.FieldAsInterface(fldPath)
+ val, err = ar.dp.FieldAsInterface(fldPath)
case utils.MetaReq:
if len(fldPath) != 1 {
val, err = ar.req.FieldAsInterface(fldPath[1:])
@@ -128,7 +125,6 @@ func (ar *record) FieldAsInterface(fldPath []string) (val interface{}, err error
}
//SetFields will populate fields of record out of templates
-
func (ar *record) SetFields(ctx *context.Context, tmpls []*config.FCTemplate, filterS *engine.FilterS, rndDec int, dftTmz, rsrSep string) (err error) {
ar.tmp = &utils.DataNode{Type: utils.NMMapType, Map: make(map[string]*utils.DataNode)}
for _, fld := range tmpls {
@@ -177,13 +173,9 @@ func (ar *record) SetFields(ctx *context.Context, tmpls []*config.FCTemplate, fi
nMItm := &utils.DataLeaf{Data: out, NewBranch: fld.NewBranch, AttributeID: fld.AttributeID}
switch fld.Type {
case utils.MetaComposed:
- err = ar.Compose(fullPath, nMItm)
- case utils.MetaGroup: // in case of *group type simply append to valSet
- err = ar.Append(fullPath, nMItm)
- case utils.MetaGeneric:
- err = ar.Set(fullPath, out)
+ err = ar.Compose(fullPath, nMItm, rsrSep)
default:
- err = ar.SetAsSlice(fullPath, nMItm)
+ err = ar.Set(fullPath, nMItm, rsrSep)
}
if err != nil {
return
@@ -196,25 +188,11 @@ func (ar *record) SetFields(ctx *context.Context, tmpls []*config.FCTemplate, fi
return
}
-// Set implements utils.NMInterface
-func (ar *record) SetAsSlice(fullPath *utils.FullPath, nm *utils.DataLeaf) (err error) {
- switch fullPath.PathSlice[0] {
- default:
- 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
- case utils.MetaUCH:
- ar.cache.Set(fullPath.Path[5:], nm.Data, nil)
- return
- }
-}
-
// RemoveAll deletes all fields at given prefix
func (ar *record) RemoveAll(prefix string) error {
switch prefix {
default:
- ar.data = utils.NewOrderedNavigableMap()
+ // ar.data = utils.NewOrderedNavigableMap()
case utils.MetaTmp:
ar.tmp = &utils.DataNode{Type: utils.NMMapType, Map: make(map[string]*utils.DataNode)}
case utils.MetaUCH:
@@ -227,10 +205,10 @@ func (ar *record) RemoveAll(prefix string) error {
func (ar *record) Remove(fullPath *utils.FullPath) error {
switch fullPath.PathSlice[0] {
default:
- return ar.data.Remove(&utils.FullPath{
+ return nil /* ar.data.Remove(&utils.FullPath{
PathSlice: fullPath.PathSlice,
Path: fullPath.Path,
- })
+ })*/
case utils.MetaTmp:
return ar.tmp.Remove(utils.CloneStringSlice(fullPath.PathSlice[1:]))
case utils.MetaUCH:
@@ -239,24 +217,9 @@ func (ar *record) Remove(fullPath *utils.FullPath) error {
}
}
-// Append sets the value at the given path
-// this used with full path and the processed path to not calculate them for every set
-func (ar *record) Append(fullPath *utils.FullPath, val *utils.DataLeaf) (err error) {
- switch fullPath.PathSlice[0] {
- case utils.MetaTmp:
- _, err = ar.tmp.Append(fullPath.PathSlice[1:], val)
- return
- case utils.MetaUCH:
- ar.cache.Set(fullPath.Path[5:], val.Data, nil)
- return
- default:
- return ar.data.Append(fullPath, val)
- }
-}
-
// Set sets the value at the given path
// this used with full path and the processed path to not calculate them for every set
-func (ar *record) Compose(fullPath *utils.FullPath, val *utils.DataLeaf) (err error) {
+func (ar *record) Compose(fullPath *utils.FullPath, val *utils.DataLeaf, sep string) (err error) {
switch fullPath.PathSlice[0] {
case utils.MetaTmp:
return ar.tmp.Compose(fullPath.PathSlice[1:], val)
@@ -271,36 +234,19 @@ func (ar *record) Compose(fullPath *utils.FullPath, val *utils.DataLeaf) (err er
ar.cache.Set(path, prv, nil)
return
default:
- return ar.data.Compose(fullPath, val)
- }
-}
-
-type profile interface {
- Set([]string, interface{}, bool, string) error
-}
-
-func prepareData(prf profile, lData []*utils.OrderedNavigableMap, rsrSep string) (err error) {
- for _, mp := range lData {
- for el := mp.GetFirstElement(); el != nil; el = el.Next() {
- path := el.Value
- nmIt, _ := mp.Field(path)
- if nmIt == nil {
- continue
- }
- path = path[:len(path)-1] // remove the last index
- if err = prf.Set(path, nmIt.Data, nmIt.NewBranch, rsrSep); err != nil {
- return
- }
+ var valStr string
+ if valStr, err = ar.FieldAsString(fullPath.PathSlice); err != nil && err != utils.ErrNotFound {
+ return
}
+ return ar.data.Set(fullPath.PathSlice, valStr+utils.IfaceAsString(val.Data), val.NewBranch, utils.InfieldSep)
}
- return
}
// Set implements utils.NMInterface
-func (ar *record) Set(fullPath *utils.FullPath, nm interface{}) (err error) {
+func (ar *record) Set(fullPath *utils.FullPath, nm *utils.DataLeaf, sep string) (err error) {
switch fullPath.PathSlice[0] {
default:
- return ar.data.Set(fullPath, nm)
+ return ar.data.Set(fullPath.PathSlice, nm.Data, nm.NewBranch, sep)
case utils.MetaTmp:
_, err = ar.tmp.Set(fullPath.PathSlice[1:], nm)
return
@@ -309,3 +255,80 @@ func (ar *record) Set(fullPath *utils.FullPath, nm interface{}) (err error) {
return
}
}
+
+type profile interface {
+ // utils.DataProvider
+ Set([]string, interface{}, bool, string) error
+ Merge(interface{})
+ TenantID() string
+}
+
+func newProfileFunc(lType string) func() profile {
+ switch lType {
+ case utils.MetaAttributes:
+ return func() profile {
+ return new(engine.AttributeProfile)
+ }
+ case utils.MetaResources:
+ return func() profile {
+ return new(engine.ResourceProfile)
+ }
+ case utils.MetaFilters:
+ return func() profile {
+ return new(engine.Filter)
+ }
+ case utils.MetaStats:
+ return func() profile {
+ return new(engine.StatQueueProfile)
+ }
+ case utils.MetaThresholds:
+ return func() profile {
+ return new(engine.ThresholdProfile)
+ }
+ case utils.MetaRoutes:
+ return func() profile {
+ return new(engine.RouteProfile)
+ }
+ case utils.MetaChargers:
+ return func() profile {
+ return new(engine.ChargerProfile)
+ }
+ case utils.MetaDispatchers:
+ return func() profile {
+ return &engine.DispatcherProfile{
+ StrategyParams: make(map[string]interface{}),
+ }
+ }
+ case utils.MetaDispatcherHosts:
+ return func() profile {
+ return &engine.DispatcherHost{
+ RemoteHost: &config.RemoteHost{
+ Transport: utils.MetaJSON,
+ },
+ }
+ }
+ case utils.MetaRateProfiles:
+ return func() profile {
+ return &utils.RateProfile{
+ Rates: make(map[string]*utils.Rate),
+ MinCost: utils.NewDecimal(0, 0),
+ MaxCost: utils.NewDecimal(0, 0),
+ }
+ }
+ case utils.MetaActionProfiles:
+ return func() profile {
+ return &engine.ActionProfile{
+ Targets: make(map[string]utils.StringSet),
+ }
+ }
+ case utils.MetaAccounts:
+ return func() profile {
+ return &utils.Account{
+ Opts: make(map[string]interface{}),
+ Balances: make(map[string]*utils.Balance),
+ }
+ }
+ default:
+ return func() profile { return nil }
+ }
+}
diff --git a/loaders/libloader_test.go b/loaders/libloader_test.go
index 9d3638d41..46b97d94c 100644
--- a/loaders/libloader_test.go
+++ b/loaders/libloader_test.go
@@ -19,6 +19,7 @@ along with this program. If not, see
package loaders
import (
+ "encoding/json"
"reflect"
"testing"
@@ -62,21 +63,20 @@ func TestNewRecord(t *testing.T) {
cfg := config.NewDefaultCGRConfig()
fs := engine.NewFilterS(cfg, nil, nil)
expErrMsg := "inline parse error for string: <*string>"
- if _, err := newRecord(context.Background(), utils.MapStorage{},
- []*config.FCTemplate{
+ if err := newRecord(utils.MapStorage{}, nil, "cgrates.org", cfg, ltcache.NewCache(-1, 0, false, nil)).
+ SetFields(context.Background(), []*config.FCTemplate{
{Filters: []string{"*exists:~*req.NoField:"}},
{Filters: []string{"*string"}},
- },
- "cgrates.org", fs, cfg, ltcache.NewCache(-1, 0, false, nil)); err == nil || err.Error() != expErrMsg {
+ }, fs, 0, "", utils.InfieldSep); err == nil || err.Error() != expErrMsg {
t.Errorf("Expeceted: %q, received: %v", expErrMsg, err)
}
- r, err := newRecord(context.Background(), utils.MapStorage{}, []*config.FCTemplate{}, "cgrates.org", fs, cfg, ltcache.NewCache(-1, 0, false, nil))
- if err != nil {
- t.Fatal(err)
+ pt := profileTest{}
+ if err := newRecord(utils.MapStorage{}, pt, "cgrates.org", cfg, ltcache.NewCache(-1, 0, false, nil)).
+ SetFields(context.Background(), []*config.FCTemplate{}, fs, 0, "", utils.InfieldSep); err != nil {
+ t.Error(err)
}
- exp := utils.NewOrderedNavigableMap()
- if !reflect.DeepEqual(r, exp) {
- t.Errorf("Expected %+v, received %+q", exp, r)
+ if len(pt) != 0 {
+ t.Fatal("Expected empty map")
}
}
@@ -92,16 +92,17 @@ func TestNewRecordWithCahe(t *testing.T) {
for _, f := range fc {
f.ComputePath()
}
- 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 {
+ exp := profileTest{
+ utils.Tenant: "cgrates.org",
+ utils.ID: "Attr1",
+ utils.Value: "0",
+ }
+ r := profileTest{}
+ if err := newRecord(config.NewSliceDP([]string{"cgrates.org", "Attr1"}, nil), r, "cgrates.org", cfg, ltcache.NewCache(-1, 0, false, nil)).
+ SetFields(context.Background(), fc, fs, 0, "", utils.InfieldSep); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(r, exp) {
t.Errorf("Expected %+v, received %+v", exp, r)
- t.Errorf("Expected %+v, received %+v", utils.ToJSON(exp.GetOrder()), utils.ToJSON(r.GetOrder()))
}
}
@@ -117,14 +118,32 @@ func TestNewRecordWithTmp(t *testing.T) {
for _, f := range fc {
f.ComputePath()
}
- 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 {
+ exp := profileTest{
+ utils.Tenant: "cgrates.org",
+ utils.ID: "Attr1",
+ utils.Value: "0",
+ }
+ r := profileTest{}
+ if err := newRecord(config.NewSliceDP([]string{"cgrates.org", "Attr1"}, nil), r, "cgrates.org", cfg, ltcache.NewCache(-1, 0, false, nil)).
+ SetFields(context.Background(), fc, fs, 0, "", utils.InfieldSep); 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)
}
}
+
+type profileTest utils.MapStorage
+
+func (p profileTest) Set(path []string, val interface{}, _ bool, _ string) error {
+ return utils.MapStorage(p).Set(path, val)
+}
+func (p profileTest) Merge(v2 interface{}) {
+ var vi map[string]interface{}
+ json.Unmarshal([]byte(utils.ToJSON(v2)), &vi)
+ for k, v := range vi {
+ (map[string]interface{}(p))[k] = v
+ }
+}
+func (p profileTest) TenantID() string {
+ return utils.ConcatenatedKey(utils.IfaceAsString(map[string]interface{}(p)[utils.Tenant]), utils.IfaceAsString(map[string]interface{}(p)[utils.ID]))
+}
diff --git a/loaders/loader.go b/loaders/loader.go
index 957271025..02bd4f98e 100644
--- a/loaders/loader.go
+++ b/loaders/loader.go
@@ -32,11 +32,13 @@ import (
"github.com/cgrates/ltcache"
)
-const (
- gprefix = utils.MetaGoogleAPI + utils.ConcatenatedKeySep
-)
+// const (
+// gprefix = utils.MetaGoogleAPI + utils.ConcatenatedKeySep
+// )
-func removeFromDB(ctx *context.Context, dm *engine.DataManager, lType, tnt, id string, withIndex, ratesPartial bool, ratesData *utils.OrderedNavigableMap) (_ error) {
+func removeFromDB(ctx *context.Context, dm *engine.DataManager, lType string, withIndex, ratesPartial bool, obj profile) (_ error) {
+ tntID := utils.NewTenantID(obj.TenantID())
+ tnt, id := tntID.Tenant, tntID.ID
switch lType {
case utils.MetaAttributes:
return dm.RemoveAttributeProfile(ctx, tnt, id, withIndex)
@@ -58,11 +60,12 @@ func removeFromDB(ctx *context.Context, dm *engine.DataManager, lType, tnt, id s
return dm.RemoveDispatcherHost(ctx, tnt, id)
case utils.MetaRateProfiles:
if ratesPartial {
- rateIDs, err := RateIDsFromOrderedNavigableMap(ratesData)
- if err != nil {
- return err
+ rt := obj.(*utils.RateProfile)
+ ids := make([]string, 0, len(rt.Rates))
+ for k := range rt.Rates {
+ ids = append(ids, k)
}
- return dm.RemoveRateProfileRates(ctx, tnt, id, rateIDs, withIndex)
+ return dm.RemoveRateProfileRates(ctx, tnt, id, ids, withIndex)
}
return dm.RemoveRateProfile(ctx, tnt, id, withIndex)
case utils.MetaActionProfiles:
@@ -73,108 +76,33 @@ func removeFromDB(ctx *context.Context, dm *engine.DataManager, lType, tnt, id s
return
}
-func setToDB(ctx *context.Context, dm *engine.DataManager, lType, rsrSep string, tntID *utils.TenantID, lDataSet []*utils.OrderedNavigableMap, withIndex, ratesPartial bool) (err error) {
+func setToDB(ctx *context.Context, dm *engine.DataManager, lType string, data profile, withIndex, ratesPartial bool) (err error) {
switch lType {
case utils.MetaAttributes:
- apf := &engine.AttributeProfile{
- Tenant: tntID.Tenant,
- ID: tntID.ID,
- }
- if err = prepareData(apf, lDataSet, rsrSep); err != nil {
- return
- }
- return dm.SetAttributeProfile(ctx, apf, withIndex)
+ return dm.SetAttributeProfile(ctx, data.(*engine.AttributeProfile), withIndex)
case utils.MetaResources:
- res := &engine.ResourceProfile{
- Tenant: tntID.Tenant,
- ID: tntID.ID,
- }
- if err = prepareData(res, lDataSet, rsrSep); err != nil {
- return
- }
- return dm.SetResourceProfile(ctx, res, withIndex)
+ return dm.SetResourceProfile(ctx, data.(*engine.ResourceProfile), withIndex)
case utils.MetaFilters:
- fltr := &engine.Filter{
- Tenant: tntID.Tenant,
- ID: tntID.ID,
- }
- if err = prepareData(fltr, lDataSet, rsrSep); err != nil {
- return
- }
+ fltr := data.(*engine.Filter)
fltr.Compress()
if err = fltr.Compile(); err != nil {
return
}
return dm.SetFilter(ctx, fltr, withIndex)
case utils.MetaStats:
- stsPrf := &engine.StatQueueProfile{
- Tenant: tntID.Tenant,
- ID: tntID.ID,
- }
- if err = prepareData(stsPrf, lDataSet, rsrSep); err != nil {
- return
- }
- return dm.SetStatQueueProfile(ctx, stsPrf, withIndex)
+ return dm.SetStatQueueProfile(ctx, data.(*engine.StatQueueProfile), withIndex)
case utils.MetaThresholds:
- thPrf := &engine.ThresholdProfile{
- Tenant: tntID.Tenant,
- ID: tntID.ID,
- }
- if err = prepareData(thPrf, lDataSet, rsrSep); err != nil {
- return
- }
- return dm.SetThresholdProfile(ctx, thPrf, withIndex)
+ return dm.SetThresholdProfile(ctx, data.(*engine.ThresholdProfile), withIndex)
case utils.MetaRoutes:
- spPrf := &engine.RouteProfile{
- Tenant: tntID.Tenant,
- ID: tntID.ID,
- }
- if err = prepareData(spPrf, lDataSet, rsrSep); err != nil {
- return
- }
- return dm.SetRouteProfile(ctx, spPrf, withIndex)
+ return dm.SetRouteProfile(ctx, data.(*engine.RouteProfile), withIndex)
case utils.MetaChargers:
- cpPrf := &engine.ChargerProfile{
- Tenant: tntID.Tenant,
- ID: tntID.ID,
- }
- if err = prepareData(cpPrf, lDataSet, rsrSep); err != nil {
- return
- }
- return dm.SetChargerProfile(ctx, cpPrf, withIndex)
+ return dm.SetChargerProfile(ctx, data.(*engine.ChargerProfile), withIndex)
case utils.MetaDispatchers:
- dpPrf := &engine.DispatcherProfile{
- Tenant: tntID.Tenant,
- ID: tntID.ID,
- StrategyParams: make(map[string]interface{}),
- }
- if err = prepareData(dpPrf, lDataSet, rsrSep); err != nil {
- return
- }
- return dm.SetDispatcherProfile(ctx, dpPrf, withIndex)
+ return dm.SetDispatcherProfile(ctx, data.(*engine.DispatcherProfile), withIndex)
case utils.MetaDispatcherHosts:
- dpPrf := &engine.DispatcherHost{
- Tenant: tntID.Tenant,
- RemoteHost: &config.RemoteHost{
- ID: tntID.ID,
- Transport: utils.MetaJSON,
- },
- }
- if err = prepareData(dpPrf, lDataSet, rsrSep); err != nil {
- return
- }
- return dm.SetDispatcherHost(ctx, dpPrf)
+ return dm.SetDispatcherHost(ctx, data.(*engine.DispatcherHost))
case utils.MetaRateProfiles:
- 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),
- }
- if err = prepareData(rpl, lDataSet, rsrSep); err != nil {
- return
- }
+ rpl := data.(*utils.RateProfile)
if ratesPartial {
err = dm.SetRateProfileRates(ctx, rpl, true)
} else {
@@ -182,180 +110,48 @@ func setToDB(ctx *context.Context, dm *engine.DataManager, lType, rsrSep string,
}
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)
+ return dm.SetActionProfile(ctx, data.(*engine.ActionProfile), 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 dm.SetAccount(ctx, data.(*utils.Account), withIndex)
}
return
}
-func dryRun(ctx *context.Context, lType, rsrSep, ldrID string, tntID *utils.TenantID, lDataSet []*utils.OrderedNavigableMap) (err error) {
+func dryRun(ctx *context.Context, lType, ldrID string, obj profile) (err error) {
+ var msg string
switch lType {
case utils.MetaAttributes:
- 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)))
+ msg = "<%s-%s> DRY_RUN: AttributeProfile: %s"
case utils.MetaResources:
- 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)))
+ msg = "<%s-%s> DRY_RUN: ResourceProfile: %s"
case utils.MetaFilters:
- fltr := &engine.Filter{
- Tenant: tntID.Tenant,
- ID: tntID.ID,
- }
- if err = prepareData(fltr, lDataSet, rsrSep); err != nil {
- return
- }
+ fltr := obj.(*engine.Filter)
fltr.Compress()
if err = fltr.Compile(); err != nil {
return
}
- utils.Logger.Info(
- fmt.Sprintf("<%s-%s> DRY_RUN: Filter: %s",
- utils.LoaderS, ldrID, utils.ToJSON(fltr)))
+ msg = "<%s-%s> DRY_RUN: Filter: %s"
case utils.MetaStats:
- stsPrf := &engine.StatQueueProfile{
- Tenant: tntID.Tenant,
- ID: tntID.ID,
- }
- 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)))
+ msg = "<%s-%s> DRY_RUN: StatsQueueProfile: %s"
case utils.MetaThresholds:
- thPrf := &engine.ThresholdProfile{
- Tenant: tntID.Tenant,
- ID: tntID.ID,
- }
- 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)))
+ msg = "<%s-%s> DRY_RUN: ThresholdProfile: %s"
case utils.MetaRoutes:
- spPrf := &engine.RouteProfile{
- Tenant: tntID.Tenant,
- ID: tntID.ID,
- }
- 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)))
+ msg = "<%s-%s> DRY_RUN: RouteProfile: %s"
case utils.MetaChargers:
- cpPrf := &engine.ChargerProfile{
- Tenant: tntID.Tenant,
- ID: tntID.ID,
- }
- 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)))
+ msg = "<%s-%s> DRY_RUN: ChargerProfile: %s"
case utils.MetaDispatchers:
- dpPrf := &engine.DispatcherProfile{
- Tenant: tntID.Tenant,
- ID: tntID.ID,
- StrategyParams: make(map[string]interface{}),
- }
- 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)))
+ msg = "<%s-%s> DRY_RUN: DispatcherProfile: %s"
case utils.MetaDispatcherHosts:
- dpPrf := &engine.DispatcherHost{
- Tenant: tntID.Tenant,
- RemoteHost: &config.RemoteHost{
- ID: tntID.ID,
- Transport: utils.MetaJSON,
- },
- }
- if err = prepareData(dpPrf, lDataSet, rsrSep); err != nil {
- return
- }
- utils.Logger.Info(
- fmt.Sprintf("<%s-%s> DRY_RUN: DispatcherHost: %s",
- utils.LoaderS, ldrID, utils.ToJSON(dpPrf)))
+ msg = "<%s-%s> DRY_RUN: DispatcherHost: %s"
case utils.MetaRateProfiles:
- 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),
- }
- if err = prepareData(rpl, lDataSet, rsrSep); err != nil {
- return
- }
- utils.Logger.Info(
- fmt.Sprintf("<%s-%s> DRY_RUN: RateProfile: %s",
- utils.LoaderS, ldrID, utils.ToJSON(rpl)))
-
+ msg = "<%s-%s> DRY_RUN: RateProfile: %s"
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)))
+ msg = "<%s-%s> DRY_RUN: ActionProfile: %s"
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)))
+ msg = "<%s-%s> DRY_RUN: Accounts: %s"
}
+ utils.Logger.Info(fmt.Sprintf(msg,
+ utils.LoaderS, ldrID, utils.ToJSON(obj)))
return
}
@@ -385,16 +181,16 @@ type loader struct {
Locker
}
-func (l *loader) process(ctx *context.Context, tntID *utils.TenantID, lDataSet []*utils.OrderedNavigableMap, lType, action, caching string, withIndex, partialRates bool) (err error) {
+func (l *loader) process(ctx *context.Context, obj profile, 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.ldrCfg.ID, tntID, lDataSet)
+ return dryRun(ctx, lType, l.ldrCfg.ID, obj)
case utils.MetaStore:
- err = setToDB(ctx, l.dm, lType, l.cfg.GeneralCfg().RSRSep, tntID, lDataSet, withIndex, partialRates)
+ err = setToDB(ctx, l.dm, lType, obj, withIndex, partialRates)
case utils.MetaRemove:
- err = removeFromDB(ctx, l.dm, lType, tntID.Tenant, tntID.ID, withIndex, partialRates, lDataSet[0])
+ err = removeFromDB(ctx, l.dm, lType, withIndex, partialRates, obj)
default:
return fmt.Errorf("unsupported loader action: <%q>", action)
}
@@ -403,7 +199,7 @@ func (l *loader) process(ctx *context.Context, tntID *utils.TenantID, lDataSet [
}
cacheArgs := make(map[string][]string)
var cacheIDs []string // verify if we need to clear indexe
- tntId := tntID.TenantID()
+ tntId := obj.TenantID()
switch lType {
case utils.MetaAttributes:
cacheIDs = []string{utils.CacheAttributeFilterIndexes}
@@ -448,8 +244,9 @@ 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.OrderedNavigableMap
+ newPrf := newProfileFunc(lType)
+ obj := newPrf()
+ var prevTntID string
for lineNr := 1; ; lineNr++ {
var record []string
if record, err = csv.Read(); err != nil {
@@ -462,27 +259,29 @@ func (l *loader) processData(ctx *context.Context, csv CSVReader, tmpls []*confi
utils.LoaderS, l.ldrCfg.ID, csv.Path(), lineNr, err))
return
}
- 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 {
+
+ tmp := newPrf()
+ if err = newRecord(config.NewSliceDP(record, nil), tmp, l.ldrCfg.Tenant, l.cfg, l.dataCache[lType]).
+ SetFields(ctx, tmpls, l.filterS, l.cfg.GeneralCfg().RoundingDecimals, l.cfg.GeneralCfg().DefaultTimezone, l.cfg.GeneralCfg().RSRSep); 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 := TenantIDFromOrderedNavigableMap(data)
- if !prevTntID.Equal(tntID) {
- if prevTntID != nil {
- if err = l.process(ctx, prevTntID, lData, lType, action, caching, withIndex, partialRates); err != nil {
+
+ if tntID := tmp.TenantID(); prevTntID != tntID {
+ if len(prevTntID) != 0 {
+ if err = l.process(ctx, obj, lType, action, caching, withIndex, partialRates); err != nil {
return
}
}
prevTntID = tntID
- lData = make([]*utils.OrderedNavigableMap, 0, 1)
+ obj = newPrf()
}
- lData = append(lData, data)
+ obj.Merge(tmp)
}
- if prevTntID != nil {
- err = l.process(ctx, prevTntID, lData, lType, action, caching, withIndex, partialRates)
+ if len(prevTntID) != 0 {
+ err = l.process(ctx, obj, lType, action, caching, withIndex, partialRates)
}
return
}
diff --git a/loaders/loader_test.go b/loaders/loader_test.go
index e63309e20..aa4c062f6 100644
--- a/loaders/loader_test.go
+++ b/loaders/loader_test.go
@@ -46,23 +46,23 @@ func TestRemoveFromDB(t *testing.T) {
for _, lType := range []string{utils.MetaAttributes, utils.MetaResources, utils.MetaFilters, utils.MetaStats,
utils.MetaThresholds, utils.MetaRoutes, utils.MetaChargers, utils.MetaDispatchers, utils.MetaDispatcherHosts,
utils.MetaRateProfiles, utils.MetaActionProfiles, utils.MetaAccounts} {
- if err := removeFromDB(context.Background(), dm, lType, "cgrates.org", "ID", true, false, utils.NewOrderedNavigableMap()); err != utils.ErrNotFound {
+ if err := removeFromDB(context.Background(), dm, lType, true, false, profileTest{utils.Tenant: "cgrates.org", utils.ID: "ID"}); err != utils.ErrNotFound {
t.Error(err)
}
}
expErrMsg := "cannot find RateIDs in map"
- if err := removeFromDB(context.Background(), dm, utils.MetaRateProfiles, "cgrates.org", "ID", true, true, utils.NewOrderedNavigableMap()); err == nil || err.Error() != expErrMsg {
+ if err := removeFromDB(context.Background(), dm, utils.MetaRateProfiles, true, true, profileTest{utils.Tenant: "cgrates.org", utils.ID: "ID"}); err == nil || err.Error() != expErrMsg {
t.Errorf("Expeceted: %v, received: %v", expErrMsg, err)
}
- if err := removeFromDB(context.Background(), dm, utils.MetaRateProfiles, "cgrates.org", "ID", true, true, newOrderNavMap(utils.MapStorage{utils.RateIDs: "RT1"})); err != utils.ErrNotFound {
+ if err := removeFromDB(context.Background(), dm, utils.MetaRateProfiles, true, true, &utils.RateProfile{Tenant: "cgrates.org", ID: "ID", Rates: map[string]*utils.Rate{"RT1": {}}}); err != utils.ErrNotFound {
t.Error(err)
}
- if err := removeFromDB(context.Background(), dm, utils.EmptyString, "cgrates.org", "ID", true, false, utils.NewOrderedNavigableMap()); err != nil {
+ if err := removeFromDB(context.Background(), dm, utils.EmptyString, true, false, profileTest{utils.Tenant: "cgrates.org", utils.ID: "ID"}); err != nil {
t.Error(err)
}
}
-func testDryRunWithData(lType string, data []utils.MapStorage) (string, error) {
+func testDryRunWithData(lType string, data profile) (string, error) {
tmpLogger := utils.Logger
defer func() {
utils.Logger = tmpLogger
@@ -70,15 +70,15 @@ 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", TenantIDFromOrderedNavigableMap(data[0]), data)
+ err := dryRun(context.Background(), lType, "test", data)
return buf.String(), err
}
func testDryRun(t *testing.T, lType string) string {
- data := utils.NewOrderedNavigableMap()
- data.SetAsSlice(utils.NewFullPath(utils.Tenant), []*utils.DataNode{utils.NewLeafNode("cgrates.org")})
- data.SetAsSlice(utils.NewFullPath(utils.ID), []*utils.DataNode{utils.NewLeafNode("ID")})
- buf, err := testDryRunWithData(lType, []*utils.OrderedNavigableMap{data})
+ buf, err := testDryRunWithData(lType, profileTest{
+ utils.Tenant: "cgrates.org",
+ utils.ID: "ID",
+ })
if err != nil {
t.Fatal(lType, err)
}
@@ -93,241 +93,96 @@ func newOrderNavMap(mp utils.MapStorage) (o *utils.OrderedNavigableMap) {
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}",
+ if expLog, rplyLog := "[INFO] DRY_RUN: AttributeProfile: {\"Tenant\":\"cgrates.org\",\"ID\":\"ID\"}",
testDryRun(t, utils.MetaAttributes); !strings.Contains(rplyLog, expLog) {
t.Errorf("Expected %+q, received %+q", expLog, rplyLog)
}
- if expLog, rplyLog := "[INFO] DRY_RUN: ResourceProfile: {\"Tenant\":\"cgrates.org\",\"ID\":\"ID\",\"FilterIDs\":null,\"UsageTTL\":0,\"Limit\":0,\"AllocationMessage\":\"\",\"Blocker\":false,\"Stored\":false,\"Weight\":0,\"ThresholdIDs\":null}",
+ if expLog, rplyLog := "[INFO] DRY_RUN: ResourceProfile: {\"Tenant\":\"cgrates.org\",\"ID\":\"ID\"}",
testDryRun(t, utils.MetaResources); !strings.Contains(rplyLog, expLog) {
t.Errorf("Expected %+q, received %+q", expLog, rplyLog)
}
- if expLog, rplyLog := "[INFO] DRY_RUN: Filter: {\"Tenant\":\"cgrates.org\",\"ID\":\"ID\",\"Rules\":[]}",
+ if expLog, rplyLog := "[INFO] DRY_RUN: Filter: {\"Tenant\":\"cgrates.org\",\"ID\":\"ID\"}",
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\":null,\"QueueLength\":0,\"TTL\":0,\"MinItems\":0,\"Metrics\":null,\"Stored\":false,\"Blocker\":false,\"Weight\":0,\"ThresholdIDs\":null}",
+ if expLog, rplyLog := "[INFO] DRY_RUN: StatsQueueProfile: {\"Tenant\":\"cgrates.org\",\"ID\":\"ID\"}",
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\":null,\"MaxHits\":0,\"MinHits\":0,\"MinSleep\":0,\"Blocker\":false,\"Weight\":0,\"ActionProfileIDs\":null,\"Async\":false}",
+ if expLog, rplyLog := "[INFO] DRY_RUN: ThresholdProfile: {\"Tenant\":\"cgrates.org\",\"ID\":\"ID\"}",
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\":null,\"Sorting\":\"\",\"SortingParameters\":null,\"Routes\":null,\"Weights\":null}",
+ if expLog, rplyLog := "[INFO] DRY_RUN: RouteProfile: {\"Tenant\":\"cgrates.org\",\"ID\":\"ID\"}",
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\":null,\"RunID\":\"\",\"AttributeIDs\":null,\"Weight\":0}",
+ if expLog, rplyLog := "[INFO] DRY_RUN: ChargerProfile: {\"Tenant\":\"cgrates.org\",\"ID\":\"ID\"}",
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\":null,\"Strategy\":\"\",\"StrategyParams\":{},\"Weight\":0,\"Hosts\":null}",
+ if expLog, rplyLog := "[INFO] DRY_RUN: DispatcherProfile: {\"Tenant\":\"cgrates.org\",\"ID\":\"ID\"}",
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\":null,\"Weights\":null,\"MinCost\":0,\"MaxCost\":0,\"MaxCostStrategy\":\"\",\"Rates\":{}}",
+ if expLog, rplyLog := "[INFO] DRY_RUN: RateProfile: {\"Tenant\":\"cgrates.org\",\"ID\":\"ID\"}",
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\":null,\"Weight\":0,\"Schedule\":\"\",\"Targets\":{},\"Actions\":null}",
+ if expLog, rplyLog := "[INFO] DRY_RUN: ActionProfile: {\"Tenant\":\"cgrates.org\",\"ID\":\"ID\"}",
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\":null,\"Weights\":null,\"Opts\":{},\"Balances\":{},\"ThresholdIDs\":null}",
+ if expLog, rplyLog := "[INFO] DRY_RUN: Accounts: {\"Tenant\":\"cgrates.org\",\"ID\":\"ID\"}",
testDryRun(t, utils.MetaAccounts); !strings.Contains(rplyLog, expLog) {
t.Errorf("Expected %+q, received %+q", expLog, rplyLog)
}
-
- 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)
- }
- if expLog := "[INFO] DRY_RUN: DispatcherHost: {\"Tenant\":\"cgrates.org\",\"ID\":\"ID\",\"Address\":\"127.0.0.1\",\"Transport\":\"*json\",\"ConnectAttempts\":0,\"Reconnects\":0,\"ConnectTimeout\":0,\"ReplyTimeout\":0,\"TLS\":false,\"ClientKey\":\"\",\"ClientCertificate\":\"\",\"CaCertificate\":\"\"}"; !strings.Contains(rplyLog, expLog) {
+ if expLog, rplyLog := "[INFO] DRY_RUN: DispatcherHost: {\"Tenant\":\"cgrates.org\",\"ID\":\"ID\"}",
+ testDryRun(t, utils.MetaDispatcherHosts); !strings.Contains(rplyLog, expLog) {
t.Errorf("Expected %+q, received %+q", expLog, rplyLog)
}
}
-func TestDryRunWithUpdateStructErrors(t *testing.T) {
- expErrMsg := `strconv.ParseFloat: parsing "notWeight": invalid syntax`
- 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.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.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.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.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.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.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Weight: "notWeight"})}); err == nil || err.Error() != expErrMsg {
- t.Errorf("Expeceted: %v, received: %v", expErrMsg, err)
- }
-}
-
-func TestDryRunWithModelsErrors(t *testing.T) {
- 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.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.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.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.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.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.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.MetaFilters, []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID", "ReplyTimeout": "float"})}); err != utils.ErrWrongPath {
- t.Errorf("Expeceted: %v, received: %v", expErrMsg, err)
- }
-
- expErrMsg = `emtpy RSRParser in rule: <>`
- data := newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})
- data.SetAsSlice(utils.NewFullPath("Rules.Type"), []*utils.DataNode{utils.NewLeafNode("*no")})
- if _, err := testDryRunWithData(utils.MetaFilters, []*utils.OrderedNavigableMap{data}); 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.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.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.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.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.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.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.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Weight: "notWeight"})}, true, false); err == nil || err.Error() != expErrMsg {
- t.Errorf("Expeceted: %v, received: %v", expErrMsg, err)
- }
-
-}
-
-func TestSetToDBWithModelsErrors(t *testing.T) {
- 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 = `time: invalid duration "float"`
- 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.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.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.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.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.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.MetaFilters, utils.InfieldSep, utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID", "ReplyTimeout": "float"})}, true, false); err != utils.ErrWrongPath {
- t.Errorf("Expeceted: %v, received: %v", expErrMsg, err)
- }
-
- expErrMsg = `emtpy RSRParser in rule: <>`
- data := newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})
- data.SetAsSlice(utils.NewFullPath("Rules.Type"), []*utils.DataNode{utils.NewLeafNode("*no")})
- if err := setToDB(context.Background(), nil, utils.MetaFilters, utils.InfieldSep, utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{data}, true, false); err == nil || err.Error() != expErrMsg {
- t.Errorf("Expeceted: %v, received: %v", expErrMsg, err)
- }
- if err := setToDB(context.Background(), nil, utils.EmptyString, utils.InfieldSep, utils.NewTenantID("cgrates.org:ID"), []*utils.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, true, false); err != nil {
- t.Error(err)
- }
-}
-
func TestSetToDBWithDBError(t *testing.T) {
- 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 {
+ if err := setToDB(context.Background(), nil, utils.MetaAttributes, newProfileFunc(utils.MetaAttributes)(), true, false); err != utils.ErrNoDatabaseConn {
t.Fatal(err)
}
- 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 {
+ if err := setToDB(context.Background(), nil, utils.MetaResources, newProfileFunc(utils.MetaResources)(), true, false); err != utils.ErrNoDatabaseConn {
t.Fatal(err)
}
- 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 {
+ if err := setToDB(context.Background(), nil, utils.MetaStats, newProfileFunc(utils.MetaStats)(), true, false); err != utils.ErrNoDatabaseConn {
t.Fatal(err)
}
- 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 {
+ if err := setToDB(context.Background(), nil, utils.MetaThresholds, newProfileFunc(utils.MetaThresholds)(), true, false); err != utils.ErrNoDatabaseConn {
t.Fatal(err)
}
- 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 {
+ if err := setToDB(context.Background(), nil, utils.MetaChargers, newProfileFunc(utils.MetaChargers)(), true, false); err != utils.ErrNoDatabaseConn {
t.Fatal(err)
}
- 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 {
+ if err := setToDB(context.Background(), nil, utils.MetaDispatchers, newProfileFunc(utils.MetaDispatchers)(), true, false); err != utils.ErrNoDatabaseConn {
t.Fatal(err)
}
- 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 {
+ if err := setToDB(context.Background(), nil, utils.MetaActionProfiles, newProfileFunc(utils.MetaActionProfiles)(), true, false); err != utils.ErrNoDatabaseConn {
t.Fatal(err)
}
- 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 {
+ if err := setToDB(context.Background(), nil, utils.MetaFilters, newProfileFunc(utils.MetaFilters)(), true, false); err != utils.ErrNoDatabaseConn {
t.Fatal(err)
}
- 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 {
+ if err := setToDB(context.Background(), nil, utils.MetaRoutes, newProfileFunc(utils.MetaRoutes)(), true, false); err != utils.ErrNoDatabaseConn {
t.Fatal(err)
}
- 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 {
+ if err := setToDB(context.Background(), nil, utils.MetaDispatcherHosts, newProfileFunc(utils.MetaDispatcherHosts)(), true, false); err != utils.ErrNoDatabaseConn {
t.Fatal(err)
}
- 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 {
+ if err := setToDB(context.Background(), nil, utils.MetaRateProfiles, newProfileFunc(utils.MetaRateProfiles)(), true, false); err != utils.ErrNoDatabaseConn {
t.Fatal(err)
}
- 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 {
+ if err := setToDB(context.Background(), nil, utils.MetaAccounts, newProfileFunc(utils.MetaAccounts)(), true, false); err != utils.ErrNoDatabaseConn {
t.Fatal(err)
}
}
@@ -335,131 +190,131 @@ 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.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, true, false); err != nil {
+ v1 := &engine.AttributeProfile{Tenant: "cgrates.org", ID: "ID"}
+ if err := setToDB(context.Background(), dm, utils.MetaAttributes, v1, true, false); err != nil {
t.Fatal(err)
}
- v1 := &engine.AttributeProfile{Tenant: "cgrates.org", ID: "ID"}
if prf, err := dm.GetAttributeProfile(context.Background(), "cgrates.org", "ID", true, true, utils.NonTransactional); err != nil {
t.Fatal(err)
} else if !reflect.DeepEqual(v1, prf) {
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.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, true, false); err != nil {
+ v2 := &engine.ResourceProfile{Tenant: "cgrates.org", ID: "ID"}
+ if err := setToDB(context.Background(), dm, utils.MetaResources, v2, true, false); err != nil {
t.Fatal(err)
}
- v2 := &engine.ResourceProfile{Tenant: "cgrates.org", ID: "ID"}
if prf, err := dm.GetResourceProfile(context.Background(), "cgrates.org", "ID", true, true, utils.NonTransactional); err != nil {
t.Fatal(err)
} else if !reflect.DeepEqual(v2, prf) {
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.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, true, false); err != nil {
+ v3 := &engine.StatQueueProfile{Tenant: "cgrates.org", ID: "ID"}
+ if err := setToDB(context.Background(), dm, utils.MetaStats, v3, true, false); err != nil {
t.Fatal(err)
}
- v3 := &engine.StatQueueProfile{Tenant: "cgrates.org", ID: "ID"}
if prf, err := dm.GetStatQueueProfile(context.Background(), "cgrates.org", "ID", true, true, utils.NonTransactional); err != nil {
t.Fatal(err)
} else if !reflect.DeepEqual(v3, prf) {
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.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, true, false); err != nil {
+ v4 := &engine.ThresholdProfile{Tenant: "cgrates.org", ID: "ID"}
+ if err := setToDB(context.Background(), dm, utils.MetaThresholds, v4, true, false); err != nil {
t.Fatal(err)
}
- v4 := &engine.ThresholdProfile{Tenant: "cgrates.org", ID: "ID"}
if prf, err := dm.GetThresholdProfile(context.Background(), "cgrates.org", "ID", true, true, utils.NonTransactional); err != nil {
t.Fatal(err)
} else if !reflect.DeepEqual(v4, prf) {
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.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, true, false); err != nil {
+ v5 := &engine.ChargerProfile{Tenant: "cgrates.org", ID: "ID"}
+ if err := setToDB(context.Background(), dm, utils.MetaChargers, v5, true, false); err != nil {
t.Fatal(err)
}
- v5 := &engine.ChargerProfile{Tenant: "cgrates.org", ID: "ID"}
if prf, err := dm.GetChargerProfile(context.Background(), "cgrates.org", "ID", true, true, utils.NonTransactional); err != nil {
t.Fatal(err)
} else if !reflect.DeepEqual(v5, prf) {
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.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, true, false); err != nil {
+ v6 := &engine.DispatcherProfile{Tenant: "cgrates.org", ID: "ID", StrategyParams: make(map[string]interface{})}
+ if err := setToDB(context.Background(), dm, utils.MetaDispatchers, v6, true, false); err != nil {
t.Fatal(err)
}
- v6 := &engine.DispatcherProfile{Tenant: "cgrates.org", ID: "ID", StrategyParams: make(map[string]interface{})}
if prf, err := dm.GetDispatcherProfile(context.Background(), "cgrates.org", "ID", true, true, utils.NonTransactional); err != nil {
t.Fatal(err)
} else if !reflect.DeepEqual(v6, prf) {
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.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, true, false); err != nil {
+ v7 := &engine.ActionProfile{Tenant: "cgrates.org", ID: "ID", Targets: map[string]utils.StringSet{}}
+ if err := setToDB(context.Background(), dm, utils.MetaActionProfiles, v7, true, false); err != nil {
t.Fatal(err)
}
- v7 := &engine.ActionProfile{Tenant: "cgrates.org", ID: "ID", Targets: map[string]utils.StringSet{}}
if prf, err := dm.GetActionProfile(context.Background(), "cgrates.org", "ID", true, true, utils.NonTransactional); err != nil {
t.Fatal(err)
} else if !reflect.DeepEqual(v7, prf) {
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.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", Rules: make([]*engine.FilterRule, 0)}
v8.Compile()
+ if err := setToDB(context.Background(), dm, utils.MetaFilters, v8, true, false); err != nil {
+ t.Fatal(err)
+ }
if prf, err := dm.GetFilter(context.Background(), "cgrates.org", "ID", true, true, utils.NonTransactional); err != nil {
t.Fatal(err)
} else if !reflect.DeepEqual(v8, prf) {
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.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, true, false); err != nil {
+ v9 := &engine.RouteProfile{Tenant: "cgrates.org", ID: "ID"}
+ if err := setToDB(context.Background(), dm, utils.MetaRoutes, v9, true, false); err != nil {
t.Fatal(err)
}
- v9 := &engine.RouteProfile{Tenant: "cgrates.org", ID: "ID"}
if prf, err := dm.GetRouteProfile(context.Background(), "cgrates.org", "ID", true, true, utils.NonTransactional); err != nil {
t.Fatal(err)
} else if !reflect.DeepEqual(v9, prf) {
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.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID", "Address": "127.0.0.1"})}, true, false); err != nil {
+ v10 := &engine.DispatcherHost{Tenant: "cgrates.org", RemoteHost: &config.RemoteHost{ID: "ID", Address: "127.0.0.1", Transport: utils.MetaJSON}}
+ if err := setToDB(context.Background(), dm, utils.MetaDispatcherHosts, v10, 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}}
if prf, err := dm.GetDispatcherHost(context.Background(), "cgrates.org", "ID", true, true, utils.NonTransactional); err != nil {
t.Fatal(err)
} else if !reflect.DeepEqual(v10, prf) {
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.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, true, false); err != nil {
+ v11 := &utils.RateProfile{Tenant: "cgrates.org", ID: "ID", Rates: map[string]*utils.Rate{}, MinCost: utils.NewDecimal(0, 0), MaxCost: utils.NewDecimal(0, 0)}
+ if err := setToDB(context.Background(), dm, utils.MetaRateProfiles, v11, true, false); err != nil {
t.Fatal(err)
}
- v11 := &utils.RateProfile{Tenant: "cgrates.org", ID: "ID", Rates: map[string]*utils.Rate{}, MinCost: utils.NewDecimal(0, 0), MaxCost: utils.NewDecimal(0, 0)}
if prf, err := dm.GetRateProfile(context.Background(), "cgrates.org", "ID", true, true, utils.NonTransactional); err != nil {
t.Fatal(err)
} else if !reflect.DeepEqual(v11, prf) {
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.OrderedNavigableMap{newOrderNavMap(utils.MapStorage{utils.Tenant: "cgrates.org", utils.ID: "ID"})}, true, false); err != nil {
+ v12 := &utils.Account{Tenant: "cgrates.org", ID: "ID", Balances: map[string]*utils.Balance{}, Opts: make(map[string]interface{})}
+ if err := setToDB(context.Background(), dm, utils.MetaAccounts, v12, true, false); err != nil {
t.Fatal(err)
}
- v12 := &utils.Account{Tenant: "cgrates.org", ID: "ID", Balances: map[string]*utils.Balance{}, Opts: make(map[string]interface{})}
if prf, err := dm.GetAccount(context.Background(), "cgrates.org", "ID"); err != nil {
t.Fatal(err)
} else if !reflect.DeepEqual(v12, prf) {
t.Errorf("Expeceted: %v, received: %v", utils.ToJSON(v12), utils.ToJSON(prf))
}
- 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, true); err != nil {
+ v13 := &utils.RateProfile{Tenant: "cgrates.org", ID: "ID", Rates: map[string]*utils.Rate{}, MinCost: utils.NewDecimal(0, 0), MaxCost: utils.NewDecimal(0, 0)}
+ if err := setToDB(context.Background(), dm, utils.MetaRateProfiles, v13, true, true); err != nil {
t.Fatal(err)
}
- v13 := &utils.RateProfile{Tenant: "cgrates.org", ID: "ID", Rates: map[string]*utils.Rate{}, MinCost: utils.NewDecimal(0, 0), MaxCost: utils.NewDecimal(0, 0)}
if prf, err := dm.GetRateProfile(context.Background(), "cgrates.org", "ID", true, true, utils.NonTransactional); err != nil {
t.Fatal(err)
} else if !reflect.DeepEqual(v13, prf) {
@@ -490,11 +345,11 @@ func TestLoaderProcess(t *testing.T) {
}
expErrMsg := `unsupported loader action: <"notSupported">`
- 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 {
+ if err := ld.process(context.Background(), nil, 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.OrderedNavigableMap{}, utils.MetaAttributes, utils.MetaParse, utils.MetaNone, true, false); err != nil {
+ if err := ld.process(context.Background(), nil, utils.MetaAttributes, utils.MetaParse, utils.MetaNone, true, false); err != nil {
t.Error(err)
}
@@ -505,25 +360,25 @@ 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.OrderedNavigableMap{newOrderNavMap(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(), profileTest{utils.Tenant: "cgrates.org", utils.ID: "ID"}, utils.MetaAttributes, utils.MetaDryRun, utils.MetaNone, true, false); err != nil {
t.Error(err)
}
- if expLog, rplyLog := "[INFO] DRY_RUN: AttributeProfile: {\"Tenant\":\"cgrates.org\",\"ID\":\"ID\",\"FilterIDs\":null,\"Attributes\":null,\"Blocker\":false,\"Weight\":0}",
+ if expLog, rplyLog := "[INFO] DRY_RUN: AttributeProfile: {\"Tenant\":\"cgrates.org\",\"ID\":\"ID\"}",
buf.String(); !strings.Contains(rplyLog, expLog) {
t.Errorf("Expected %+q, received %+q", expLog, rplyLog)
}
- 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 {
+ v1 := &engine.AttributeProfile{Tenant: "cgrates.org", ID: "ID"}
+ if err := ld.process(context.Background(), v1, utils.MetaAttributes, utils.MetaStore, utils.MetaNone, true, false); err != nil {
t.Error(err)
}
- v1 := &engine.AttributeProfile{Tenant: "cgrates.org", ID: "ID"}
if prf, err := dm.GetAttributeProfile(context.Background(), "cgrates.org", "ID", true, true, utils.NonTransactional); err != nil {
t.Fatal(err)
} 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.OrderedNavigableMap{newOrderNavMap(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(), v1, 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 {
diff --git a/utils/account.go b/utils/account.go
index 482c09c76..b96b96721 100644
--- a/utils/account.go
+++ b/utils/account.go
@@ -864,3 +864,22 @@ func (bL *Balance) Set(path []string, val interface{}, newBranch bool) (err erro
}
return ErrWrongPath
}
+
+func (ap *Account) Merge(v2 interface{}) {
+ vi := v2.(*Account)
+ if len(vi.Tenant) != 0 {
+ ap.Tenant = vi.Tenant
+ }
+ if len(vi.ID) != 0 {
+ ap.ID = vi.ID
+ }
+ ap.FilterIDs = append(ap.FilterIDs, vi.FilterIDs...)
+ ap.Weights = append(ap.Weights, vi.Weights...)
+ ap.ThresholdIDs = append(ap.ThresholdIDs, vi.ThresholdIDs...)
+ for k, v := range vi.Opts {
+ ap.Opts[k] = v
+ }
+ for k, v := range vi.Balances {
+ ap.Balances[k] = v
+ }
+}
diff --git a/utils/dataconverter_test.go b/utils/dataconverter_test.go
index 4af818b3d..61a324729 100644
--- a/utils/dataconverter_test.go
+++ b/utils/dataconverter_test.go
@@ -1354,7 +1354,7 @@ func TestJoinConverter(t *testing.T) {
if err != nil {
t.Fatal(err)
}
- expVal := "1,2,3,5"
+ expVal := "1;2;3;5"
if i, err := d.Convert("1;2;3;5"); err != nil {
t.Error(err.Error())
} else if expVal != i {
@@ -1383,7 +1383,7 @@ func TestSplitConverter(t *testing.T) {
t.Fatal(err)
}
expVal := []string{"1", "2", "3", "5"}
- if i, err := d.Convert("1,2,3,5"); err != nil {
+ if i, err := d.Convert("1;2;3;5"); err != nil {
t.Error(err.Error())
} else if !reflect.DeepEqual(expVal, i) {
t.Errorf("expecting: %q, received: %q", expVal, i)
diff --git a/utils/librates.go b/utils/librates.go
index 6741e7085..cad4f8710 100644
--- a/utils/librates.go
+++ b/utils/librates.go
@@ -676,3 +676,28 @@ func (rt *Rate) Set(path []string, val interface{}, newBranch bool) (err error)
}
return
}
+
+func (rp *RateProfile) Merge(v2 interface{}) {
+ vi := v2.(*RateProfile)
+ if len(vi.Tenant) != 0 {
+ rp.Tenant = vi.Tenant
+ }
+ if len(vi.ID) != 0 {
+ rp.ID = vi.ID
+ }
+ if len(vi.MaxCostStrategy) != 0 {
+ rp.MaxCostStrategy = vi.MaxCostStrategy
+ }
+ rp.FilterIDs = append(rp.FilterIDs, vi.FilterIDs...)
+ rp.Weights = append(rp.Weights, vi.Weights...)
+ for k, v := range vi.Rates {
+ rp.Rates[k] = v
+ }
+ o := decimal.New(0, 0)
+ if vi.MinCost != nil && vi.MinCost.Cmp(o) != 0 {
+ rp.MinCost = vi.MinCost
+ }
+ if vi.MaxCost != nil && vi.MinCost.Cmp(o) != 0 {
+ rp.MaxCost = vi.MaxCost
+ }
+}