From 1437cfaff3a6bc5232ef087e1d46e29bd4945e21 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 24 Feb 2021 17:29:20 +0200 Subject: [PATCH] Updated SetBalance action --- accounts/accounts.go | 57 ++-- accounts/actsetbalance.go | 248 ++++++++++++++++++ accounts/libaccounts_test.go | 20 +- actions/accounts.go | 109 ++++++++ actions/actions_test.go | 32 +-- actions/export.go | 2 +- actions/libactions.go | 16 +- actions/topup.go | 79 ------ apier/v1/accountprofiles.go | 18 +- apier/v1/accountprofiles_it_test.go | 3 +- apier/v1/accountsv1_it_test.go | 3 +- apier/v1/actions_it_test.go | 54 ++-- apier/v1/api_interfaces.go | 2 + apier/v1/apier.go | 5 +- apier/v1/apier2_it_test.go | 2 +- apier/v1/attributes_it_test.go | 3 +- apier/v1/cost_bench_it_test.go | 2 +- apier/v1/costs_it_test.go | 3 +- apier/v1/dispatcher.go | 21 +- apier/v1/filters_it_test.go | 3 +- apier/v1/full_remote_it_test.go | 4 +- apier/v1/precache_it_test.go | 3 +- apier/v1/tp_it_test.go | 5 +- apier/v1/tpaccountactions_it_test.go | 3 +- apier/v1/tpaccountprofiles_it_test.go | 3 +- apier/v1/tpactionplans_it_test.go | 3 +- apier/v1/tpactionprofiles_it_test.go | 3 +- apier/v1/tpactions_it_test.go | 3 +- apier/v1/tpactiontriggers_it_test.go | 3 +- apier/v1/tpattributes_it_test.go | 3 +- apier/v1/tpchargers_it_test.go | 3 +- apier/v1/tpdestinationrates_it_test.go | 3 +- apier/v1/tpdestinations_it_test.go | 3 +- apier/v1/tpdispatchers_it_test.go | 3 +- apier/v1/tpfilters_it_test.go | 3 +- apier/v1/tprateprofiles_it_test.go | 3 +- apier/v1/tprates_it_test.go | 3 +- apier/v1/tpratingplans_it_test.go | 3 +- apier/v1/tpratingprofiles_it_test.go | 3 +- apier/v1/tpresources_it_test.go | 3 +- apier/v1/tproutes_it_test.go | 3 +- apier/v1/tpsharedgroups_it_test.go | 3 +- apier/v1/tpstats_it_test.go | 3 +- apier/v1/tpthresholds_it_test.go | 3 +- apier/v1/tptimings_it_test.go | 3 +- apier/v1/versions_it_test.go | 5 +- apier/v2/attributes_it_test.go | 3 +- cmd/cgr-engine/cgr-engine.go | 2 +- config/actionscfg.go | 4 +- config/attributescfg.go | 4 +- config/cdrscfg.go | 4 +- config/filterscfg.go | 4 +- config/ralscfg.go | 4 +- config/ralscfg_test.go | 4 +- config/routescfg.go | 2 +- config/routescfg_test.go | 4 +- config/sessionscfg.go | 4 +- config/sessionscfg_test.go | 4 +- data/tariffplans/testit/ActionProfiles.csv | 13 +- .../tariffplans/tutactions/ActionProfiles.csv | 12 +- dispatchers/accounts.go | 40 ++- dispatchers/actions.go | 36 ++- dispatchers/lib_test.go | 16 +- dispatchers/sessions_it_test.go | 4 +- dispatchers/utils.go | 5 - engine/account.go | 2 +- engine/actionprofile.go | 16 +- engine/cdrs.go | 4 +- engine/libtest.go | 12 +- engine/loader_csv_test.go | 12 +- engine/model_helpers.go | 34 ++- engine/model_helpers_test.go | 4 +- engine/units_counter.go | 2 +- engine/z_onstor_it_test.go | 4 +- general_tests/attributes_it_test.go | 5 +- general_tests/cdrs_processevent_it_test.go | 2 +- general_tests/export_it_test.go | 24 +- loaders/loader_test.go | 72 ++--- migrator/actionprofiles_it_test.go | 4 +- migrator/filters.go | 2 +- services/analyzers_it_test.go | 3 + utils/accountprofile.go | 86 +----- utils/consts.go | 19 +- utils/decimal.go | 9 + utils/map_test.go | 2 +- 85 files changed, 783 insertions(+), 469 deletions(-) create mode 100644 accounts/actsetbalance.go create mode 100644 actions/accounts.go delete mode 100644 actions/topup.go diff --git a/accounts/accounts.go b/accounts/accounts.go index e0b6f1252..695d45674 100644 --- a/accounts/accounts.go +++ b/accounts/accounts.go @@ -20,7 +20,6 @@ package accounts import ( "fmt" - "strings" "time" "github.com/cgrates/cgrates/config" @@ -303,20 +302,20 @@ func (aS *AccountS) V1DebitAbstracts(args *utils.ArgsAccountsForEvent, eEc *util return } -// V1TopupBalance performs a topup for a specific account -func (aS *AccountS) V1UpdateBalance(args *utils.ArgsUpdateBalance, rply *string) (err error) { +// V1ActionSetBalance performs a update for a specific balance in account +func (aS *AccountS) V1ActionSetBalance(args *utils.ArgsActSetBalance, rply *string) (err error) { if args.AccountID == utils.EmptyString { return utils.NewErrMandatoryIeMissing(utils.AccountID) } - if len(args.Params) == 0 { - return utils.NewErrMandatoryIeMissing("Params") + if len(args.Diktats) == 0 { + return utils.NewErrMandatoryIeMissing(utils.Diktats) } tnt := args.Tenant if tnt == utils.EmptyString { tnt = aS.cfg.GeneralCfg().DefaultTenant } if _, err = guardian.Guardian.Guard(func() (interface{}, error) { - return nil, aS.updateBalance(tnt, args.AccountID, args.Params, args.Reset) + return nil, actSetAccount(aS.dm, tnt, args.AccountID, args.Diktats, args.Reset) }, aS.cfg.GeneralCfg().LockingTimeout, utils.ConcatenatedKey(utils.CacheAccountProfiles, tnt, args.AccountID)); err != nil { return @@ -326,27 +325,31 @@ func (aS *AccountS) V1UpdateBalance(args *utils.ArgsUpdateBalance, rply *string) return } -func (aS *AccountS) updateBalance(tnt, acntID string, params []*utils.ArgsBalParams, reset bool) (err error) { - var qAcnt *utils.AccountProfile - if qAcnt, err = aS.dm.GetAccountProfile(tnt, acntID); err != nil { +// V1RemoveBalance removes a blance for a specific account +func (aS *AccountS) V1ActionRemoveBalance(args *utils.ArgsActRemoveBalances, rply *string) (err error) { + if args.AccountID == utils.EmptyString { + return utils.NewErrMandatoryIeMissing(utils.AccountID) + } + if len(args.BalanceIDs) == 0 { + return utils.NewErrMandatoryIeMissing(utils.BalanceIDs) + } + tnt := args.Tenant + if tnt == utils.EmptyString { + tnt = aS.cfg.GeneralCfg().DefaultTenant + } + if _, err = guardian.Guardian.Guard(func() (interface{}, error) { + qAcnt, err := aS.dm.GetAccountProfile(tnt, args.AccountID) + if err != nil { + return nil, err + } + for _, balID := range args.BalanceIDs { + delete(qAcnt.Balances, balID) + } + return nil, aS.dm.SetAccountProfile(qAcnt, false) + }, aS.cfg.GeneralCfg().LockingTimeout, + utils.ConcatenatedKey(utils.CacheAccountProfiles, tnt, args.AccountID)); err != nil { return } - for _, param := range params { - path := strings.Split(param.Path, utils.NestingSep) - if len(path) < 3 { - return fmt.Errorf("unsupported path:%s ", param.Path) - } - if path[0] != "~*balance" { - return fmt.Errorf("unsupported field prefix: <%s>", path[0]) - } - switch - if bal, has := qAcnt.Balances[balID]; !has { - qAcnt.Balances[balID] = utils.NewDefaultBalance(balID, value) - } else if reset { - bal.Units = value - } else { - bal.Units.Add(bal.Units.Big, value.Big) - } - } - return aS.dm.SetAccountProfile(qAcnt, false) + *rply = utils.OK + return } diff --git a/accounts/actsetbalance.go b/accounts/actsetbalance.go new file mode 100644 index 000000000..a3c260020 --- /dev/null +++ b/accounts/actsetbalance.go @@ -0,0 +1,248 @@ +/* +Real-time Online/Offline Charging System (OerS) for Telecom & ISP environments +Copyright (C) ITsysCOM GmbH + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +package accounts + +import ( + "fmt" + "strconv" + "strings" + + "github.com/cgrates/cgrates/engine" + "github.com/cgrates/cgrates/utils" +) + +// actSetAccount updates the balances base on the diktas +func actSetAccount(dm *engine.DataManager, tnt, acntID string, diktats []*utils.BalDiktat, reset bool) (err error) { + var qAcnt *utils.AccountProfile + if qAcnt, err = dm.GetAccountProfile(tnt, acntID); err != nil { + return + } + for _, dk := range diktats { + // check if we have a valid path(e.g. *balance.Test.ID) + path := strings.Split(dk.Path, utils.NestingSep) + if len(path) == 0 { + return utils.ErrWrongPath + } + if path[0] != utils.MetaBalance { + return utils.ErrWrongPath + } + if len(path) < 3 { + return utils.ErrWrongPath + } + bal, has := qAcnt.Balances[path[1]] + if !has { + // no balance for that ID create one + bal = &utils.Balance{ID: path[1]} + qAcnt.Balances[path[1]] = bal + } + if err = actSetBalance(bal, path[2:], dk.Value, reset); err != nil { + return + } + } + return dm.SetAccountProfile(qAcnt, false) +} + +// actSetBalance will set the field at path from balance with value +// value is string as the value received from action is string +// the balance must not be nil +func actSetBalance(bal *utils.Balance, path []string, value string, reset bool) (err error) { + // check if we have path past *balance + if len(path) == 0 { + return utils.ErrWrongPath + } + // select what field is update based on the first value from path + // special case for CostIncrements and UnitFactors + // that are converted from string similar to how are loaded from CSVs + switch path[0] { + case utils.ID: + bal.ID = value + case utils.FilterIDs: + bal.FilterIDs = utils.NewStringSet(strings.Split(value, utils.InfieldSep)).AsSlice() + case utils.Weights: + bal.Weights, err = utils.NewDynamicWeightsFromString(value, utils.InfieldSep, utils.ANDSep) + case utils.Type: + bal.Type = value + case utils.Units: + var z *utils.Decimal + if z, err = utils.NewDecimalFromString(value); err != nil { + return + } + // do not overwrite the Units if the action is *add_balance + // this flag makes the difference between the *add_balance and *set_balance actions + if !reset && bal.Units != nil { + bal.Units.Add(bal.Units.Big, z.Big) + } else { + bal.Units = z + } + case utils.UnitFactors: + // just recreate them from strinf + bal.UnitFactors, err = actNewUnitFactorsFromString(value) + case utils.Opts: + err = utils.MapStorage(bal.Opts).Set(path[1:], value) + case utils.CostIncrements: + // just recreate them from strinf + bal.CostIncrements, err = actNewCostIncrementsFromString(value) + case utils.AttributeIDs: + bal.AttributeIDs = strings.Split(value, utils.InfieldSep) + case utils.RateProfileIDs: + bal.RateProfileIDs = utils.NewStringSet(strings.Split(value, utils.InfieldSep)).AsSlice() + default: + // we modify the UnitFactors explicit + // e.g. *balance.TEST.UnitFactors[0].Factor + if strings.HasPrefix(path[0], utils.UnitFactors) { + return actSetUnitFactor(bal.UnitFactors, path, value) + } + + // we modify the CostIncrements explicit + // e.g. *balance.TEST.CostIncrements[0].Increment + if strings.HasPrefix(path[0], utils.CostIncrements) { + return actSetCostIncrement(bal.CostIncrements, path, value) + } + // not a valid path + err = utils.ErrWrongPath + } + return +} + +// actNewUnitFactorsFromString converts a string to a list of UnitFactors +// similar to the how the TP are loaded from CSV +func actNewUnitFactorsFromString(value string) (units []*utils.UnitFactor, err error) { + sls := strings.Split(value, utils.InfieldSep) + if len(sls)%2 != 0 { + return nil, fmt.Errorf("invlid key: <%s> for BalanceUnitFactors", value) + } + units = make([]*utils.UnitFactor, 0, len(sls)/2) + + for j := 0; j < len(sls); j += 2 { + var z *utils.Decimal + if z, err = utils.NewDecimalFromString(sls[j+1]); err != nil { + return + } + units = append(units, &utils.UnitFactor{ + FilterIDs: strings.Split(sls[j], utils.ANDSep), + Factor: z, + }) + } + return +} + +// actNewCostIncrementsFromString converts a string to a list of CostIncrements +// similar to the how the TP are loaded from CSV +func actNewCostIncrementsFromString(value string) (costs []*utils.CostIncrement, err error) { + sls := strings.Split(value, utils.InfieldSep) + if len(sls)%4 != 0 { + return nil, fmt.Errorf("invlid key: <%s> for BalanceCostIncrements", value) + } + costs = make([]*utils.CostIncrement, 0, len(sls)/4) + for j := 0; j < len(sls); j += 4 { + cost := &utils.CostIncrement{ + FilterIDs: strings.Split(sls[j], utils.ANDSep), + } + if incrementStr := sls[j+1]; incrementStr != utils.EmptyString { + if cost.Increment, err = utils.NewDecimalFromString(incrementStr); err != nil { + return + } + } + if fixedFeeStr := sls[j+2]; fixedFeeStr != utils.EmptyString { + if cost.FixedFee, err = utils.NewDecimalFromString(fixedFeeStr); err != nil { + return + } + } + if recurrentFeeStr := sls[j+3]; recurrentFeeStr != utils.EmptyString { + if cost.RecurrentFee, err = utils.NewDecimalFromString(recurrentFeeStr); err != nil { + return + } + } + costs = append(costs, cost) + } + return +} + +// actSetUnitFactor will update the UnitFactors +func actSetUnitFactor(uFs []*utils.UnitFactor, path []string, value string) (err error) { + pathVal := path[0][11:] + lp := len(pathVal) + // check path requierments + // exact 2 elements + // and the first element have an index between brackets + if lp != 2 || + pathVal[0] != '[' || + pathVal[lp-1] != ']' { + return utils.ErrWrongPath + } + pathVal = pathVal[1 : lp-1] + var idx int + // convert the index from string to int + if idx, err = strconv.Atoi(pathVal); err != nil { + return + } + if len(uFs) == idx { // special case add a new unitFactor + uFs = append(uFs, &utils.UnitFactor{}) + } else if len(uFs) < idx { // make sure we are in slice range + return utils.ErrWrongPath + } + + switch path[1] { + case utils.FilterIDs: + uFs[idx].FilterIDs = utils.NewStringSet(strings.Split(value, utils.InfieldSep)).AsSlice() + case utils.Factor: + uFs[idx].Factor, err = utils.NewDecimalFromString(value) + default: + err = utils.ErrWrongPath + } + return +} + +func actSetCostIncrement(cIs []*utils.CostIncrement, path []string, value string) (err error) { + pathVal := path[0][14:] + lp := len(pathVal) + // check path requierments + // exact 2 elements + // and the first element have an index between brackets + if lp != 2 || + pathVal[0] != '[' || + pathVal[lp-1] != ']' { + return utils.ErrWrongPath + } + pathVal = pathVal[1 : lp-1] + var idx int + // convert the index from string to int + if idx, err = strconv.Atoi(pathVal); err != nil { + return + } + if len(cIs) == idx { // special case add a new CostIncrement + cIs = append(cIs, &utils.CostIncrement{}) + } else if len(cIs) < idx { // make sure we are in slice range + return utils.ErrWrongPath + } + + switch path[0] { + case utils.FilterIDs: + cIs[idx].FilterIDs = utils.NewStringSet(strings.Split(value, utils.InfieldSep)).AsSlice() + case utils.Increment: + cIs[idx].Increment, err = utils.NewDecimalFromString(value) + case utils.FixedFee: + cIs[idx].FixedFee, err = utils.NewDecimalFromString(value) + case utils.RecurrentFee: + cIs[idx].RecurrentFee, err = utils.NewDecimalFromString(value) + default: + err = utils.ErrWrongPath + } + return +} diff --git a/accounts/libaccounts_test.go b/accounts/libaccounts_test.go index a1b72497d..36a930878 100644 --- a/accounts/libaccounts_test.go +++ b/accounts/libaccounts_test.go @@ -381,12 +381,12 @@ func TestRestoreAccount(t *testing.T) { //coverage purpose Tenant: "cgrates.org", ID: "1001", Balances: map[string]*utils.Balance{ - "CB1": &utils.Balance{ + "CB1": { ID: "CB1", Type: utils.MetaConcrete, Units: utils.NewDecimal(500, 0), }, - "CB2": &utils.Balance{ + "CB2": { ID: "CB2", Type: utils.MetaConcrete, Units: utils.NewDecimal(300, 0), @@ -397,11 +397,11 @@ func TestRestoreAccount(t *testing.T) { //coverage purpose t.Error(err) } restoreAccounts(dm, []*utils.AccountProfileWithWeight{ - &utils.AccountProfileWithWeight{acntPrf, 0, utils.EmptyString}, + {acntPrf, 0, utils.EmptyString}, }, []utils.AccountBalancesBackup{ map[string]*decimal.Big{"CB2": decimal.New(100, 0)}, }) - if rcv, err := dm.GetAccountProfile("cgrates.org", "1001", false, false, utils.EmptyString); err != nil { + if rcv, err := dm.GetAccountProfile("cgrates.org", "1001"); err != nil { t.Error(err) } else if len(rcv.Balances) != 2 { t.Errorf("Unexpected number of balances received") @@ -422,12 +422,12 @@ func TestRestoreAccount2(t *testing.T) { //coverage purpose Tenant: "cgrates.org", ID: "1001", Balances: map[string]*utils.Balance{ - "CB1": &utils.Balance{ + "CB1": { ID: "CB1", Type: utils.MetaConcrete, Units: utils.NewDecimal(500, 0), // 500 Units }, - "CB2": &utils.Balance{ + "CB2": { ID: "CB2", Type: utils.MetaConcrete, Units: utils.NewDecimal(100, 0), // 500 Units @@ -435,7 +435,7 @@ func TestRestoreAccount2(t *testing.T) { //coverage purpose }, } restoreAccounts(dm, []*utils.AccountProfileWithWeight{ - &utils.AccountProfileWithWeight{acntPrf, 0, utils.EmptyString}, + {acntPrf, 0, utils.EmptyString}, }, []utils.AccountBalancesBackup{ map[string]*decimal.Big{"CB1": decimal.New(100, 0)}, }) @@ -451,12 +451,12 @@ func TestRestoreAccount3(t *testing.T) { //coverage purpose Tenant: "cgrates.org", ID: "1001", Balances: map[string]*utils.Balance{ - "CB1": &utils.Balance{ + "CB1": { ID: "CB1", Type: utils.MetaConcrete, Units: utils.NewDecimal(500, 0), // 500 Units }, - "CB2": &utils.Balance{ + "CB2": { ID: "CB2", Type: utils.MetaConcrete, Units: utils.NewDecimal(100, 0), // 500 Units @@ -467,7 +467,7 @@ func TestRestoreAccount3(t *testing.T) { //coverage purpose t.Error(err) } restoreAccounts(dm, []*utils.AccountProfileWithWeight{ - &utils.AccountProfileWithWeight{acntPrf, 0, utils.EmptyString}, + {acntPrf, 0, utils.EmptyString}, }, []utils.AccountBalancesBackup{ nil, }) diff --git a/actions/accounts.go b/actions/accounts.go new file mode 100644 index 000000000..8a8a626b4 --- /dev/null +++ b/actions/accounts.go @@ -0,0 +1,109 @@ +/* +Real-time Online/Offline Charging System (OerS) for Telecom & ISP environments +Copyright (C) ITsysCOM GmbH + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +package actions + +import ( + "context" + "fmt" + + "github.com/cgrates/cgrates/config" + "github.com/cgrates/cgrates/engine" + "github.com/cgrates/cgrates/utils" +) + +// actSetBalance will update the account +type actSetBalance struct { + config *config.CGRConfig + connMgr *engine.ConnManager + aCfg *engine.APAction + tnt string + reset bool +} + +func (aL *actSetBalance) id() string { + return aL.aCfg.ID +} + +func (aL *actSetBalance) cfg() *engine.APAction { + return aL.aCfg +} + +// execute implements actioner interface +func (aL *actSetBalance) execute(ctx context.Context, data utils.MapStorage, trgID string) (err error) { + if len(aL.config.ActionSCfg().AccountSConns) == 0 { + return fmt.Errorf("no connection with AccountS") + } + + args := &utils.ArgsActSetBalance{ + Tenant: aL.tnt, + AccountID: trgID, + Reset: aL.reset, + Diktats: make([]*utils.BalDiktat, len(aL.cfg().Diktats)), + Opts: aL.cfg().Opts, + } + for i, actD := range aL.cfg().Diktats { + var val string + if val, err = actD.Value.ParseDataProvider(data); err != nil { + return + } + args.Diktats[i] = &utils.BalDiktat{ + Path: actD.Path, + Value: val, + } + } + var rply string + return aL.connMgr.Call(aL.config.ActionSCfg().AccountSConns, nil, + utils.AccountSv1UpdateBalance, args, &rply) +} + +// actRemBalance will remove multiple balances from account +type actRemBalance struct { + config *config.CGRConfig + connMgr *engine.ConnManager + aCfg *engine.APAction + tnt string +} + +func (aL *actRemBalance) id() string { + return aL.aCfg.ID +} + +func (aL *actRemBalance) cfg() *engine.APAction { + return aL.aCfg +} + +// execute implements actioner interface +func (aL *actRemBalance) execute(ctx context.Context, data utils.MapStorage, trgID string) (err error) { + if len(aL.config.ActionSCfg().AccountSConns) == 0 { + return fmt.Errorf("no connection with AccountS") + } + + args := &utils.ArgsActRemoveBalances{ + Tenant: aL.tnt, + AccountID: trgID, + BalanceIDs: make([]string, len(aL.cfg().Diktats)), + Opts: aL.cfg().Opts, + } + for i, actD := range aL.cfg().Diktats { + args.BalanceIDs[i] = actD.Path + } + var rply string + return aL.connMgr.Call(aL.config.ActionSCfg().AccountSConns, nil, + utils.AccountSv1UpdateBalance, args, &rply) +} diff --git a/actions/actions_test.go b/actions/actions_test.go index 953827884..ce5346da5 100644 --- a/actions/actions_test.go +++ b/actions/actions_test.go @@ -62,7 +62,7 @@ func TestMatchingActionProfilesForEvent(t *testing.T) { ID: "TOPUP", FilterIDs: []string{}, Type: "*topup", - ActionDiktats: []*engine.ActionDiktat{{ + Diktats: []*engine.APDiktat{{ Path: "~*balance.TestBalance.Value", Value: config.NewRSRParsersMustCompile("10", defaultCfg.GeneralCfg().RSRSep), }}, @@ -171,7 +171,7 @@ func TestScheduledActions(t *testing.T) { ID: "TOPUP", FilterIDs: []string{}, Type: utils.MetaLog, - ActionDiktats: []*engine.ActionDiktat{{ + Diktats: []*engine.APDiktat{{ Path: "~*balance.TestBalance.Value", Value: config.NewRSRParsersMustCompile("10", defaultCfg.GeneralCfg().RSRSep), }}, @@ -233,7 +233,7 @@ func TestScheduleAction(t *testing.T) { ID: "TOPUP", FilterIDs: []string{}, Type: utils.MetaLog, - ActionDiktats: []*engine.ActionDiktat{{ + Diktats: []*engine.APDiktat{{ Path: "~*balance.TestBalance.Value", Value: config.NewRSRParsersMustCompile("10", defaultCfg.GeneralCfg().RSRSep), }}, @@ -359,7 +359,7 @@ func TestV1ScheduleActions(t *testing.T) { ID: "TOPUP", FilterIDs: []string{}, Type: utils.MetaLog, - ActionDiktats: []*engine.ActionDiktat{{ + Diktats: []*engine.APDiktat{{ Path: "~*balance.TestBalance.Value", Value: config.NewRSRParsersMustCompile("10", defaultCfg.GeneralCfg().RSRSep), }}, @@ -417,7 +417,7 @@ func TestV1ExecuteActions(t *testing.T) { ID: "TOPUP", FilterIDs: []string{}, Type: utils.MetaLog, - ActionDiktats: []*engine.ActionDiktat{{ + Diktats: []*engine.APDiktat{{ Path: "~*balance.TestBalance.Value", Value: config.NewRSRParsersMustCompile("10", defaultCfg.GeneralCfg().RSRSep), }}, @@ -484,7 +484,7 @@ func (dbM *dataDBMockError) GetActionProfileDrv(string, string) (*engine.ActionP ID: "TOPUP", FilterIDs: []string{}, Type: utils.MetaLog, - ActionDiktats: []*engine.ActionDiktat{{ + Diktats: []*engine.APDiktat{{ Path: "~*balance.TestBalance.Value", Value: config.NewRSRParsersMustCompile("10", ","), }}, @@ -862,9 +862,9 @@ func TestExportActionResetThresholdStaticTenantID(t *testing.T) { utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds): internalChann, }) apA := &engine.APAction{ - ID: "ACT_RESET_TH", - Type: utils.MetaResetThreshold, - ActionDiktats: []*engine.ActionDiktat{{}}, + ID: "ACT_RESET_TH", + Type: utils.MetaResetThreshold, + Diktats: []*engine.APDiktat{{}}, } exportAction := &actResetThreshold{ tnt: "cgrates.org", @@ -909,9 +909,9 @@ func TestExportActionResetThresholdStaticID(t *testing.T) { utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds): internalChann, }) apA := &engine.APAction{ - ID: "ACT_RESET_TH", - Type: utils.MetaResetThreshold, - ActionDiktats: []*engine.ActionDiktat{{}}, + ID: "ACT_RESET_TH", + Type: utils.MetaResetThreshold, + Diktats: []*engine.APDiktat{{}}, } exportAction := &actResetThreshold{ tnt: "cgrates.org", @@ -956,9 +956,9 @@ func TestExportActionResetStatStaticTenantID(t *testing.T) { utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats): internalChann, }) apA := &engine.APAction{ - ID: "ACT_RESET_ST", - Type: utils.MetaResetStatQueue, - ActionDiktats: []*engine.ActionDiktat{{}}, + ID: "ACT_RESET_ST", + Type: utils.MetaResetStatQueue, + Diktats: []*engine.APDiktat{{}}, } exportAction := &actResetStat{ tnt: "cgrates.org", @@ -1005,7 +1005,7 @@ func TestExportActionResetStatStaticID(t *testing.T) { apA := &engine.APAction{ ID: "ACT_RESET_ST", Type: utils.MetaResetStatQueue, - ActionDiktats: []*engine.ActionDiktat{{ + Diktats: []*engine.APDiktat{{ Value: config.NewRSRParsersMustCompile("ST1", utils.InfieldSep), }}, } diff --git a/actions/export.go b/actions/export.go index 3b81fb9fa..9a2083028 100644 --- a/actions/export.go +++ b/actions/export.go @@ -51,7 +51,7 @@ func (aL *actHTTPPost) execute(_ context.Context, data utils.MapStorage, _ strin return } var partExec bool - for _, actD := range aL.cfg().ActionDiktats { + for _, actD := range aL.cfg().Diktats { var pstr *engine.HTTPPoster if pstr, err = engine.NewHTTPPoster(config.CgrConfig().GeneralCfg().ReplyTimeout, actD.Path, utils.ContentJSON, aL.config.GeneralCfg().PosterAttempts); err != nil { diff --git a/actions/libactions.go b/actions/libactions.go index 8ff9c569a..4b497cccb 100644 --- a/actions/libactions.go +++ b/actions/libactions.go @@ -31,7 +31,11 @@ import ( // actionTarget returns the target attached to an action func actionTarget(act string) string { switch act { - case utils.MetaTopUp, utils.MetaTopUpReset: + case utils.MetaResetStatQueue: + return utils.MetaStats + case utils.MetaResetThreshold: + return utils.MetaThresholds + case utils.MetaAddBalance, utils.MetaSetBalance, utils.MetaRemBalance: return utils.MetaAccounts default: return utils.MetaNone @@ -122,10 +126,12 @@ func newActioner(cfg *config.CGRConfig, fltrS *engine.FilterS, dm *engine.DataMa return &actResetStat{tnt, cfg, connMgr, aCfg}, nil case utils.MetaResetThreshold: return &actResetThreshold{tnt, cfg, connMgr, aCfg}, nil - case utils.MetaTopUp: - return &actTopup{cfg, connMgr, aCfg, tnt, false}, nil - case utils.MetaTopUpReset: - return &actTopup{cfg, connMgr, aCfg, tnt, true}, nil + case utils.MetaAddBalance: + return &actSetBalance{cfg, connMgr, aCfg, tnt, false}, nil + case utils.MetaSetBalance: + return &actSetBalance{cfg, connMgr, aCfg, tnt, true}, nil + case utils.MetaRemBalance: + return &actRemBalance{cfg, connMgr, aCfg, tnt}, nil default: return nil, fmt.Errorf("unsupported action type: <%s>", aCfg.Type) diff --git a/actions/topup.go b/actions/topup.go deleted file mode 100644 index 26fae7c23..000000000 --- a/actions/topup.go +++ /dev/null @@ -1,79 +0,0 @@ -/* -Real-time Online/Offline Charging System (OerS) for Telecom & ISP environments -Copyright (C) ITsysCOM GmbH - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see -*/ - -package actions - -import ( - "context" - - "github.com/cgrates/cgrates/config" - "github.com/cgrates/cgrates/engine" - "github.com/cgrates/cgrates/utils" -) - -// actTopup will log data to CGRateS logger -type actTopup struct { - config *config.CGRConfig - connMgr *engine.ConnManager - aCfg *engine.APAction - tnt string - reset bool -} - -func (aL *actTopup) id() string { - return aL.aCfg.ID -} - -func (aL *actTopup) cfg() *engine.APAction { - return aL.aCfg -} - -// execute implements actioner interface -func (aL *actTopup) execute(ctx context.Context, data utils.MapStorage, trgID string) (err error) { - return - /* - if len(aL.config.ActionSCfg().AccountSConns) == 0 { - return fmt.Errorf("no connection with AccountS") - } - var valStr string - if valStr, err = aL.cfg().Value.ParseDataProviderWithInterfaces(data); err != nil { - return - } - var val float64 - if val, err = utils.IfaceAsFloat64(valStr); err != nil { - return - } - - // *accounts.1001.Balance.MonetaryBalance - path := strings.SplitN(aL.cfg().Path, utils.ConcatenatedKeySep, 2) - if len(path) != 2 { - err = fmt.Errorf("Unsupported path: %s", aL.cfg().Path) - return - } - args := &utils.ArgsModifyBalance{ - Tenant: aL.tnt, - AccountID: trgID, - BalanceID: aL.cfg().Path, - Value: val, - Reset: aL.reset, - } - var rply string - return aL.connMgr.Call(aL.config.ActionSCfg().AccountSConns, nil, - utils.AccountSv1TopupBalance, args, &rply) - */ -} diff --git a/apier/v1/accountprofiles.go b/apier/v1/accountprofiles.go index 30543eca2..f202195ed 100644 --- a/apier/v1/accountprofiles.go +++ b/apier/v1/accountprofiles.go @@ -35,7 +35,7 @@ func (apierSv1 *APIerSv1) GetAccountProfile(arg *utils.TenantIDWithOpts, reply * if tnt == utils.EmptyString { tnt = apierSv1.Config.GeneralCfg().DefaultTenant } - ap, err := apierSv1.DataManager.GetAccountProfile(tnt, arg.ID, true, true, utils.NonTransactional) + ap, err := apierSv1.DataManager.GetAccountProfile(tnt, arg.ID) if err != nil { if err.Error() != utils.ErrNotFound.Error() { err = utils.NewErrServerError(err) @@ -158,7 +158,7 @@ func (aSv1 *AccountSv1) Ping(ign *utils.CGREvent, reply *string) error { return nil } -// AccountProfileForEvent returns the matching AccountProfile for Event +// AccountProfilesForEvent returns the matching AccountProfile for Event func (aSv1 *AccountSv1) AccountProfilesForEvent(args *utils.ArgsAccountsForEvent, aps *[]*utils.AccountProfile) (err error) { return aSv1.aS.V1AccountProfilesForEvent(args, aps) @@ -176,8 +176,14 @@ func (aSv1 *AccountSv1) DebitAbstracts(args *utils.ArgsAccountsForEvent, return aSv1.aS.V1DebitAbstracts(args, eEc) } -// TopupBalance performs topup for the provided balance -func (aSv1 *AccountSv1) TopupBalance(args *utils.ArgsUpdateBalance, - rply *string) (err error) { - return aSv1.aS.V1TopupBalance(args, rply) +// ActionSetBalance performs a set balance action +func (aSv1 *AccountSv1) ActionSetBalance(args *utils.ArgsActSetBalance, + eEc *string) (err error) { + return aSv1.aS.V1ActionSetBalance(args, eEc) +} + +// ActionRemoveBalance removes a blance from an account +func (aSv1 *AccountSv1) ActionRemoveBalance(args *utils.ArgsActRemoveBalances, + eEc *string) (err error) { + return aSv1.aS.V1ActionRemoveBalance(args, eEc) } diff --git a/apier/v1/accountprofiles_it_test.go b/apier/v1/accountprofiles_it_test.go index 1232243f2..afc52f285 100644 --- a/apier/v1/accountprofiles_it_test.go +++ b/apier/v1/accountprofiles_it_test.go @@ -37,7 +37,6 @@ var ( accPrfCfgPath string accPrfCfg *config.CGRConfig accSRPC *rpc.Client - accPrfDataDir = "/usr/share/cgrates" apiAccPrf *APIAccountProfileWithCache accPrf *utils.AccountProfile accPrfConfigDIR string //run tests for specific configuration @@ -81,7 +80,7 @@ func TestAccountSIT(t *testing.T) { func testAccountSInitCfg(t *testing.T) { var err error - accPrfCfgPath = path.Join(accPrfDataDir, "conf", "samples", accPrfConfigDIR) + accPrfCfgPath = path.Join(*dataDir, "conf", "samples", accPrfConfigDIR) accPrfCfg, err = config.NewCGRConfigFromPath(accPrfCfgPath) if err != nil { t.Error(err) diff --git a/apier/v1/accountsv1_it_test.go b/apier/v1/accountsv1_it_test.go index 1ad3ecd7a..4ba9cab42 100644 --- a/apier/v1/accountsv1_it_test.go +++ b/apier/v1/accountsv1_it_test.go @@ -38,7 +38,6 @@ var ( acntSCfgPath string acntSCfg *config.CGRConfig acntSRPC *rpc.Client - acntSDataDir = "/usr/share/cgrates" ) //Test start here @@ -80,7 +79,7 @@ func TestAccountSv1IT(t *testing.T) { func testAccountSv1InitCfg(t *testing.T) { var err error - acntSCfgPath = path.Join(acntSDataDir, "conf", "samples", acntSConfigDIR) + acntSCfgPath = path.Join(*dataDir, "conf", "samples", acntSConfigDIR) acntSCfg, err = config.NewCGRConfigFromPath(acntSCfgPath) if err != nil { t.Error(err) diff --git a/apier/v1/actions_it_test.go b/apier/v1/actions_it_test.go index 2360d2b8f..2f2334e8a 100644 --- a/apier/v1/actions_it_test.go +++ b/apier/v1/actions_it_test.go @@ -36,7 +36,6 @@ var ( actPrfCfgPath string actPrfCfg *config.CGRConfig actSRPC *rpc.Client - actPrfDataDir = "/usr/share/cgrates" actPrf *ActionProfileWithCache actPrfConfigDIR string //run tests for specific configuration @@ -79,7 +78,7 @@ func TestActionSIT(t *testing.T) { func testActionSInitCfg(t *testing.T) { var err error - actPrfCfgPath = path.Join(actPrfDataDir, "conf", "samples", actPrfConfigDIR) + actPrfCfgPath = path.Join(*dataDir, "conf", "samples", actPrfConfigDIR) actPrfCfg, err = config.NewCGRConfigFromPath(actPrfCfgPath) if err != nil { t.Error(err) @@ -132,49 +131,64 @@ func testActionSGetActionProfile(t *testing.T) { Weight: 10, Schedule: utils.MetaASAP, Targets: map[string]utils.StringSet{ - utils.MetaAccounts: utils.StringSet{"1001": {}, "1002": {}}, + utils.MetaAccounts: {"1001": {}, "1002": {}}, }, Actions: []*engine.APAction{ { ID: "TOPUP", - Type: "*topup", - ActionDiktats: []*engine.ActionDiktat{{ - Path: "~*balance.TestBalance.Value", + Type: "*add_balance", + Diktats: []*engine.APDiktat{{ + Path: "*balance.TestBalance.Units", Value: config.NewRSRParsersMustCompile("10", actPrfCfg.GeneralCfg().RSRSep), }}, }, { ID: "SET_BALANCE_TEST_DATA", Type: "*set_balance", - ActionDiktats: []*engine.ActionDiktat{{ - Path: "~*balance.TestDataBalance.Type", + Diktats: []*engine.APDiktat{{ + Path: "*balance.TestDataBalance.Type", Value: config.NewRSRParsersMustCompile("*data", actPrfCfg.GeneralCfg().RSRSep), }}, }, { ID: "TOPUP_TEST_DATA", - Type: "*topup", - ActionDiktats: []*engine.ActionDiktat{{ - Path: "~*balance.TestDataBalance.Value", + Type: "*add_balance", + Diktats: []*engine.APDiktat{{ + Path: "*balance.TestDataBalance.Units", Value: config.NewRSRParsersMustCompile("1024", actPrfCfg.GeneralCfg().RSRSep), }}, }, { ID: "SET_BALANCE_TEST_VOICE", Type: "*set_balance", - ActionDiktats: []*engine.ActionDiktat{{ - Path: "~*balance.TestVoiceBalance.Type", + Diktats: []*engine.APDiktat{{ + Path: "*balance.TestVoiceBalance.Type", Value: config.NewRSRParsersMustCompile("*voice", actPrfCfg.GeneralCfg().RSRSep), }}, }, { ID: "TOPUP_TEST_VOICE", - Type: "*topup", - ActionDiktats: []*engine.ActionDiktat{{ - Path: "~*balance.TestVoiceBalance.Value", + Type: "*add_balance", + Diktats: []*engine.APDiktat{{ + Path: "*balance.TestVoiceBalance.Units", Value: config.NewRSRParsersMustCompile("15m15s", actPrfCfg.GeneralCfg().RSRSep), }}, }, + { + ID: "SET_BALANCE_TEST_FILTERS", + Type: "*set_balance", + Diktats: []*engine.APDiktat{{ + Path: "*balance.TestVoiceBalance.Filters", + Value: config.NewRSRParsersMustCompile("*string:~*req.CustomField:500", actPrfCfg.GeneralCfg().RSRSep), + }}, + }, + { + ID: "TOPUP_REM_VOICE", + Type: "*rem_balance", + Diktats: []*engine.APDiktat{{ + Path: "TestVoiceBalance2", + }}, + }, }, } if *encoding == utils.MetaGOB { @@ -189,7 +203,7 @@ func testActionSGetActionProfile(t *testing.T) { t.Fatal(err) } else { for _, act := range reply.Actions { // the path variable from RSRParsers is with lower letter and need to be compiled manually in tests to pass reflect.DeepEqual - for _, actD := range act.ActionDiktats { + for _, actD := range act.Diktats { actD.Value.Compile() } } @@ -226,7 +240,7 @@ func testActionSSettActionProfile(t *testing.T) { TTL: 0, Type: "", Opts: nil, - ActionDiktats: []*engine.ActionDiktat{{ + Diktats: []*engine.APDiktat{{ Path: "", Value: nil, }}, @@ -238,7 +252,7 @@ func testActionSSettActionProfile(t *testing.T) { TTL: 0, Type: "", Opts: nil, - ActionDiktats: []*engine.ActionDiktat{{ + Diktats: []*engine.APDiktat{{ Path: "", Value: nil, }}, @@ -267,7 +281,6 @@ func testActionSSettActionProfile(t *testing.T) { } else if !reflect.DeepEqual(actPrf.ActionProfile, reply2) { t.Errorf("Expecting : %+v, received: %+v", actPrf.ActionProfile, reply2) } - } func testActionSGetActionProfileIDs(t *testing.T) { @@ -303,7 +316,6 @@ func testActionSGetActionProfileIDsCount(t *testing.T) { } else if reply != 1 { t.Errorf("Expecting: 1, received: %+v", reply) } - } func testActionSUpdateActionProfile(t *testing.T) { diff --git a/apier/v1/api_interfaces.go b/apier/v1/api_interfaces.go index 38804aba8..769eb0807 100644 --- a/apier/v1/api_interfaces.go +++ b/apier/v1/api_interfaces.go @@ -291,4 +291,6 @@ type AccountSv1Interface interface { AccountProfilesForEvent(args *utils.ArgsAccountsForEvent, aps *[]*utils.AccountProfile) error MaxAbstracts(args *utils.ArgsAccountsForEvent, eEc *utils.ExtEventCharges) error DebitAbstracts(args *utils.ArgsAccountsForEvent, eEc *utils.ExtEventCharges) error + ActionSetBalance(args *utils.ArgsActSetBalance, eEc *string) (err error) + ActionRemoveBalance(args *utils.ArgsActRemoveBalances, eEc *string) (err error) } diff --git a/apier/v1/apier.go b/apier/v1/apier.go index bf35dfd1f..0fd981cd7 100644 --- a/apier/v1/apier.go +++ b/apier/v1/apier.go @@ -1771,7 +1771,7 @@ func (apierSv1 *APIerSv1) ExportToFolder(arg *utils.ArgExportToFolder, reply *st } } csvWriter.Flush() - case utils.MetaStatS: + case utils.MetaStats: prfx := utils.StatQueueProfilePrefix keys, err := apierSv1.DataManager.DataDB().GetKeysForPrefix(prfx) if err != nil { @@ -1983,8 +1983,7 @@ func (apierSv1 *APIerSv1) ExportToFolder(arg *utils.ArgExportToFolder, reply *st } for _, key := range keys { tntID := strings.SplitN(key[len(prfx):], utils.InInFieldSep, 2) - accPrf, err := apierSv1.DataManager.GetAccountProfile(tntID[0], tntID[1], - true, false, utils.NonTransactional) + accPrf, err := apierSv1.DataManager.GetAccountProfile(tntID[0], tntID[1]) if err != nil { return err } diff --git a/apier/v1/apier2_it_test.go b/apier/v1/apier2_it_test.go index f2c68bc66..8d13546e5 100644 --- a/apier/v1/apier2_it_test.go +++ b/apier/v1/apier2_it_test.go @@ -90,7 +90,7 @@ func TestApierIT2(t *testing.T) { func testAPIerInitCfg(t *testing.T) { var err error - apierCfgPath = path.Join(costDataDir, "conf", "samples", APIerSv2ConfigDIR) + apierCfgPath = path.Join(*dataDir, "conf", "samples", APIerSv2ConfigDIR) apierCfg, err = config.NewCGRConfigFromPath(apierCfgPath) if err != nil { t.Error(err) diff --git a/apier/v1/attributes_it_test.go b/apier/v1/attributes_it_test.go index 64ac2b51a..d40eafb9d 100644 --- a/apier/v1/attributes_it_test.go +++ b/apier/v1/attributes_it_test.go @@ -37,7 +37,6 @@ var ( alsPrfCfgPath string alsPrfCfg *config.CGRConfig attrSRPC *rpc.Client - alsPrfDataDir = "/usr/share/cgrates" alsPrf *AttributeWithCache alsPrfConfigDIR string //run tests for specific configuration @@ -115,7 +114,7 @@ func TestAttributeSIT(t *testing.T) { func testAttributeSInitCfg(t *testing.T) { var err error - alsPrfCfgPath = path.Join(alsPrfDataDir, "conf", "samples", alsPrfConfigDIR) + alsPrfCfgPath = path.Join(*dataDir, "conf", "samples", alsPrfConfigDIR) alsPrfCfg, err = config.NewCGRConfigFromPath(alsPrfCfgPath) if err != nil { t.Error(err) diff --git a/apier/v1/cost_bench_it_test.go b/apier/v1/cost_bench_it_test.go index c986cf6d6..d629a9a15 100644 --- a/apier/v1/cost_bench_it_test.go +++ b/apier/v1/cost_bench_it_test.go @@ -40,7 +40,7 @@ var ( func testCostBenchInitCfg(b *testing.B) { var err error - costBenchCfgPath = path.Join(costDataDir, "conf", "samples", costBenchConfigDIR) + costBenchCfgPath = path.Join(*dataDir, "conf", "samples", costBenchConfigDIR) costBenchCfg, err = config.NewCGRConfigFromPath(costBenchCfgPath) if err != nil { b.Error(err) diff --git a/apier/v1/costs_it_test.go b/apier/v1/costs_it_test.go index 5e57fbf45..420bf793c 100644 --- a/apier/v1/costs_it_test.go +++ b/apier/v1/costs_it_test.go @@ -36,7 +36,6 @@ var ( costCfg *config.CGRConfig costRPC *rpc.Client costConfigDIR string //run tests for specific configuration - costDataDir = "/usr/share/cgrates" sTestsCost = []func(t *testing.T){ testCostInitCfg, @@ -71,7 +70,7 @@ func TestCostIT(t *testing.T) { func testCostInitCfg(t *testing.T) { var err error - costCfgPath = path.Join(costDataDir, "conf", "samples", costConfigDIR) + costCfgPath = path.Join(*dataDir, "conf", "samples", costConfigDIR) costCfg, err = config.NewCGRConfigFromPath(costCfgPath) if err != nil { t.Error(err) diff --git a/apier/v1/dispatcher.go b/apier/v1/dispatcher.go index ea628e8a5..668a1c447 100755 --- a/apier/v1/dispatcher.go +++ b/apier/v1/dispatcher.go @@ -757,6 +757,11 @@ func (dSv1 DispatcherSv1) Apier(args *utils.MethodParameters, reply *interface{} } */ +func (rS *DispatcherSv1) Ping(ign *utils.CGREvent, reply *string) error { + *reply = utils.Pong + return nil +} + func NewDispatcherSCDRsV1(dps *dispatchers.DispatcherService) *DispatcherSCDRsV1 { return &DispatcherSCDRsV1{dS: dps} } @@ -1352,6 +1357,13 @@ func (dR *DispatcherActionSv1) Ping(args *utils.CGREvent, reply *string) error { return dR.dR.ActionSv1Ping(args, reply) } +func (dR *DispatcherActionSv1) ScheduleActions(args *utils.ArgActionSv1ScheduleActions, rpl *string) error { + return dR.dR.ActionSv1ScheduleActions(args, rpl) +} +func (dR *DispatcherActionSv1) ExecuteActions(args *utils.ArgActionSv1ScheduleActions, rpl *string) error { + return dR.dR.ActionSv1ExecuteActions(args, rpl) +} + func NewDispatcherAccountSv1(dps *dispatchers.DispatcherService) *DispatcherAccountSv1 { return &DispatcherAccountSv1{dR: dps} } @@ -1378,7 +1390,10 @@ func (dR *DispatcherAccountSv1) DebitAbstracts(args *utils.ArgsAccountsForEvent, return dR.dR.DebitAbstracts(args, eEc) } -func (rS *DispatcherSv1) Ping(ign *utils.CGREvent, reply *string) error { - *reply = utils.Pong - return nil +func (dR *DispatcherAccountSv1) ActionSetBalance(args *utils.ArgsActSetBalance, eEc *string) (err error) { + return dR.dR.AccountSv1ActionSetBalance(args, eEc) +} + +func (dR *DispatcherAccountSv1) ActionRemoveBalance(args *utils.ArgsActRemoveBalances, eEc *string) (err error) { + return dR.dR.AccountSv1ActionRemoveBalance(args, eEc) } diff --git a/apier/v1/filters_it_test.go b/apier/v1/filters_it_test.go index 92427e527..31059015c 100644 --- a/apier/v1/filters_it_test.go +++ b/apier/v1/filters_it_test.go @@ -36,7 +36,6 @@ var ( filterCfgPath string filterCfg *config.CGRConfig filterRPC *rpc.Client - filterDataDir = "/usr/share/cgrates" filter *FilterWithCache filterConfigDIR string //run tests for specific configuration @@ -80,7 +79,7 @@ func TestFilterIT(t *testing.T) { func testFilterInitCfg(t *testing.T) { var err error - filterCfgPath = path.Join(filterDataDir, "conf", "samples", filterConfigDIR) + filterCfgPath = path.Join(*dataDir, "conf", "samples", filterConfigDIR) filterCfg, err = config.NewCGRConfigFromPath(filterCfgPath) if err != nil { t.Error(err) diff --git a/apier/v1/full_remote_it_test.go b/apier/v1/full_remote_it_test.go index 9c8daa68e..46358f0ab 100644 --- a/apier/v1/full_remote_it_test.go +++ b/apier/v1/full_remote_it_test.go @@ -702,7 +702,7 @@ func testFullRemoteITAction(t *testing.T) { TTL: 0, Type: "", Opts: nil, - ActionDiktats: []*engine.ActionDiktat{{ + Diktats: []*engine.APDiktat{{ Path: "", Value: nil, }}, @@ -714,7 +714,7 @@ func testFullRemoteITAction(t *testing.T) { TTL: 0, Type: "", Opts: nil, - ActionDiktats: []*engine.ActionDiktat{{ + Diktats: []*engine.APDiktat{{ Path: "", Value: nil, }}, diff --git a/apier/v1/precache_it_test.go b/apier/v1/precache_it_test.go index 9086b996b..220122563 100644 --- a/apier/v1/precache_it_test.go +++ b/apier/v1/precache_it_test.go @@ -38,7 +38,6 @@ var ( precacheCfgPath string precacheCfg *config.CGRConfig precacheRPC *rpc.Client - precacheDataDir = "/usr/share/cgrates" precacheConfigDIR string //run tests for specific configuration // use this flag to test the APIBan implemnentation for precache @@ -83,7 +82,7 @@ func TestPrecacheIT(t *testing.T) { func testPrecacheInitCfg(t *testing.T) { var err error - precacheCfgPath = path.Join(precacheDataDir, "conf", "samples", "precache", precacheConfigDIR) + precacheCfgPath = path.Join(*dataDir, "conf", "samples", "precache", precacheConfigDIR) precacheCfg, err = config.NewCGRConfigFromPath(precacheCfgPath) if err != nil { t.Error(err) diff --git a/apier/v1/tp_it_test.go b/apier/v1/tp_it_test.go index 3042df20a..ed280ed4f 100644 --- a/apier/v1/tp_it_test.go +++ b/apier/v1/tp_it_test.go @@ -37,7 +37,6 @@ var ( tpCfgPath string tpCfg *config.CGRConfig tpRPC *rpc.Client - tpDataDir = "/usr/share/cgrates" tpConfigDIR string //run tests for specific configuration sTestsTP = []func(t *testing.T){ @@ -74,7 +73,7 @@ func TestTPIT(t *testing.T) { func testTPInitCfg(t *testing.T) { var err error - tpCfgPath = path.Join(tpDataDir, "conf", "samples", tpConfigDIR) + tpCfgPath = path.Join(*dataDir, "conf", "samples", tpConfigDIR) tpCfg, err = config.NewCGRConfigFromPath(tpCfgPath) if err != nil { t.Error(err) @@ -108,7 +107,7 @@ func testTPImportTPFromFolderPath(t *testing.T) { var reply string if err := tpRPC.Call(utils.APIerSv1ImportTariffPlanFromFolder, utils.AttrImportTPFromFolder{TPid: "TEST_TPID2", - FolderPath: path.Join(tpDataDir, "tariffplans", "tutorial")}, &reply); err != nil { + FolderPath: path.Join(*dataDir, "tariffplans", "tutorial")}, &reply); err != nil { t.Error("Got error on APIerSv1.ImportTarrifPlanFromFolder: ", err.Error()) } else if reply != utils.OK { t.Error("Calling APIerSv1.ImportTarrifPlanFromFolder got reply: ", reply) diff --git a/apier/v1/tpaccountactions_it_test.go b/apier/v1/tpaccountactions_it_test.go index 21680eb8e..21b5a1a6c 100644 --- a/apier/v1/tpaccountactions_it_test.go +++ b/apier/v1/tpaccountactions_it_test.go @@ -36,7 +36,6 @@ var ( tpAccActionsCfgPath string tpAccActionsCfg *config.CGRConfig tpAccActionsRPC *rpc.Client - tpAccActionsDataDir = "/usr/share/cgrates" tpAccActions *utils.TPAccountActions tpAccActionsDelay int tpAccActionsConfigDIR string //run tests for specific configuration @@ -82,7 +81,7 @@ func TestTPAccActionsIT(t *testing.T) { func testTPAccActionsInitCfg(t *testing.T) { var err error - tpAccActionsCfgPath = path.Join(tpAccActionsDataDir, "conf", "samples", tpAccActionsConfigDIR) + tpAccActionsCfgPath = path.Join(*dataDir, "conf", "samples", tpAccActionsConfigDIR) tpAccActionsCfg, err = config.NewCGRConfigFromPath(tpAccActionsCfgPath) if err != nil { t.Error(err) diff --git a/apier/v1/tpaccountprofiles_it_test.go b/apier/v1/tpaccountprofiles_it_test.go index 24680ab3b..3b8b39cc2 100644 --- a/apier/v1/tpaccountprofiles_it_test.go +++ b/apier/v1/tpaccountprofiles_it_test.go @@ -36,7 +36,6 @@ var ( tpAcctPrfCfgPath string tpAcctPrfCfg *config.CGRConfig tpAcctPrfRPC *rpc.Client - tpAcctPrfDataDir = "/usr/share/cgrates" tpAcctPrf *utils.TPAccountProfile tpAcctPrfDelay int tpAcctPrfConfigDIR string //run tests for specific configuration @@ -79,7 +78,7 @@ func TestTPAcctPrfIT(t *testing.T) { func testTPAcctPrfInitCfg(t *testing.T) { var err error - tpAcctPrfCfgPath = path.Join(tpAcctPrfDataDir, "conf", "samples", tpAcctPrfConfigDIR) + tpAcctPrfCfgPath = path.Join(*dataDir, "conf", "samples", tpAcctPrfConfigDIR) tpAcctPrfCfg, err = config.NewCGRConfigFromPath(tpAcctPrfCfgPath) if err != nil { t.Error(err) diff --git a/apier/v1/tpactionplans_it_test.go b/apier/v1/tpactionplans_it_test.go index 115985ed6..0025b40a0 100644 --- a/apier/v1/tpactionplans_it_test.go +++ b/apier/v1/tpactionplans_it_test.go @@ -36,7 +36,6 @@ var ( tpAccPlansCfgPath string tpAccPlansCfg *config.CGRConfig tpAccPlansRPC *rpc.Client - tpAccPlansDataDir = "/usr/share/cgrates" tpAccPlan *utils.TPActionPlan tpAccPlansDelay int tpAccPlansConfigDIR string //run tests for specific configuration @@ -80,7 +79,7 @@ func TestTPAccPlansIT(t *testing.T) { func testTPAccPlansInitCfg(t *testing.T) { var err error - tpAccPlansCfgPath = path.Join(tpAccPlansDataDir, "conf", "samples", tpAccPlansConfigDIR) + tpAccPlansCfgPath = path.Join(*dataDir, "conf", "samples", tpAccPlansConfigDIR) tpAccPlansCfg, err = config.NewCGRConfigFromPath(tpAccPlansCfgPath) if err != nil { t.Error(err) diff --git a/apier/v1/tpactionprofiles_it_test.go b/apier/v1/tpactionprofiles_it_test.go index 52ffe6ace..bb7e68d90 100644 --- a/apier/v1/tpactionprofiles_it_test.go +++ b/apier/v1/tpactionprofiles_it_test.go @@ -38,7 +38,6 @@ var ( tpActPrfCfgPath string tpActPrfCfg *config.CGRConfig tpActPrfRPC *rpc.Client - tpActPrfDataDir = "/usr/share/cgrates" tpActPrf *utils.TPActionProfile tpActPrfDelay int tpActPrfConfigDIR string //run tests for specific configuration @@ -81,7 +80,7 @@ func TestTPActPrfIT(t *testing.T) { func testTPActPrfInitCfg(t *testing.T) { var err error - tpActPrfCfgPath = path.Join(tpActPrfDataDir, "conf", "samples", tpActPrfConfigDIR) + tpActPrfCfgPath = path.Join(*dataDir, "conf", "samples", tpActPrfConfigDIR) tpActPrfCfg, err = config.NewCGRConfigFromPath(tpActPrfCfgPath) if err != nil { t.Error(err) diff --git a/apier/v1/tpactions_it_test.go b/apier/v1/tpactions_it_test.go index 27ce52cf4..431ef6139 100644 --- a/apier/v1/tpactions_it_test.go +++ b/apier/v1/tpactions_it_test.go @@ -36,7 +36,6 @@ var ( tpActionCfgPath string tpActionCfg *config.CGRConfig tpActionRPC *rpc.Client - tpActionDataDir = "/usr/share/cgrates" tpActions *utils.TPActions tpActionDelay int tpActionConfigDIR string //run tests for specific configuration @@ -80,7 +79,7 @@ func TestTPActionsIT(t *testing.T) { func testTPActionsInitCfg(t *testing.T) { var err error - tpActionCfgPath = path.Join(tpActionDataDir, "conf", "samples", tpActionConfigDIR) + tpActionCfgPath = path.Join(*dataDir, "conf", "samples", tpActionConfigDIR) tpActionCfg, err = config.NewCGRConfigFromPath(tpActionCfgPath) if err != nil { t.Error(err) diff --git a/apier/v1/tpactiontriggers_it_test.go b/apier/v1/tpactiontriggers_it_test.go index 6e94d43a2..0cb31b3e1 100644 --- a/apier/v1/tpactiontriggers_it_test.go +++ b/apier/v1/tpactiontriggers_it_test.go @@ -36,7 +36,6 @@ var ( tpActionTriggerCfgPath string tpActionTriggerCfg *config.CGRConfig tpActionTriggerRPC *rpc.Client - tpActionTriggerDataDir = "/usr/share/cgrates" tpActionTriggers *utils.TPActionTriggers tpActionTriggerDelay int tpActionTriggerConfigDIR string //run tests for specific configuration @@ -80,7 +79,7 @@ func TestTPActionTriggersIT(t *testing.T) { func testTPActionTriggersInitCfg(t *testing.T) { var err error - tpActionTriggerCfgPath = path.Join(tpActionTriggerDataDir, "conf", "samples", tpActionTriggerConfigDIR) + tpActionTriggerCfgPath = path.Join(*dataDir, "conf", "samples", tpActionTriggerConfigDIR) tpActionTriggerCfg, err = config.NewCGRConfigFromPath(tpActionTriggerCfgPath) if err != nil { t.Error(err) diff --git a/apier/v1/tpattributes_it_test.go b/apier/v1/tpattributes_it_test.go index dc7126dbe..773e5fd7a 100644 --- a/apier/v1/tpattributes_it_test.go +++ b/apier/v1/tpattributes_it_test.go @@ -38,7 +38,6 @@ var ( tpAlsPrfCfgPath string tpAlsPrfCfg *config.CGRConfig tpAlsPrfRPC *rpc.Client - tpAlsPrfDataDir = "/usr/share/cgrates" tpAlsPrf *utils.TPAttributeProfile tpAlsPrfDelay int tpAlsPrfConfigDIR string //run tests for specific configuration @@ -81,7 +80,7 @@ func TestTPAlsPrfIT(t *testing.T) { func testTPAlsPrfInitCfg(t *testing.T) { var err error - tpAlsPrfCfgPath = path.Join(tpAlsPrfDataDir, "conf", "samples", tpAlsPrfConfigDIR) + tpAlsPrfCfgPath = path.Join(*dataDir, "conf", "samples", tpAlsPrfConfigDIR) tpAlsPrfCfg, err = config.NewCGRConfigFromPath(tpAlsPrfCfgPath) if err != nil { t.Error(err) diff --git a/apier/v1/tpchargers_it_test.go b/apier/v1/tpchargers_it_test.go index 162ad23b4..4d94f6b5b 100644 --- a/apier/v1/tpchargers_it_test.go +++ b/apier/v1/tpchargers_it_test.go @@ -37,7 +37,6 @@ var ( tpChrgsCfgPath string tpChrgsCfg *config.CGRConfig tpChrgsRPC *rpc.Client - tpChrgsDataDir = "/usr/share/cgrates" tpChrgs *utils.TPChargerProfile tpChrgsDelay int tpChrgsConfigDIR string //run tests for specific configuration @@ -80,7 +79,7 @@ func TestTPChrgsIT(t *testing.T) { func testTPChrgsInitCfg(t *testing.T) { var err error - tpChrgsCfgPath = path.Join(tpChrgsDataDir, "conf", "samples", tpChrgsConfigDIR) + tpChrgsCfgPath = path.Join(*dataDir, "conf", "samples", tpChrgsConfigDIR) tpChrgsCfg, err = config.NewCGRConfigFromPath(tpChrgsCfgPath) if err != nil { t.Error(err) diff --git a/apier/v1/tpdestinationrates_it_test.go b/apier/v1/tpdestinationrates_it_test.go index 3476d58c9..d64045789 100644 --- a/apier/v1/tpdestinationrates_it_test.go +++ b/apier/v1/tpdestinationrates_it_test.go @@ -36,7 +36,6 @@ var ( tpDstRateCfgPath string tpDstRateCfg *config.CGRConfig tpDstRateRPC *rpc.Client - tpDstRateDataDir = "/usr/share/cgrates" tpDstRate *utils.TPDestinationRate tpDstRateDelay int tpDstRateConfigDIR string //run tests for specific configuration @@ -79,7 +78,7 @@ func TestTPDstRateIT(t *testing.T) { func testTPDstRateInitCfg(t *testing.T) { var err error - tpDstRateCfgPath = path.Join(tpDstRateDataDir, "conf", "samples", tpDstRateConfigDIR) + tpDstRateCfgPath = path.Join(*dataDir, "conf", "samples", tpDstRateConfigDIR) tpDstRateCfg, err = config.NewCGRConfigFromPath(tpDstRateCfgPath) if err != nil { t.Error(err) diff --git a/apier/v1/tpdestinations_it_test.go b/apier/v1/tpdestinations_it_test.go index 0e9cc13e3..c89fa2d2c 100644 --- a/apier/v1/tpdestinations_it_test.go +++ b/apier/v1/tpdestinations_it_test.go @@ -36,7 +36,6 @@ var ( tpDestinationCfgPath string tpDestinationCfg *config.CGRConfig tpDestinationRPC *rpc.Client - tpDestinationDataDir = "/usr/share/cgrates" tpDestination *utils.TPDestination tpDestinationDelay int tpDestinationConfigDIR string //run tests for specific configuration @@ -79,7 +78,7 @@ func TestTPDestinationsIT(t *testing.T) { func testTPDestinationsInitCfg(t *testing.T) { var err error - tpDestinationCfgPath = path.Join(tpDestinationDataDir, "conf", "samples", tpDestinationConfigDIR) + tpDestinationCfgPath = path.Join(*dataDir, "conf", "samples", tpDestinationConfigDIR) tpDestinationCfg, err = config.NewCGRConfigFromPath(tpDestinationCfgPath) if err != nil { t.Error(err) diff --git a/apier/v1/tpdispatchers_it_test.go b/apier/v1/tpdispatchers_it_test.go index e778b46e6..7ce9d85fd 100644 --- a/apier/v1/tpdispatchers_it_test.go +++ b/apier/v1/tpdispatchers_it_test.go @@ -36,7 +36,6 @@ var ( tpDispatcherCfgPath string tpDispatcherCfg *config.CGRConfig tpDispatcherRPC *rpc.Client - tpDispatcherDataDir = "/usr/share/cgrates" tpDispatcher *utils.TPDispatcherProfile tpDispatcherDelay int tpDispatcherConfigDIR string //run tests for specific configuration @@ -79,7 +78,7 @@ func TestTPDispatcherIT(t *testing.T) { func testTPDispatcherInitCfg(t *testing.T) { var err error - tpDispatcherCfgPath = path.Join(tpDispatcherDataDir, "conf", "samples", tpDispatcherConfigDIR) + tpDispatcherCfgPath = path.Join(*dataDir, "conf", "samples", tpDispatcherConfigDIR) tpDispatcherCfg, err = config.NewCGRConfigFromPath(tpDispatcherCfgPath) if err != nil { t.Error(err) diff --git a/apier/v1/tpfilters_it_test.go b/apier/v1/tpfilters_it_test.go index 2124b498e..11c36239c 100644 --- a/apier/v1/tpfilters_it_test.go +++ b/apier/v1/tpfilters_it_test.go @@ -38,7 +38,6 @@ var ( tpFilterCfgPath string tpFilterCfg *config.CGRConfig tpFilterRPC *rpc.Client - tpFilterDataDir = "/usr/share/cgrates" tpFilter *utils.TPFilterProfile tpFilterDelay int tpFilterConfigDIR string //run tests for specific configuration @@ -81,7 +80,7 @@ func TestTPFilterITMySql(t *testing.T) { func testTPFilterInitCfg(t *testing.T) { var err error - tpFilterCfgPath = path.Join(tpFilterDataDir, "conf", "samples", tpFilterConfigDIR) + tpFilterCfgPath = path.Join(*dataDir, "conf", "samples", tpFilterConfigDIR) tpFilterCfg, err = config.NewCGRConfigFromPath(tpFilterCfgPath) if err != nil { t.Error(err) diff --git a/apier/v1/tprateprofiles_it_test.go b/apier/v1/tprateprofiles_it_test.go index 45f3a1a3e..b08f488d5 100644 --- a/apier/v1/tprateprofiles_it_test.go +++ b/apier/v1/tprateprofiles_it_test.go @@ -37,7 +37,6 @@ var ( tpRatePrfCfgPath string tpRatePrfCfg *config.CGRConfig tpRatePrfRPC *rpc.Client - tpRatePrfDataDir = "/usr/share/cgrates" tpRatePrf *utils.TPRateProfile tpRatePrfDelay int tpRatePrfConfigDIR string //run tests for specific configuration @@ -80,7 +79,7 @@ func TestTPRatePrfIT(t *testing.T) { func testTPRatePrfInitCfg(t *testing.T) { var err error - tpRatePrfCfgPath = path.Join(tpRatePrfDataDir, "conf", "samples", tpRatePrfConfigDIR) + tpRatePrfCfgPath = path.Join(*dataDir, "conf", "samples", tpRatePrfConfigDIR) tpRatePrfCfg, err = config.NewCGRConfigFromPath(tpRatePrfCfgPath) if err != nil { t.Error(err) diff --git a/apier/v1/tprates_it_test.go b/apier/v1/tprates_it_test.go index 1c423814c..544e026da 100644 --- a/apier/v1/tprates_it_test.go +++ b/apier/v1/tprates_it_test.go @@ -36,7 +36,6 @@ var ( tpRateCfgPath string tpRateCfg *config.CGRConfig tpRateRPC *rpc.Client - tpRateDataDir = "/usr/share/cgrates" tpRate *utils.TPRateRALs tpRateDelay int tpRateConfigDIR string //run tests for specific configuration @@ -79,7 +78,7 @@ func TestTPRatesIT(t *testing.T) { func testTPRatesInitCfg(t *testing.T) { var err error - tpRateCfgPath = path.Join(tpRateDataDir, "conf", "samples", tpRateConfigDIR) + tpRateCfgPath = path.Join(*dataDir, "conf", "samples", tpRateConfigDIR) tpRateCfg, err = config.NewCGRConfigFromPath(tpRateCfgPath) if err != nil { t.Error(err) diff --git a/apier/v1/tpratingplans_it_test.go b/apier/v1/tpratingplans_it_test.go index 29f5a3f3e..981be4bae 100644 --- a/apier/v1/tpratingplans_it_test.go +++ b/apier/v1/tpratingplans_it_test.go @@ -36,7 +36,6 @@ var ( tpRatingPlanCfgPath string tpRatingPlanCfg *config.CGRConfig tpRatingPlanRPC *rpc.Client - tpRatingPlanDataDir = "/usr/share/cgrates" tpRatingPlan *utils.TPRatingPlan tpRatingPlanDelay int tpRatingPlanConfigDIR string //run tests for specific configuration @@ -79,7 +78,7 @@ func TestTPRatingPlansIT(t *testing.T) { func testTPRatingPlansInitCfg(t *testing.T) { var err error - tpRatingPlanCfgPath = path.Join(tpRatingPlanDataDir, "conf", "samples", tpRatingPlanConfigDIR) + tpRatingPlanCfgPath = path.Join(*dataDir, "conf", "samples", tpRatingPlanConfigDIR) tpRatingPlanCfg, err = config.NewCGRConfigFromPath(tpRatingPlanCfgPath) if err != nil { t.Error(err) diff --git a/apier/v1/tpratingprofiles_it_test.go b/apier/v1/tpratingprofiles_it_test.go index 1890e5915..3654aeaf3 100644 --- a/apier/v1/tpratingprofiles_it_test.go +++ b/apier/v1/tpratingprofiles_it_test.go @@ -36,7 +36,6 @@ var ( tpRatingProfileCfgPath string tpRatingProfileCfg *config.CGRConfig tpRatingProfileRPC *rpc.Client - tpRatingProfileDataDir = "/usr/share/cgrates" tpRatingProfile *utils.TPRatingProfile tpRatingProfileDelay int tpRatingProfileConfigDIR string //run tests for specific configuration @@ -82,7 +81,7 @@ func TestTPRatingProfilesIT(t *testing.T) { func testTPRatingProfilesInitCfg(t *testing.T) { var err error - tpRatingProfileCfgPath = path.Join(tpRatingProfileDataDir, "conf", "samples", tpRatingProfileConfigDIR) + tpRatingProfileCfgPath = path.Join(*dataDir, "conf", "samples", tpRatingProfileConfigDIR) tpRatingProfileCfg, err = config.NewCGRConfigFromPath(tpRatingProfileCfgPath) if err != nil { t.Error(err) diff --git a/apier/v1/tpresources_it_test.go b/apier/v1/tpresources_it_test.go index 1b3016031..f225267a8 100644 --- a/apier/v1/tpresources_it_test.go +++ b/apier/v1/tpresources_it_test.go @@ -37,7 +37,6 @@ var ( tpResCfgPath string tpResCfg *config.CGRConfig tpResRPC *rpc.Client - tpResDataDir = "/usr/share/cgrates" tpRes *utils.TPResourceProfile tpResDelay int tpResConfigDIR string //run tests for specific configuration @@ -79,7 +78,7 @@ func TestTPResIT(t *testing.T) { func testTPResInitCfg(t *testing.T) { var err error - tpResCfgPath = path.Join(tpResDataDir, "conf", "samples", tpResConfigDIR) + tpResCfgPath = path.Join(*dataDir, "conf", "samples", tpResConfigDIR) tpResCfg, err = config.NewCGRConfigFromPath(tpResCfgPath) if err != nil { t.Error(err) diff --git a/apier/v1/tproutes_it_test.go b/apier/v1/tproutes_it_test.go index 9e84c0ae1..3737c29a5 100644 --- a/apier/v1/tproutes_it_test.go +++ b/apier/v1/tproutes_it_test.go @@ -38,7 +38,6 @@ var ( tpRouteCfgPath string tpRouteCfg *config.CGRConfig tpRouteRPC *rpc.Client - tpRouteDataDire = "/usr/share/cgrates" tpRoutePrf *utils.TPRouteProfile tpRouteDelay int tpRouteConfigDIR string //run tests for specific configuration @@ -81,7 +80,7 @@ func TestTPRouteIT(t *testing.T) { func testTPRouteInitCfg(t *testing.T) { var err error - tpRouteCfgPath = path.Join(tpRouteDataDire, "conf", "samples", tpRouteConfigDIR) + tpRouteCfgPath = path.Join(*dataDir, "conf", "samples", tpRouteConfigDIR) tpRouteCfg, err = config.NewCGRConfigFromPath(tpRouteCfgPath) if err != nil { t.Error(err) diff --git a/apier/v1/tpsharedgroups_it_test.go b/apier/v1/tpsharedgroups_it_test.go index b262b2565..4e8ba4479 100644 --- a/apier/v1/tpsharedgroups_it_test.go +++ b/apier/v1/tpsharedgroups_it_test.go @@ -36,7 +36,6 @@ var ( tpSharedGroupCfgPath string tpSharedGroupCfg *config.CGRConfig tpSharedGroupRPC *rpc.Client - tpSharedGroupDataDir = "/usr/share/cgrates" tpSharedGroups *utils.TPSharedGroups tpSharedGroupDelay int tpSharedGroupConfigDIR string //run tests for specific configuration @@ -79,7 +78,7 @@ func TestTPSharedGroupsIT(t *testing.T) { func testTPSharedGroupsInitCfg(t *testing.T) { var err error - tpSharedGroupCfgPath = path.Join(tpSharedGroupDataDir, "conf", "samples", tpSharedGroupConfigDIR) + tpSharedGroupCfgPath = path.Join(*dataDir, "conf", "samples", tpSharedGroupConfigDIR) tpSharedGroupCfg, err = config.NewCGRConfigFromPath(tpSharedGroupCfgPath) if err != nil { t.Error(err) diff --git a/apier/v1/tpstats_it_test.go b/apier/v1/tpstats_it_test.go index 7a427bce8..a787537bb 100644 --- a/apier/v1/tpstats_it_test.go +++ b/apier/v1/tpstats_it_test.go @@ -38,7 +38,6 @@ var ( tpStatCfgPath string tpStatCfg *config.CGRConfig tpStatRPC *rpc.Client - tpStatDataDir = "/usr/share/cgrates" tpStat *utils.TPStatProfile tpStatDelay int tpStatConfigDIR string //run tests for specific configuration @@ -80,7 +79,7 @@ func TestTPStatIT(t *testing.T) { func testTPStatsInitCfg(t *testing.T) { var err error - tpStatCfgPath = path.Join(tpStatDataDir, "conf", "samples", tpStatConfigDIR) + tpStatCfgPath = path.Join(*dataDir, "conf", "samples", tpStatConfigDIR) tpStatCfg, err = config.NewCGRConfigFromPath(tpStatCfgPath) if err != nil { t.Error(err) diff --git a/apier/v1/tpthresholds_it_test.go b/apier/v1/tpthresholds_it_test.go index 295a79185..bf793d2aa 100644 --- a/apier/v1/tpthresholds_it_test.go +++ b/apier/v1/tpthresholds_it_test.go @@ -37,7 +37,6 @@ var ( tpThresholdCfgPath string tpThresholdCfg *config.CGRConfig tpThresholdRPC *rpc.Client - tpThresholdDataDir = "/usr/share/cgrates" tpThreshold *utils.TPThresholdProfile tpThresholdDelay int tpThresholdConfigDIR string //run tests for specific configuration @@ -80,7 +79,7 @@ func TestTPThresholdIT(t *testing.T) { func testTPThreholdInitCfg(t *testing.T) { var err error - tpThresholdCfgPath = path.Join(tpThresholdDataDir, "conf", "samples", tpThresholdConfigDIR) + tpThresholdCfgPath = path.Join(*dataDir, "conf", "samples", tpThresholdConfigDIR) tpThresholdCfg, err = config.NewCGRConfigFromPath(tpThresholdCfgPath) if err != nil { t.Error(err) diff --git a/apier/v1/tptimings_it_test.go b/apier/v1/tptimings_it_test.go index 95df9482c..5f158b5e9 100644 --- a/apier/v1/tptimings_it_test.go +++ b/apier/v1/tptimings_it_test.go @@ -36,7 +36,6 @@ var ( tpTimingCfgPath string tpTimingCfg *config.CGRConfig tpTimingRPC *rpc.Client - tpTimingDataDir = "/usr/share/cgrates" tpTiming *utils.ApierTPTiming tpTimingDelay int tpTimingConfigDIR string //run tests for specific configuration @@ -79,7 +78,7 @@ func TestTPTimingIT(t *testing.T) { func testTPTimingsInitCfg(t *testing.T) { var err error - tpTimingCfgPath = path.Join(tpTimingDataDir, "conf", "samples", tpTimingConfigDIR) + tpTimingCfgPath = path.Join(*dataDir, "conf", "samples", tpTimingConfigDIR) tpTimingCfg, err = config.NewCGRConfigFromPath(tpTimingCfgPath) if err != nil { t.Error(err) diff --git a/apier/v1/versions_it_test.go b/apier/v1/versions_it_test.go index 5f86ab008..415d6aa5e 100644 --- a/apier/v1/versions_it_test.go +++ b/apier/v1/versions_it_test.go @@ -34,7 +34,6 @@ var ( vrsCfgPath string vrsCfg *config.CGRConfig vrsRPC *rpc.Client - vrsDataDir = "/usr/share/cgrates" vrsDelay int vrsConfigDIR string //run tests for specific configuration vrsStorageType string @@ -86,12 +85,12 @@ func TestVrsIT(t *testing.T) { func testVrsInitCfg(t *testing.T) { var err error - vrsCfgPath = path.Join(vrsDataDir, "conf", "samples", vrsConfigDIR) + vrsCfgPath = path.Join(*dataDir, "conf", "samples", vrsConfigDIR) vrsCfg, err = config.NewCGRConfigFromPath(vrsCfgPath) if err != nil { t.Error(err) } - vrsCfg.DataFolderPath = vrsDataDir // Share DataFolderPath through config towards StoreDb for Flush() + vrsCfg.DataFolderPath = *dataDir // Share DataFolderPath through config towards StoreDb for Flush() vrsDelay = 1000 } diff --git a/apier/v2/attributes_it_test.go b/apier/v2/attributes_it_test.go index 439f3b014..6daa44e2f 100644 --- a/apier/v2/attributes_it_test.go +++ b/apier/v2/attributes_it_test.go @@ -38,7 +38,6 @@ var ( alsPrfCfgPath string alsPrfCfg *config.CGRConfig attrSRPC *rpc.Client - alsPrfDataDir = "/usr/share/cgrates" alsPrf *engine.AttributeProfile alsPrfConfigDIR string //run tests for specific configuration @@ -77,7 +76,7 @@ func TestAttributeSIT(t *testing.T) { func testAttributeSInitCfg(t *testing.T) { var err error - alsPrfCfgPath = path.Join(alsPrfDataDir, "conf", "samples", alsPrfConfigDIR) + alsPrfCfgPath = path.Join(*dataDir, "conf", "samples", alsPrfConfigDIR) alsPrfCfg, err = config.NewCGRConfigFromPath(alsPrfCfgPath) if err != nil { t.Error(err) diff --git a/cmd/cgr-engine/cgr-engine.go b/cmd/cgr-engine/cgr-engine.go index dc341e093..684cc7956 100644 --- a/cmd/cgr-engine/cgr-engine.go +++ b/cmd/cgr-engine/cgr-engine.go @@ -517,7 +517,7 @@ func main() { utils.ConcatenatedKey(utils.MetaInternal, utils.MetaResponder): internalResponderChan, utils.ConcatenatedKey(utils.MetaInternal, utils.MetaScheduler): internalSchedulerSChan, utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS): internalSessionSChan, - utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStatS): internalStatSChan, + utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats): internalStatSChan, utils.ConcatenatedKey(utils.MetaInternal, utils.MetaRoutes): internalRouteSChan, utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds): internalThresholdSChan, utils.ConcatenatedKey(utils.MetaInternal, utils.MetaServiceManager): internalServeManagerChan, diff --git a/config/actionscfg.go b/config/actionscfg.go index 2f43ecee3..8537bedb6 100644 --- a/config/actionscfg.go +++ b/config/actionscfg.go @@ -76,7 +76,7 @@ func (acS *ActionSCfg) loadFromJSONCfg(jsnCfg *ActionSJsonCfg) (err error) { // if we have the connection internal we change the name so we can have internal rpc for each subsystem acS.StatSConns[idx] = connID if connID == utils.MetaInternal { - acS.StatSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStatS) + acS.StatSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats) } } } @@ -161,7 +161,7 @@ func (acS *ActionSCfg) AsMapInterface() (initialMP map[string]interface{}) { statSConns := make([]string, len(acS.StatSConns)) for i, item := range acS.StatSConns { statSConns[i] = item - if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStatS) { + if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats) { statSConns[i] = utils.MetaInternal } } diff --git a/config/attributescfg.go b/config/attributescfg.go index 0153eff75..38dc9c0b0 100644 --- a/config/attributescfg.go +++ b/config/attributescfg.go @@ -47,7 +47,7 @@ func (alS *AttributeSCfg) loadFromJSONCfg(jsnCfg *AttributeSJsonCfg) (err error) // if we have the connection internal we change the name so we can have internal rpc for each subsystem alS.StatSConns[idx] = connID if connID == utils.MetaInternal { - alS.StatSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStatS) + alS.StatSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats) } } } @@ -137,7 +137,7 @@ func (alS *AttributeSCfg) AsMapInterface() (initialMP map[string]interface{}) { statSConns := make([]string, len(alS.StatSConns)) for i, item := range alS.StatSConns { statSConns[i] = item - if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStatS) { + if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats) { statSConns[i] = utils.MetaInternal } } diff --git a/config/cdrscfg.go b/config/cdrscfg.go index 98087b22e..bebddb5c4 100644 --- a/config/cdrscfg.go +++ b/config/cdrscfg.go @@ -103,7 +103,7 @@ func (cdrscfg *CdrsCfg) loadFromJSONCfg(jsnCdrsCfg *CdrsJsonCfg) (err error) { // if we have the connection internal we change the name so we can have internal rpc for each subsystem cdrscfg.StatSConns[idx] = connID if connID == utils.MetaInternal { - cdrscfg.StatSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStatS) + cdrscfg.StatSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats) } } } @@ -200,7 +200,7 @@ func (cdrscfg *CdrsCfg) AsMapInterface() (initialMP map[string]interface{}) { statSConns := make([]string, len(cdrscfg.StatSConns)) for i, item := range cdrscfg.StatSConns { statSConns[i] = item - if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStatS) { + if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats) { statSConns[i] = utils.MetaInternal } } diff --git a/config/filterscfg.go b/config/filterscfg.go index dddbe4254..803e02339 100644 --- a/config/filterscfg.go +++ b/config/filterscfg.go @@ -39,7 +39,7 @@ func (fSCfg *FilterSCfg) loadFromJSONCfg(jsnCfg *FilterSJsonCfg) (err error) { // if we have the connection internal we change the name so we can have internal rpc for each subsystem fSCfg.StatSConns[idx] = connID if connID == utils.MetaInternal { - fSCfg.StatSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStatS) + fSCfg.StatSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats) } } } @@ -73,7 +73,7 @@ func (fSCfg *FilterSCfg) AsMapInterface() (initialMP map[string]interface{}) { statSConns := make([]string, len(fSCfg.StatSConns)) for i, item := range fSCfg.StatSConns { statSConns[i] = item - if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStatS) { + if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats) { statSConns[i] = utils.MetaInternal } } diff --git a/config/ralscfg.go b/config/ralscfg.go index 60fef32e2..0bb7266f8 100644 --- a/config/ralscfg.go +++ b/config/ralscfg.go @@ -63,7 +63,7 @@ func (ralsCfg *RalsCfg) loadFromJSONCfg(jsnRALsCfg *RalsJsonCfg) (err error) { // if we have the connection internal we change the name so we can have internal rpc for each subsystem ralsCfg.StatSConns[idx] = conn if conn == utils.MetaInternal { - ralsCfg.StatSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStatS) + ralsCfg.StatSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats) } } } @@ -131,7 +131,7 @@ func (ralsCfg *RalsCfg) AsMapInterface() (initialMP map[string]interface{}) { statS := make([]string, len(ralsCfg.StatSConns)) for i, item := range ralsCfg.StatSConns { statS[i] = item - if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStatS) { + if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats) { statS[i] = utils.MetaInternal } } diff --git a/config/ralscfg_test.go b/config/ralscfg_test.go index 90171264b..8b618ad0a 100644 --- a/config/ralscfg_test.go +++ b/config/ralscfg_test.go @@ -50,7 +50,7 @@ func TestRalsCfgFromJsonCfgCase1(t *testing.T) { expected := &RalsCfg{ Enabled: true, ThresholdSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds), "*conn1"}, - StatSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStatS), "*conn1"}, + StatSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats), "*conn1"}, CacheSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCaches), "*conn1"}, RpSubjectPrefixMatching: true, RemoveExpired: true, @@ -170,7 +170,7 @@ func TestRalsCfgClone(t *testing.T) { ban := &RalsCfg{ Enabled: true, ThresholdSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds), "*conn1"}, - StatSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStatS), "*conn1"}, + StatSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats), "*conn1"}, CacheSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCaches), "*conn1"}, RpSubjectPrefixMatching: true, RemoveExpired: true, diff --git a/config/routescfg.go b/config/routescfg.go index 4cf7636dc..193263912 100644 --- a/config/routescfg.go +++ b/config/routescfg.go @@ -180,7 +180,7 @@ func (rts *RouteSCfg) AsMapInterface() (initialMP map[string]interface{}) { statSConns := make([]string, len(rts.StatSConns)) for i, item := range rts.StatSConns { statSConns[i] = item - if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStatS) { + if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats) { statSConns[i] = utils.MetaInternal } } diff --git a/config/routescfg_test.go b/config/routescfg_test.go index a829a4d9f..68072baed 100644 --- a/config/routescfg_test.go +++ b/config/routescfg_test.go @@ -46,7 +46,7 @@ func TestRouteSCfgloadFromJsonCfg(t *testing.T) { SuffixIndexedFields: &[]string{"*req.index1", "*req.index2"}, AttributeSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes), "conn1"}, ResourceSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaResources), "conn1"}, - StatSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStatS), "conn1"}, + StatSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats), "conn1"}, RALsConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaResponder), "conn1"}, DefaultRatio: 10, NestedFields: true, @@ -127,7 +127,7 @@ func TestRouteSCfgClone(t *testing.T) { SuffixIndexedFields: &[]string{"*req.index1", "*req.index2"}, AttributeSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes), "conn1"}, ResourceSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaResources), "conn1"}, - StatSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStatS), "conn1"}, + StatSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats), "conn1"}, RALsConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaResponder), "conn1"}, DefaultRatio: 10, NestedFields: true, diff --git a/config/sessionscfg.go b/config/sessionscfg.go index 525e5338d..fe53783d2 100644 --- a/config/sessionscfg.go +++ b/config/sessionscfg.go @@ -176,7 +176,7 @@ func (scfg *SessionSCfg) loadFromJSONCfg(jsnCfg *SessionSJsonCfg) (err error) { // if we have the connection internal we change the name so we can have internal rpc for each subsystem scfg.StatSConns[idx] = connID if connID == utils.MetaInternal { - scfg.StatSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStatS) + scfg.StatSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats) } } } @@ -404,7 +404,7 @@ func (scfg *SessionSCfg) AsMapInterface() (initialMP map[string]interface{}) { statSConns := make([]string, len(scfg.StatSConns)) for i, item := range scfg.StatSConns { statSConns[i] = item - if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStatS) { + if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats) { statSConns[i] = utils.MetaInternal } } diff --git a/config/sessionscfg_test.go b/config/sessionscfg_test.go index dad3110ab..21fce497d 100644 --- a/config/sessionscfg_test.go +++ b/config/sessionscfg_test.go @@ -100,7 +100,7 @@ func TestSessionSCfgloadFromJsonCfgCase1(t *testing.T) { RALsConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaResponder), "*conn1"}, ResSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaResources), "*conn1"}, ThreshSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds), "*conn1"}, - StatSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStatS), "*conn1"}, + StatSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats), "*conn1"}, RouteSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaRoutes), "*conn1"}, AttrSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes), "*conn1"}, CDRsConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCDRs), "*conn1"}, @@ -846,7 +846,7 @@ func TestSessionSCfgClone(t *testing.T) { RALsConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaResponder), "*conn1"}, ResSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaResources), "*conn1"}, ThreshSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds), "*conn1"}, - StatSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStatS), "*conn1"}, + StatSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats), "*conn1"}, RouteSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaRoutes), "*conn1"}, AttrSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes), "*conn1"}, CDRsConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCDRs), "*conn1"}, diff --git a/data/tariffplans/testit/ActionProfiles.csv b/data/tariffplans/testit/ActionProfiles.csv index c602f6e9f..73af7c414 100644 --- a/data/tariffplans/testit/ActionProfiles.csv +++ b/data/tariffplans/testit/ActionProfiles.csv @@ -1,7 +1,8 @@ #Tenant,ID,FilterIDs,ActivationInterval,Weight,Schedule,TargetType,TargetIDs,ActionID,ActionFilterIDs,ActionBlocker,ActionTTL,ActionType,ActionOpts,ActionPath,ActionValue -cgrates.org,ONE_TIME_ACT,,,10,*asap,*accounts,1001;1002,TOPUP,,false,0s,*add_balance,,~*balance.TestDataBalance.Units,10 -cgrates.org,ONE_TIME_ACT,,,,,,,SET_BALANCE_TEST_DATA,,false,0s,*set_balance,,~*balance.TestDataBalance.Units,0 -cgrates.org,ONE_TIME_ACT,,,,,,,TOPUP_TEST_DATA,,false,0s,*add_balance,,~*balance.TestDataBalance.Units,1024 -cgrates.org,ONE_TIME_ACT,,,,,,,SET_BALANCE_TEST_VOICE,,false,0s,*set_balance,,~*balance.TestVoiceBalance.Type,*voice -cgrates.org,ONE_TIME_ACT,,,,,,,TOPUP_TEST_VOICE,,false,0s,*add_balance,,~*balance.TestVoiceBalance.Units,15m15s -cgrates.org,ONE_TIME_ACT,,,,,,,SET_BALANCE_TEST_VOICE,,false,0s,*set_balance,,~*balance.TestVoiceBalance.Filters, +cgrates.org,ONE_TIME_ACT,,,10,*asap,*accounts,1001;1002,TOPUP,,false,0s,*add_balance,,*balance.TestBalance.Units,10 +cgrates.org,ONE_TIME_ACT,,,,,,,SET_BALANCE_TEST_DATA,,false,0s,*set_balance,,*balance.TestDataBalance.Type,*data +cgrates.org,ONE_TIME_ACT,,,,,,,TOPUP_TEST_DATA,,false,0s,*add_balance,,*balance.TestDataBalance.Units,1024 +cgrates.org,ONE_TIME_ACT,,,,,,,SET_BALANCE_TEST_VOICE,,false,0s,*set_balance,,*balance.TestVoiceBalance.Type,*voice +cgrates.org,ONE_TIME_ACT,,,,,,,TOPUP_TEST_VOICE,,false,0s,*add_balance,,*balance.TestVoiceBalance.Units,15m15s +cgrates.org,ONE_TIME_ACT,,,,,,,SET_BALANCE_TEST_FILTERS,,false,0s,*set_balance,,*balance.TestVoiceBalance.Filters,*string:~*req.CustomField:500 +cgrates.org,ONE_TIME_ACT,,,,,,,TOPUP_REM_VOICE,,false,0s,*rem_balance,,TestVoiceBalance2, \ No newline at end of file diff --git a/data/tariffplans/tutactions/ActionProfiles.csv b/data/tariffplans/tutactions/ActionProfiles.csv index 5f313ebae..ddf8906f9 100644 --- a/data/tariffplans/tutactions/ActionProfiles.csv +++ b/data/tariffplans/tutactions/ActionProfiles.csv @@ -1,6 +1,8 @@ #Tenant,ID,FilterIDs,ActivationInterval,Weight,Schedule,TargetType,TargetIDs,ActionID,ActionFilterIDs,ActionBlocker,ActionTTL,ActionType,ActionOpts,ActionPath,ActionValue -cgrates.org,ONE_TIME_ACT,,,10,*asap,*accounts,1001;1002,TOPUP,,false,0s,*topup,,~*balance.TestBalance.Value,10 -cgrates.org,ONE_TIME_ACT,,,,,,,SET_BALANCE_TEST_DATA,,false,0s,*set_balance,,~*balance.TestDataBalance.Type,*data -cgrates.org,ONE_TIME_ACT,,,,,,,TOPUP_TEST_DATA,,false,0s,*topup,,~*balance.TestDataBalance.Value,1024 -cgrates.org,ONE_TIME_ACT,,,,,,,SET_BALANCE_TEST_VOICE,,false,0s,*set_balance,,~*balance.TestVoiceBalance.Type,*voice -cgrates.org,ONE_TIME_ACT,,,,,,,TOPUP_TEST_VOICE,,false,0s,*topup,,~*balance.TestVoiceBalance.Value,15m15s +cgrates.org,ONE_TIME_ACT,,,10,*asap,*accounts,1001;1002,TOPUP,,false,0s,*add_balance,,*balance.TestBalance.Units,10 +cgrates.org,ONE_TIME_ACT,,,,,,,SET_BALANCE_TEST_DATA,,false,0s,*set_balance,,*balance.TestDataBalance.Type,*data +cgrates.org,ONE_TIME_ACT,,,,,,,TOPUP_TEST_DATA,,false,0s,*add_balance,,*balance.TestDataBalance.Units,1024 +cgrates.org,ONE_TIME_ACT,,,,,,,SET_BALANCE_TEST_VOICE,,false,0s,*set_balance,,*balance.TestVoiceBalance.Type,*voice +cgrates.org,ONE_TIME_ACT,,,,,,,TOPUP_TEST_VOICE,,false,0s,*add_balance,,*balance.TestVoiceBalance.Units,15m15s +cgrates.org,ONE_TIME_ACT,,,,,,,SET_BALANCE_TEST_FILTERS,,false,0s,*set_balance,,*balance.TestVoiceBalance.Filters,*string:~*req.CustomField:500 +cgrates.org,ONE_TIME_ACT,,,,,,,TOPUP_REM_VOICE,,false,0s,*rem_balance,,TestVoiceBalance2, diff --git a/dispatchers/accounts.go b/dispatchers/accounts.go index 3ecc6959a..92fcfd79c 100644 --- a/dispatchers/accounts.go +++ b/dispatchers/accounts.go @@ -18,7 +18,11 @@ along with this program. If not, see package dispatchers -import "github.com/cgrates/cgrates/utils" +import ( + "time" + + "github.com/cgrates/cgrates/utils" +) func (dS *DispatcherService) AccountSv1Ping(args *utils.CGREvent, rpl *string) (err error) { if args == nil { @@ -75,3 +79,37 @@ func (dS *DispatcherService) DebitAbstracts(args *utils.ArgsAccountsForEvent, re } return dS.Dispatch(args.CGREvent, utils.MetaAccounts, utils.AccountSv1DebitAbstracts, args, reply) } + +func (dS *DispatcherService) AccountSv1ActionSetBalance(args *utils.ArgsActSetBalance, reply *string) (err error) { + tnt := dS.cfg.GeneralCfg().DefaultTenant + if args.Tenant != utils.EmptyString { + tnt = args.Tenant + } + if len(dS.cfg.DispatcherSCfg().AttributeSConns) != 0 { + if err = dS.authorize(utils.AccountSv1ActionSetBalance, tnt, + utils.IfaceAsString(args.Opts[utils.OptsAPIKey]), utils.TimePointer(time.Now())); err != nil { + return + } + } + return dS.Dispatch(&utils.CGREvent{ + Tenant: tnt, + Opts: args.Opts, + }, utils.MetaAccounts, utils.AccountSv1ActionSetBalance, args, reply) +} + +func (dS *DispatcherService) AccountSv1ActionRemoveBalance(args *utils.ArgsActRemoveBalances, reply *string) (err error) { + tnt := dS.cfg.GeneralCfg().DefaultTenant + if args.Tenant != utils.EmptyString { + tnt = args.Tenant + } + if len(dS.cfg.DispatcherSCfg().AttributeSConns) != 0 { + if err = dS.authorize(utils.AccountSv1ActionRemoveBalance, tnt, + utils.IfaceAsString(args.Opts[utils.OptsAPIKey]), utils.TimePointer(time.Now())); err != nil { + return + } + } + return dS.Dispatch(&utils.CGREvent{ + Tenant: tnt, + Opts: args.Opts, + }, utils.MetaAccounts, utils.AccountSv1ActionRemoveBalance, args, reply) +} diff --git a/dispatchers/actions.go b/dispatchers/actions.go index 72616bc7f..1e13ea9dd 100644 --- a/dispatchers/actions.go +++ b/dispatchers/actions.go @@ -31,5 +31,39 @@ func (dS *DispatcherService) ActionSv1Ping(args *utils.CGREvent, rpl *string) (e return } } - return dS.Dispatch(args, utils.ActionS, utils.ActionSv1Ping, args, rpl) + return dS.Dispatch(args, utils.MetaActions, utils.ActionSv1Ping, args, rpl) +} + +func (dS *DispatcherService) ActionSv1ScheduleActions(args *utils.ArgActionSv1ScheduleActions, rpl *string) (err error) { + if args == nil { + args = new(utils.ArgActionSv1ScheduleActions) + } + tnt := dS.cfg.GeneralCfg().DefaultTenant + if args.CGREvent != nil && args.CGREvent.Tenant != utils.EmptyString { + tnt = args.CGREvent.Tenant + } + if len(dS.cfg.DispatcherSCfg().AttributeSConns) != 0 { + if err = dS.authorize(utils.ActionSv1ScheduleActions, tnt, + utils.IfaceAsString(args.Opts[utils.OptsAPIKey]), args.Time); err != nil { + return + } + } + return dS.Dispatch(args.CGREvent, utils.MetaActions, utils.ActionSv1ScheduleActions, args, rpl) +} + +func (dS *DispatcherService) ActionSv1ExecuteActions(args *utils.ArgActionSv1ScheduleActions, rpl *string) (err error) { + if args == nil { + args = new(utils.ArgActionSv1ScheduleActions) + } + tnt := dS.cfg.GeneralCfg().DefaultTenant + if args.CGREvent != nil && args.CGREvent.Tenant != utils.EmptyString { + tnt = args.CGREvent.Tenant + } + if len(dS.cfg.DispatcherSCfg().AttributeSConns) != 0 { + if err = dS.authorize(utils.ActionSv1Ping, tnt, + utils.IfaceAsString(args.Opts[utils.OptsAPIKey]), args.Time); err != nil { + return + } + } + return dS.Dispatch(args.CGREvent, utils.MetaActions, utils.ActionSv1Ping, args, rpl) } diff --git a/dispatchers/lib_test.go b/dispatchers/lib_test.go index 98c1bb79d..db17771dc 100644 --- a/dispatchers/lib_test.go +++ b/dispatchers/lib_test.go @@ -72,7 +72,7 @@ func newTestEngine(t *testing.T, cfgPath string, initDataDB, intitStoreDB bool) if err != nil { t.Fatalf("Error at config init :%v\n", err) } - d.Cfg.DataFolderPath = dspDataDir // Share DataFolderPath through config towards StoreDb for Flush() + d.Cfg.DataFolderPath = *dataDir // Share DataFolderPath through config towards StoreDb for Flush() if initDataDB { d.initDataDb(t) @@ -87,7 +87,7 @@ func newTestEngine(t *testing.T, cfgPath string, initDataDB, intitStoreDB bool) func (d *testDispatcher) startEngine(t *testing.T) { var err error - if d.cmd, err = engine.StartEngine(d.CfgPath, dspDelay); err != nil { + if d.cmd, err = engine.StartEngine(d.CfgPath, *waitRater); err != nil { t.Fatalf("Error at engine start:%v\n", err) } @@ -150,12 +150,12 @@ func (d *testDispatcher) loadData2(t *testing.T, path string) { func testDsp(t *testing.T, tests []func(t *testing.T), testName, all, all2, disp, allTF, all2TF, attrTF string) { engine.KillEngine(0) - allEngine = newTestEngine(t, path.Join(dspDataDir, "conf", "samples", "dispatchers", all), true, true) - allEngine2 = newTestEngine(t, path.Join(dspDataDir, "conf", "samples", "dispatchers", all2), true, true) - dispEngine = newTestEngine(t, path.Join(dspDataDir, "conf", "samples", "dispatchers", disp), true, true) - dispEngine.loadData2(t, path.Join(dspDataDir, "tariffplans", attrTF)) - allEngine.loadData(t, path.Join(dspDataDir, "tariffplans", allTF)) - allEngine2.loadData(t, path.Join(dspDataDir, "tariffplans", all2TF)) + allEngine = newTestEngine(t, path.Join(*dataDir, "conf", "samples", "dispatchers", all), true, true) + allEngine2 = newTestEngine(t, path.Join(*dataDir, "conf", "samples", "dispatchers", all2), true, true) + dispEngine = newTestEngine(t, path.Join(*dataDir, "conf", "samples", "dispatchers", disp), true, true) + dispEngine.loadData2(t, path.Join(*dataDir, "tariffplans", attrTF)) + allEngine.loadData(t, path.Join(*dataDir, "tariffplans", allTF)) + allEngine2.loadData(t, path.Join(*dataDir, "tariffplans", all2TF)) time.Sleep(200 * time.Millisecond) for _, stest := range tests { t.Run(testName, stest) diff --git a/dispatchers/sessions_it_test.go b/dispatchers/sessions_it_test.go index 5d4badd75..eee07b555 100755 --- a/dispatchers/sessions_it_test.go +++ b/dispatchers/sessions_it_test.go @@ -736,7 +736,7 @@ func testDspSessionReplicate(t *testing.T) { } else if reply != utils.OK { t.Error("Reply: ", reply) } - allEngine.loadData(t, path.Join(dspDataDir, "tariffplans", "testit")) + allEngine.loadData(t, path.Join(*dataDir, "tariffplans", "testit")) testDspSessionAddBalacne(t) testDspSessionAuthorize(t) testDspSessionInit(t) @@ -868,7 +868,7 @@ func testDspSessionForceDisconect(t *testing.T) { allEngine.startEngine(t) allEngine.initDataDb(t) allEngine.resetStorDb(t) - allEngine.loadData(t, path.Join(dspDataDir, "tariffplans", "testit")) + allEngine.loadData(t, path.Join(*dataDir, "tariffplans", "testit")) testDspSessionAddBalacne(t) testDspSessionAuthorize(t) testDspSessionInit(t) diff --git a/dispatchers/utils.go b/dispatchers/utils.go index bbfb7b363..ed6dcd526 100755 --- a/dispatchers/utils.go +++ b/dispatchers/utils.go @@ -28,11 +28,6 @@ import ( "github.com/cgrates/cgrates/utils" ) -var ( //var used in all tests - dspDelay = 1000 - dspDataDir = "/usr/share/cgrates" -) - type ArgsReplicateSessionsWithOpts struct { Opts map[string]interface{} Tenant string diff --git a/engine/account.go b/engine/account.go index cf37e2cca..612b79029 100644 --- a/engine/account.go +++ b/engine/account.go @@ -722,7 +722,7 @@ func (acc *Account) InitCounters() { } ct := utils.MetaCounterEvent //default if strings.Contains(at.ThresholdType, "balance") { - ct = utils.MetaCounterBalance + ct = utils.MetaBalance } uc, exists := ucTempMap[at.Balance.GetType()+ct] //log.Print("CT: ", at.Balance.GetType()+ct) diff --git a/engine/actionprofile.go b/engine/actionprofile.go index 39d5ccf82..2cdf12d3f 100644 --- a/engine/actionprofile.go +++ b/engine/actionprofile.go @@ -53,16 +53,16 @@ func (aps ActionProfiles) Sort() { // APAction defines action related information used within a ActionProfile type APAction struct { - ID string // Action ID - FilterIDs []string // Action FilterIDs - Blocker bool // Blocker will stop further actions running in the chain - TTL time.Duration // Cancel Action if not executed within TTL - Type string // Type of Action - Opts map[string]interface{} // Extra options to pass depending on action type - ActionDiktats []*ActionDiktat + ID string // Action ID + FilterIDs []string // Action FilterIDs + Blocker bool // Blocker will stop further actions running in the chain + TTL time.Duration // Cancel Action if not executed within TTL + Type string // Type of Action + Opts map[string]interface{} // Extra options to pass depending on action type + Diktats []*APDiktat } -type ActionDiktat struct { +type APDiktat struct { Path string // Path to execute Value config.RSRParsers // Value to execute on path } diff --git a/engine/cdrs.go b/engine/cdrs.go index dde5ca957..b11099bc2 100644 --- a/engine/cdrs.go +++ b/engine/cdrs.go @@ -1041,8 +1041,8 @@ func (cdrS *CDRServer) V1RateCDRs(arg *ArgRateCDRs, reply *string) (err error) { thdS = flgs.GetBool(utils.MetaThresholds) } statS := len(cdrS.cgrCfg.CdrsCfg().StatSConns) != 0 - if flgs.Has(utils.MetaStatS) { - statS = flgs.GetBool(utils.MetaStatS) + if flgs.Has(utils.MetaStats) { + statS = flgs.GetBool(utils.MetaStats) } chrgS := len(cdrS.cgrCfg.CdrsCfg().ChargerSConns) != 0 if flgs.Has(utils.MetaChargers) { diff --git a/engine/libtest.go b/engine/libtest.go index cc19b08ec..e23b16b9e 100644 --- a/engine/libtest.go +++ b/engine/libtest.go @@ -290,12 +290,12 @@ cgrates.org,RP1,,,,,,,RT_CHRISTMAS,,* * 24 12 *,;30,false,0s,0.0564,0.06,1m,1s ` ActionProfileCSVContent = ` #Tenant,ID,FilterIDs,ActivationInterval,Weight,Schedule,TargetType,TargetIDs,ActionID,ActionFilterIDs,ActionBlocker,ActionTTL,ActionType,ActionOpts,ActionPath,ActionValue -cgrates.org,ONE_TIME_ACT,,,10,*asap,*accounts,1001;1002,TOPUP,,false,0s,*add_balance,,~*balance.TestBalance.Value,10 -cgrates.org,ONE_TIME_ACT,,,,,,,SET_BALANCE_TEST_DATA,,false,0s,*set_balance,,~*balance.TestDataBalance.Type,*data -cgrates.org,ONE_TIME_ACT,,,,,,,TOPUP_TEST_DATA,,false,0s,*add_balance,,~*balance.TestDataBalance.Value,1024 -cgrates.org,ONE_TIME_ACT,,,,,,,SET_BALANCE_TEST_VOICE,,false,0s,*set_balance,,~*balance.TestVoiceBalance.Type,*voice -cgrates.org,ONE_TIME_ACT,,,,,,,TOPUP_TEST_VOICE,,false,0s,*add_balance,,~*balance.TestVoiceBalance.Value,15m15s -cgrates.org,ONE_TIME_ACT,,,,,,,TOPUP_TEST_VOICE,,false,0s,*add_balance,,~*balance.TestVoiceBalance2.Value,15m15s +cgrates.org,ONE_TIME_ACT,,,10,*asap,*accounts,1001;1002,TOPUP,,false,0s,*add_balance,,*balance.TestBalance.Value,10 +cgrates.org,ONE_TIME_ACT,,,,,,,SET_BALANCE_TEST_DATA,,false,0s,*set_balance,,*balance.TestDataBalance.Type,*data +cgrates.org,ONE_TIME_ACT,,,,,,,TOPUP_TEST_DATA,,false,0s,*add_balance,,*balance.TestDataBalance.Value,1024 +cgrates.org,ONE_TIME_ACT,,,,,,,SET_BALANCE_TEST_VOICE,,false,0s,*set_balance,,*balance.TestVoiceBalance.Type,*voice +cgrates.org,ONE_TIME_ACT,,,,,,,TOPUP_TEST_VOICE,,false,0s,*add_balance,,*balance.TestVoiceBalance.Value,15m15s +cgrates.org,ONE_TIME_ACT,,,,,,,TOPUP_TEST_VOICE,,false,0s,*add_balance,,*balance.TestVoiceBalance2.Value,15m15s ` AccountProfileCSVContent = ` diff --git a/engine/loader_csv_test.go b/engine/loader_csv_test.go index 008777299..4dbb11d15 100644 --- a/engine/loader_csv_test.go +++ b/engine/loader_csv_test.go @@ -1495,7 +1495,7 @@ func TestLoadActionProfiles(t *testing.T) { TTL: "0s", Type: "*add_balance", ActionDiktats: []*utils.TPActionDiktat{{ - Path: "~*balance.TestBalance.Value", + Path: "*balance.TestBalance.Value", Value: "10", }}, }, @@ -1504,7 +1504,7 @@ func TestLoadActionProfiles(t *testing.T) { TTL: "0s", Type: "*set_balance", ActionDiktats: []*utils.TPActionDiktat{{ - Path: "~*balance.TestDataBalance.Type", + Path: "*balance.TestDataBalance.Type", Value: "*data", }}, }, @@ -1513,7 +1513,7 @@ func TestLoadActionProfiles(t *testing.T) { TTL: "0s", Type: "*add_balance", ActionDiktats: []*utils.TPActionDiktat{{ - Path: "~*balance.TestDataBalance.Value", + Path: "*balance.TestDataBalance.Value", Value: "1024", }}, }, @@ -1522,7 +1522,7 @@ func TestLoadActionProfiles(t *testing.T) { TTL: "0s", Type: "*set_balance", ActionDiktats: []*utils.TPActionDiktat{{ - Path: "~*balance.TestVoiceBalance.Type", + Path: "*balance.TestVoiceBalance.Type", Value: "*voice", }}, }, @@ -1531,10 +1531,10 @@ func TestLoadActionProfiles(t *testing.T) { TTL: "0s", Type: "*add_balance", ActionDiktats: []*utils.TPActionDiktat{{ - Path: "~*balance.TestVoiceBalance.Value", + Path: "*balance.TestVoiceBalance.Value", Value: "15m15s", }, { - Path: "~*balance.TestVoiceBalance2.Value", + Path: "*balance.TestVoiceBalance2.Value", Value: "15m15s", }}, }, diff --git a/engine/model_helpers.go b/engine/model_helpers.go index 4d7b0bd1b..a2baec1e4 100644 --- a/engine/model_helpers.go +++ b/engine/model_helpers.go @@ -3354,23 +3354,23 @@ func APItoActionProfile(tpAp *utils.TPActionProfile, timezone string) (ap *Actio ap.Targets[target.TargetType] = utils.NewStringSet(target.TargetIDs) } for i, act := range tpAp.Actions { - actDs := make([]*ActionDiktat, len(act.ActionDiktats)) + actDs := make([]*APDiktat, len(act.ActionDiktats)) for j, actD := range act.ActionDiktats { var val config.RSRParsers if val, err = config.NewRSRParsers(actD.Value, config.CgrConfig().GeneralCfg().RSRSep); err != nil { return } - actDs[j] = &ActionDiktat{ + actDs[j] = &APDiktat{ Path: actD.Path, Value: val, } } ap.Actions[i] = &APAction{ - ID: act.ID, - FilterIDs: act.FilterIDs, - Blocker: act.Blocker, - Type: act.Type, - ActionDiktats: actDs, + ID: act.ID, + FilterIDs: act.FilterIDs, + Blocker: act.Blocker, + Type: act.Type, + Diktats: actDs, } if ap.Actions[i].TTL, err = utils.ParseDurationWithNanosecs(act.TTL); err != nil { return @@ -3417,8 +3417,8 @@ func ActionProfileToAPI(ap *ActionProfile) (tpAp *utils.TPActionProfile) { tpAp.Targets = append(tpAp.Targets, &utils.TPActionTarget{TargetType: targetType, TargetIDs: targetIDs.AsSlice()}) } for i, act := range ap.Actions { - actDs := make([]*utils.TPActionDiktat, len(act.ActionDiktats)) - for j, actD := range act.ActionDiktats { + actDs := make([]*utils.TPActionDiktat, len(act.Diktats)) + for j, actD := range act.Diktats { actDs[j] = &utils.TPActionDiktat{ Path: actD.Path, Value: actD.Value.GetRule(config.CgrConfig().GeneralCfg().RSRSep), @@ -3501,9 +3501,7 @@ func (tps AccountProfileMdls) AsTPAccountProfile() (result []*utils.TPAccountPro } if tp.BalanceFilterIDs != utils.EmptyString { - filterIDs := make(utils.StringSet) - filterIDs.AddSlice(strings.Split(tp.BalanceFilterIDs, utils.InfieldSep)) - aPrf.Balances[tp.BalanceID].FilterIDs = filterIDs.AsSlice() + aPrf.Balances[tp.BalanceID].FilterIDs = utils.NewStringSet(strings.Split(tp.BalanceFilterIDs, utils.InfieldSep)).AsSlice() } if tp.BalanceCostIncrements != utils.EmptyString { costIncrements := make([]*utils.TPBalanceCostIncrement, 0) @@ -3521,14 +3519,14 @@ func (tps AccountProfileMdls) AsTPAccountProfile() (result []*utils.TPAccountPro aPrf.Balances[tp.BalanceID].CostIncrement = costIncrements } if tp.BalanceAttributeIDs != utils.EmptyString { - attributeIDs := make(utils.StringSet) - attributeIDs.AddSlice(strings.Split(tp.BalanceAttributeIDs, utils.InfieldSep)) - aPrf.Balances[tp.BalanceID].AttributeIDs = attributeIDs.AsSlice() + // the order for attributes is important + // also no duplicate check as we would + // need to let the user execute the same + // attribute twice if needed + aPrf.Balances[tp.BalanceID].AttributeIDs = strings.Split(tp.BalanceAttributeIDs, utils.InfieldSep) } if tp.BalanceRateProfileIDs != utils.EmptyString { - rateProfileIDs := make(utils.StringSet) - rateProfileIDs.AddSlice(strings.Split(tp.BalanceRateProfileIDs, utils.InfieldSep)) - aPrf.Balances[tp.BalanceID].RateProfileIDs = rateProfileIDs.AsSlice() + aPrf.Balances[tp.BalanceID].RateProfileIDs = utils.NewStringSet(strings.Split(tp.BalanceRateProfileIDs, utils.InfieldSep)).AsSlice() } if tp.BalanceUnitFactors != utils.EmptyString { unitFactors := make([]*utils.TPBalanceUnitFactor, 0) diff --git a/engine/model_helpers_test.go b/engine/model_helpers_test.go index 5cbb05bc4..bf8b9c58f 100644 --- a/engine/model_helpers_test.go +++ b/engine/model_helpers_test.go @@ -5820,7 +5820,7 @@ func TestModelHelpersAPItoActionProfile(t *testing.T) { { ID: "test_action_id", FilterIDs: []string{"test_action_filter_id1", "test_action_filter_id2"}, - ActionDiktats: []*ActionDiktat{{ + Diktats: []*APDiktat{{ Path: "test_path", }}, Opts: map[string]interface{}{ @@ -5969,7 +5969,7 @@ func TestModelHelpersActionProfileToAPI(t *testing.T) { ID: "test_action_id", FilterIDs: []string{"test_action_filter_id1", "test_action_filter_id2"}, TTL: time.Second, - ActionDiktats: []*ActionDiktat{{ + Diktats: []*APDiktat{{ Path: "test_path", }}, Opts: map[string]interface{}{ diff --git a/engine/units_counter.go b/engine/units_counter.go index b0f2a5fce..6ff9db713 100644 --- a/engine/units_counter.go +++ b/engine/units_counter.go @@ -125,7 +125,7 @@ func (ucs UnitCounters) addUnits(amount float64, kind string, cc *CallCost, b *B continue } - if uc.CounterType == utils.MetaCounterBalance && b != nil && b.MatchFilter(c.Filter, true, false) { + if uc.CounterType == utils.MetaBalance && b != nil && b.MatchFilter(c.Filter, true, false) { c.Value += amount continue } diff --git a/engine/z_onstor_it_test.go b/engine/z_onstor_it_test.go index 24ccd3c69..ac5eccf29 100644 --- a/engine/z_onstor_it_test.go +++ b/engine/z_onstor_it_test.go @@ -2253,7 +2253,7 @@ func testOnStorITActionProfile(t *testing.T) { ID: "TOPUP", FilterIDs: []string{}, Type: "*topup", - ActionDiktats: []*ActionDiktat{{ + Diktats: []*APDiktat{{ Path: "~*balance.TestBalance.Value", }}, }, @@ -2261,7 +2261,7 @@ func testOnStorITActionProfile(t *testing.T) { ID: "TOPUP_TEST_VOICE", FilterIDs: []string{}, Type: "*topup", - ActionDiktats: []*ActionDiktat{{ + Diktats: []*APDiktat{{ Path: "~*balance.TestVoiceBalance.Value", }}, }, diff --git a/general_tests/attributes_it_test.go b/general_tests/attributes_it_test.go index 2265d1971..0c45f90f4 100644 --- a/general_tests/attributes_it_test.go +++ b/general_tests/attributes_it_test.go @@ -39,7 +39,6 @@ var ( attrCfgPath string attrCfg *config.CGRConfig attrRPC *rpc.Client - attrDataDir = "/usr/share/cgrates" alsPrfConfigDIR string sTestsAlsPrf = []func(t *testing.T){ testAttributeSInitCfg, @@ -83,12 +82,12 @@ func TestAttributeSIT(t *testing.T) { func testAttributeSInitCfg(t *testing.T) { var err error - attrCfgPath = path.Join(attrDataDir, "conf", "samples", alsPrfConfigDIR) + attrCfgPath = path.Join(*dataDir, "conf", "samples", alsPrfConfigDIR) attrCfg, err = config.NewCGRConfigFromPath(attrCfgPath) if err != nil { t.Error(err) } - attrCfg.DataFolderPath = attrDataDir // Share DataFolderPath through config towards StoreDb for Flush() + attrCfg.DataFolderPath = *dataDir // Share DataFolderPath through config towards StoreDb for Flush() } func testAttributeSInitDataDb(t *testing.T) { diff --git a/general_tests/cdrs_processevent_it_test.go b/general_tests/cdrs_processevent_it_test.go index 9291edd91..c8c247338 100644 --- a/general_tests/cdrs_processevent_it_test.go +++ b/general_tests/cdrs_processevent_it_test.go @@ -318,7 +318,7 @@ func testV1CDRsProcessEventRalS(t *testing.T) { func testV1CDRsProcessEventSts(t *testing.T) { argsEv := &engine.ArgV1ProcessEvent{ - Flags: []string{utils.MetaStatS, "*rals:false", "*attributes:false", "*chargers:false", "*export:false"}, + Flags: []string{utils.MetaStats, "*rals:false", "*attributes:false", "*chargers:false", "*export:false"}, CGREvent: utils.CGREvent{ Tenant: "cgrates.org", ID: "test4", diff --git a/general_tests/export_it_test.go b/general_tests/export_it_test.go index bfa530591..2a3d63f2d 100644 --- a/general_tests/export_it_test.go +++ b/general_tests/export_it_test.go @@ -434,14 +434,14 @@ func testExpVerifyActionProfiles(t *testing.T) { Weight: 10, Schedule: utils.MetaASAP, Targets: map[string]utils.StringSet{ - utils.MetaAccounts: utils.StringSet{"1001": {}, "1002": {}}, + utils.MetaAccounts: {"1001": {}, "1002": {}}, }, Actions: []*engine.APAction{ { ID: "TOPUP", Type: utils.MetaTopUp, - ActionDiktats: []*engine.ActionDiktat{{ - Path: utils.DynamicDataPrefix + utils.MetaCounterBalance + utils.NestingSep + "TestBalance" + utils.NestingSep + utils.Value, + Diktats: []*engine.APDiktat{{ + Path: utils.DynamicDataPrefix + utils.MetaBalance + utils.NestingSep + "TestBalance" + utils.NestingSep + utils.Value, Value: config.NewRSRParsersMustCompile("10", utils.InfieldSep), }}, }, @@ -449,32 +449,32 @@ func testExpVerifyActionProfiles(t *testing.T) { { ID: "SET_BALANCE_TEST_DATA", Type: utils.MetaSetBalance, - ActionDiktats: []*engine.ActionDiktat{{ - Path: utils.DynamicDataPrefix + utils.MetaCounterBalance + utils.NestingSep + "TestDataBalance" + utils.NestingSep + utils.Type, + Diktats: []*engine.APDiktat{{ + Path: utils.DynamicDataPrefix + utils.MetaBalance + utils.NestingSep + "TestDataBalance" + utils.NestingSep + utils.Type, Value: config.NewRSRParsersMustCompile(utils.MetaData, utils.InfieldSep), }}, }, { ID: "TOPUP_TEST_DATA", Type: utils.MetaTopUp, - ActionDiktats: []*engine.ActionDiktat{{ - Path: utils.DynamicDataPrefix + utils.MetaCounterBalance + utils.NestingSep + "TestDataBalance" + utils.NestingSep + utils.Value, + Diktats: []*engine.APDiktat{{ + Path: utils.DynamicDataPrefix + utils.MetaBalance + utils.NestingSep + "TestDataBalance" + utils.NestingSep + utils.Value, Value: config.NewRSRParsersMustCompile("1024", utils.InfieldSep), }}, }, { ID: "SET_BALANCE_TEST_VOICE", Type: utils.MetaSetBalance, - ActionDiktats: []*engine.ActionDiktat{{ - Path: utils.DynamicDataPrefix + utils.MetaCounterBalance + utils.NestingSep + "TestVoiceBalance" + utils.NestingSep + utils.Type, + Diktats: []*engine.APDiktat{{ + Path: utils.DynamicDataPrefix + utils.MetaBalance + utils.NestingSep + "TestVoiceBalance" + utils.NestingSep + utils.Type, Value: config.NewRSRParsersMustCompile(utils.MetaVoice, utils.InfieldSep), }}, }, { ID: "TOPUP_TEST_VOICE", Type: utils.MetaTopUp, - ActionDiktats: []*engine.ActionDiktat{{ - Path: utils.DynamicDataPrefix + utils.MetaCounterBalance + utils.NestingSep + "TestVoiceBalance" + utils.NestingSep + utils.Value, + Diktats: []*engine.APDiktat{{ + Path: utils.DynamicDataPrefix + utils.MetaBalance + utils.NestingSep + "TestVoiceBalance" + utils.NestingSep + utils.Value, Value: config.NewRSRParsersMustCompile("15m15s", utils.InfieldSep), }}, }, @@ -491,7 +491,7 @@ func testExpVerifyActionProfiles(t *testing.T) { t.Fatal(err) } else { for _, act := range reply.Actions { // the path variable from RSRParsers is with lower letter and need to be compiled manually in tests to pass reflect.DeepEqual - for _, actD := range act.ActionDiktats { + for _, actD := range act.Diktats { actD.Value.Compile() } } diff --git a/loaders/loader_test.go b/loaders/loader_test.go index 1168e3acf..5207f92f1 100644 --- a/loaders/loader_test.go +++ b/loaders/loader_test.go @@ -797,7 +797,7 @@ not_a_valid_metric_type,true, if err := ldr.processContent(utils.MetaStats, utils.EmptyString); err == nil || err.Error() != expected { t.Errorf("Expected %+v, received %+v", expected, err) } - if err := ldr.removeContent(utils.MetaStatS, utils.EmptyString); err != nil { + if err := ldr.removeContent(utils.MetaStats, utils.EmptyString); err != nil { t.Error(err) } @@ -817,7 +817,7 @@ not_a_valid_metric_type,true, if err := ldr.processContent(utils.MetaStats, utils.EmptyString); err != nil { t.Error(err) } - if err := ldr.removeContent(utils.MetaStatS, utils.EmptyString); err != nil { + if err := ldr.removeContent(utils.MetaStats, utils.EmptyString); err != nil { t.Error(err) } } @@ -2545,43 +2545,43 @@ func TestLoaderActionProfile(t *testing.T) { { ID: "TOPUP", Type: "*add_balance", - ActionDiktats: []*engine.ActionDiktat{{ - Path: "~*balance.TestBalance.Value", + Diktats: []*engine.APDiktat{{ + Path: "*balance.TestBalance.Value", Value: config.NewRSRParsersMustCompile("10", utils.InfieldSep), }}, }, { ID: "SET_BALANCE_TEST_DATA", Type: "*set_balance", - ActionDiktats: []*engine.ActionDiktat{{ - Path: "~*balance.TestDataBalance.Type", + Diktats: []*engine.APDiktat{{ + Path: "*balance.TestDataBalance.Type", Value: config.NewRSRParsersMustCompile("*data", utils.InfieldSep), }}, }, { ID: "TOPUP_TEST_DATA", Type: "*add_balance", - ActionDiktats: []*engine.ActionDiktat{{ - Path: "~*balance.TestDataBalance.Value", + Diktats: []*engine.APDiktat{{ + Path: "*balance.TestDataBalance.Value", Value: config.NewRSRParsersMustCompile("1024", utils.InfieldSep), }}, }, { ID: "SET_BALANCE_TEST_VOICE", Type: "*set_balance", - ActionDiktats: []*engine.ActionDiktat{{ - Path: "~*balance.TestVoiceBalance.Type", + Diktats: []*engine.APDiktat{{ + Path: "*balance.TestVoiceBalance.Type", Value: config.NewRSRParsersMustCompile("*voice", utils.InfieldSep), }}, }, { ID: "TOPUP_TEST_VOICE", Type: "*add_balance", - ActionDiktats: []*engine.ActionDiktat{{ - Path: "~*balance.TestVoiceBalance.Value", + Diktats: []*engine.APDiktat{{ + Path: "*balance.TestVoiceBalance.Value", Value: config.NewRSRParsersMustCompile("15m15s", utils.InfieldSep), }, { - Path: "~*balance.TestVoiceBalance2.Value", + Path: "*balance.TestVoiceBalance2.Value", Value: config.NewRSRParsersMustCompile("15m15s", utils.InfieldSep), }}, }, @@ -2706,11 +2706,11 @@ func TestLoaderWrongCsv(t *testing.T) { //Not a valid comment beginning of csv newCSVContentMiss := ` //Tenant,ID,FilterIDs,ActivationInterval,Weight,Schedule,AccountIDs,ActionID,ActionFilterIDs,ActionBLocker,ActionTTL,ActionType,ActionOpts,ActionPath,ActionValue -cgrates.org,ONE_TIME_ACT,,,10,*asap,1001;1002,TOPUP,,false,0s,*topup,,~*balance.TestBalance.Value,10 -cgrates.org,ONE_TIME_ACT,,,,,,SET_BALANCE_TEST_DATA,,false,0s,*set_balance,,~*balance.TestDataBalance.Type,*data -cgrates.org,ONE_TIME_ACT,,,,,,TOPUP_TEST_DATA,,false,0s,*topup,,~*balance.TestDataBalance.Value,1024 -cgrates.org,ONE_TIME_ACT,,,,,,SET_BALANCE_TEST_VOICE,,false,0s,*set_balance,,~*balance.TestVoiceBalance.Type,*voice -cgrates.org,ONE_TIME_ACT,,,,,,TOPUP_TEST_VOICE,,false,0s,*topup,,~*balance.TestVoiceBalance.Value,15m15s +cgrates.org,ONE_TIME_ACT,,,10,*asap,1001;1002,TOPUP,,false,0s,*add_balance,,*balance.TestBalance.Value,10 +cgrates.org,ONE_TIME_ACT,,,,,,SET_BALANCE_TEST_DATA,,false,0s,*set_balance,,*balance.TestDataBalance.Type,*data +cgrates.org,ONE_TIME_ACT,,,,,,TOPUP_TEST_DATA,,false,0s,*add_balance,,*balance.TestDataBalance.Value,1024 +cgrates.org,ONE_TIME_ACT,,,,,,SET_BALANCE_TEST_VOICE,,false,0s,*set_balance,,*balance.TestVoiceBalance.Type,*voice +cgrates.org,ONE_TIME_ACT,,,,,,TOPUP_TEST_VOICE,,false,0s,*add_balance,,*balance.TestVoiceBalance.Value,15m15s ` rdr := ioutil.NopCloser(strings.NewReader(newCSVContentMiss)) @@ -2732,11 +2732,11 @@ cgrates.org,ONE_TIME_ACT,,,,,,TOPUP_TEST_VOICE,,false,0s,*topup,,~*balance.TestV //Missing fields in csv eg:ActionBLocker newCSVContent := ` //Tenant,ID,FilterIDs,ActivationInterval,Weight,Schedule,AccountIDs,ActionID,ActionFilterIDs,ActionTTL,ActionType,ActionOpts,ActionPath,ActionValue -cgrates.org,ONE_TIME_ACT,,,10,*asap,1001;1002,TOPUP,,false,0s,*topup,,~*balance.TestBalance.Value,10 -cgrates.org,ONE_TIME_ACT,,,,,,SET_BALANCE_TEST_DATA,,false,0s,*set_balance,,~*balance.TestDataBalance.Type,*data -cgrates.org,ONE_TIME_ACT,,,,,,TOPUP_TEST_DATA,,false,0s,*topup,,~*balance.TestDataBalance.Value,1024 -cgrates.org,ONE_TIME_ACT,,,,,,SET_BALANCE_TEST_VOICE,,false,0s,*set_balance,,~*balance.TestVoiceBalance.Type,*voice -cgrates.org,ONE_TIME_ACT,,,,,,TOPUP_TEST_VOICE,,false,0s,*topup,,~*balance.TestVoiceBalance.Value,15m15s +cgrates.org,ONE_TIME_ACT,,,10,*asap,1001;1002,TOPUP,,false,0s,*add_balance,,*balance.TestBalance.Value,10 +cgrates.org,ONE_TIME_ACT,,,,,,SET_BALANCE_TEST_DATA,,false,0s,*set_balance,,*balance.TestDataBalance.Type,*data +cgrates.org,ONE_TIME_ACT,,,,,,TOPUP_TEST_DATA,,false,0s,*add_balance,,*balance.TestDataBalance.Value,1024 +cgrates.org,ONE_TIME_ACT,,,,,,SET_BALANCE_TEST_VOICE,,false,0s,*set_balance,,*balance.TestVoiceBalance.Type,*voice +cgrates.org,ONE_TIME_ACT,,,,,,TOPUP_TEST_VOICE,,false,0s,*add_balance,,*balance.TestVoiceBalance.Value,15m15s ` rdr = ioutil.NopCloser(strings.NewReader(newCSVContent)) csvRdr = csv.NewReader(rdr) @@ -3074,7 +3074,7 @@ NOT_UINT rdrCsv := csv.NewReader(rdr) rdrCsv.Comment = '#' ldr.rdrs = map[string]map[string]*openedCSVFile{ - utils.MetaStatS: { + utils.MetaStats: { utils.StatsCsv: &openedCSVFile{ fileName: utils.StatsCsv, rdr: rdr, @@ -3083,7 +3083,7 @@ NOT_UINT }, } expectedErr := "cannot update unsupported struct field: 0" - if err := ldr.processContent(utils.MetaStatS, utils.EmptyString); err == nil || err.Error() != expectedErr { + if err := ldr.processContent(utils.MetaStats, utils.EmptyString); err == nil || err.Error() != expectedErr { t.Errorf("Expected %+v, received %+v", expectedErr, err) } } @@ -3112,7 +3112,7 @@ func TestLoadStatsAsStructErrConversion(t *testing.T) { rdrCsv := csv.NewReader(rdr) rdrCsv.Comment = '#' ldr.rdrs = map[string]map[string]*openedCSVFile{ - utils.MetaStatS: { + utils.MetaStats: { utils.StatsCsv: &openedCSVFile{ fileName: utils.StatsCsv, rdr: rdr, @@ -3121,7 +3121,7 @@ func TestLoadStatsAsStructErrConversion(t *testing.T) { }, } expectedErr := "Unsupported time format" - if err := ldr.processContent(utils.MetaStatS, utils.EmptyString); err == nil || err.Error() != expectedErr { + if err := ldr.processContent(utils.MetaStats, utils.EmptyString); err == nil || err.Error() != expectedErr { t.Errorf("Expected %+v, received %+v", expectedErr, err) } } @@ -3928,7 +3928,7 @@ cgrates.org,REM_STATS_1 csvRdr := csv.NewReader(rdr) csvRdr.Comment = '#' ldr.rdrs = map[string]map[string]*openedCSVFile{ - utils.MetaStatS: { + utils.MetaStats: { utils.StatsCsv: &openedCSVFile{ fileName: utils.StatsCsv, rdr: rdr, @@ -3943,12 +3943,12 @@ cgrates.org,REM_STATS_1 if err := ldr.dm.SetStatQueueProfile(expStats, true); err != nil { t.Error(err) } - if err := ldr.removeContent(utils.MetaStatS, utils.EmptyString); err != nil { + if err := ldr.removeContent(utils.MetaStats, utils.EmptyString); err != nil { t.Error(err) } //nothing to remove from database - if err := ldr.removeContent(utils.MetaStatS, utils.EmptyString); err != utils.ErrNotFound { + if err := ldr.removeContent(utils.MetaStats, utils.EmptyString); err != utils.ErrNotFound { t.Error(err) } @@ -3958,7 +3958,7 @@ cgrates.org,REM_STATS_1 csvRdr = csv.NewReader(rdr) csvRdr.Comment = '#' ldr.rdrs = map[string]map[string]*openedCSVFile{ - utils.MetaStatS: { + utils.MetaStats: { utils.StatsCsv: &openedCSVFile{ fileName: utils.StatsCsv, rdr: rdr, @@ -3966,7 +3966,7 @@ cgrates.org,REM_STATS_1 }, }, } - if err := ldr.removeContent(utils.MetaStatS, utils.EmptyString); err != nil { + if err := ldr.removeContent(utils.MetaStats, utils.EmptyString); err != nil { t.Error(err) } @@ -3977,7 +3977,7 @@ cgrates.org,REM_STATS_1 csvRdr = csv.NewReader(rdr) csvRdr.Comment = '#' ldr.rdrs = map[string]map[string]*openedCSVFile{ - utils.MetaStatS: { + utils.MetaStats: { utils.StatsCsv: &openedCSVFile{ fileName: utils.StatsCsv, rdr: rdr, @@ -5049,7 +5049,7 @@ cgrates.org,REM_STATS_1 csvRdr := csv.NewReader(rdr) csvRdr.Comment = '#' ldr.rdrs = map[string]map[string]*openedCSVFile{ - utils.MetaStatS: { + utils.MetaStats: { utils.StatsCsv: &openedCSVFile{ fileName: utils.StatsCsv, rdr: rdr, @@ -5070,9 +5070,9 @@ cgrates.org,REM_STATS_1 ldr.dm = engine.NewDataManager(newData, config.CgrConfig().CacheCfg(), nil) expected := "NO_DATA_BASE_CONNECTION" - if err := ldr.removeContent(utils.MetaStatS, utils.EmptyString); err == nil || err.Error() != expected { + if err := ldr.removeContent(utils.MetaStats, utils.EmptyString); err == nil || err.Error() != expected { t.Errorf("Expected %+v, received %+v", expected, err) - } else if err := ldr.processContent(utils.MetaStatS, utils.EmptyString); err == nil || err.Error() != expected { + } else if err := ldr.processContent(utils.MetaStats, utils.EmptyString); err == nil || err.Error() != expected { t.Errorf("Expected %+v, received %+v", expected, err) } } diff --git a/migrator/actionprofiles_it_test.go b/migrator/actionprofiles_it_test.go index 7f3376822..d2e7f7694 100644 --- a/migrator/actionprofiles_it_test.go +++ b/migrator/actionprofiles_it_test.go @@ -196,7 +196,7 @@ func testActPrfMigrateAndMove(t *testing.T) { ID: "TOPUP", FilterIDs: []string{}, Type: "*topup", - ActionDiktats: []*engine.ActionDiktat{{ + Diktats: []*engine.APDiktat{{ Path: "~*balance.TestBalance.Value", }}, }, @@ -204,7 +204,7 @@ func testActPrfMigrateAndMove(t *testing.T) { ID: "TOPUP_TEST_VOICE", FilterIDs: []string{}, Type: "*topup", - ActionDiktats: []*engine.ActionDiktat{{ + Diktats: []*engine.APDiktat{{ Path: "~*balance.TestVoiceBalance.Value", }}, }, diff --git a/migrator/filters.go b/migrator/filters.go index bfa04972b..b4079abda 100644 --- a/migrator/filters.go +++ b/migrator/filters.go @@ -59,7 +59,7 @@ func (m *Migrator) migrateCurrentRequestFilter() (err error) { return } -var filterTypes = utils.NewStringSet([]string{utils.MetaRSR, utils.MetaStatS, utils.MetaResources, +var filterTypes = utils.NewStringSet([]string{utils.MetaRSR, utils.MetaStats, utils.MetaResources, utils.MetaNotRSR, utils.MetaNotStatS, utils.MetaNotResources}) func migrateFilterV1(fl *v1Filter) (fltr *engine.Filter) { diff --git a/services/analyzers_it_test.go b/services/analyzers_it_test.go index 9095ed8e7..f1d528301 100644 --- a/services/analyzers_it_test.go +++ b/services/analyzers_it_test.go @@ -123,6 +123,9 @@ func TestAnalyzerSReload2(t *testing.T) { close(anz.stopChan) anz.start() anz.anz = nil + if err := os.RemoveAll("/tmp/analyzers"); err != nil { + t.Fatal(err) + } } func TestAnalyzerSReload3(t *testing.T) { diff --git a/utils/accountprofile.go b/utils/accountprofile.go index 942e8d83f..24bbdcfd7 100644 --- a/utils/accountprofile.go +++ b/utils/accountprofile.go @@ -19,9 +19,7 @@ along with this program. If not, see package utils import ( - "fmt" "sort" - "strings" "time" "github.com/ericlagergren/decimal" @@ -482,88 +480,22 @@ func (ext *APIUnitFactor) AsUnitFactor() *UnitFactor { } } -type ArgsUpdateBalance struct { +type ArgsActSetBalance struct { Tenant string AccountID string - Params []*ArgsBalParams + Diktats []*BalDiktat Reset bool + Opts map[string]interface{} } -type ArgsBalParams struct { +type BalDiktat struct { Path string Value string } -func (ap *AccountProfile) Set(path []string, value interface{}) (err error) { - if len(path) == 0 { - return ErrWrongPath - } - // if len(path) == 1 { - // return - // } - switch path[0] { - case "*balance": - if len(path) < 3 { - return ErrWrongPath - } - return ap.Balances[path[1]].Set(path[2:], value) - default: - return ErrWrongPath - } -} - -func (bal *Balance) Set(path []string, value interface{}) (err error) { - if len(path) == 0 { - return ErrWrongPath - } - switch path[0] { - case "ID": - bal.ID = IfaceAsString(value) - case "FilterIDs": - var fltrsIDs []string - if fltrsIDs, err = IfaceAsSliceString(value); err != nil { - err = nil - fltrsIDs = NewStringSet(strings.Split(IfaceAsString(value), InfieldSep)).AsSlice() - } - bal.FilterIDs = fltrsIDs - case "Weights": - var wg DynamicWeights - if wg, err = NewDynamicWeightsFromString(IfaceAsString(value), InfieldSep, ANDSep); err != nil { - return - } - bal.Weights = wg - case "Type": - bal.Type = IfaceAsString(value) - case "Units": - switch vl := value.(type) { - case *Decimal: - bal.Units = vl - default: - z, ok := new(decimal.Big).SetString(IfaceAsString(value)) - if !ok { - return fmt.Errorf("can't convert <%+v> to decimal", value) - } - bal.Units.Big = z - } - case "UnitFactors": - case "Opts": - case "CostIncrements": - case "AttributeIDs": - var attrIDs []string - if attrIDs, err = IfaceAsSliceString(value); err != nil { - err = nil - attrIDs = NewStringSet(strings.Split(IfaceAsString(value), InfieldSep)).AsSlice() - } - bal.AttributeIDs = attrIDs - case "RateProfileIDs": - var rateIDs []string - if rateIDs, err = IfaceAsSliceString(value); err != nil { - err = nil - rateIDs = NewStringSet(strings.Split(IfaceAsString(value), InfieldSep)).AsSlice() - } - bal.RateProfileIDs = rateIDs - default: - return ErrWrongPath - } - return nil +type ArgsActRemoveBalances struct { + Tenant string + AccountID string + BalanceIDs []string + Opts map[string]interface{} } diff --git a/utils/consts.go b/utils/consts.go index 0f3a19226..2cd19a122 100755 --- a/utils/consts.go +++ b/utils/consts.go @@ -435,7 +435,7 @@ const ( MetaSureTax = "*sure_tax" MetaDynamic = "*dynamic" MetaCounterEvent = "*event" - MetaCounterBalance = "*balance" + MetaBalance = "*balance" EventName = "EventName" // action trigger threshold types TriggerMinEventCounter = "*min_event_counter" @@ -956,6 +956,15 @@ const ( MetaExporterIDs = "*exporterIDs" MetaAsync = "*async" MetaUsage = "*usage" + Weights = "Weights" + UnitFactors = "UnitFactors" + CostIncrements = "CostIncrements" + Factor = "Factor" + Increment = "Increment" + FixedFee = "FixedFee" + RecurrentFee = "RecurrentFee" + Diktats = "Diktats" + BalanceIDs = "BalanceIDs" ) // Migrator Action @@ -1060,7 +1069,6 @@ const ( MetaDenyNegative = "*deny_negative" MetaResetAccount = "*reset_account" MetaRemoveAccount = "*remove_account" - MetaSetBalance = "*set_balance" MetaRemoveBalance = "*remove_balance" MetaTopUpReset = "*topup_reset" MetaTopUp = "*topup" @@ -1092,6 +1100,10 @@ const ( BalanceValue = "BalanceValue" BalanceUnits = "BalanceUnits" ExtraParameters = "ExtraParameters" + + MetaAddBalance = "*add_balance" + MetaSetBalance = "*set_balance" + MetaRemBalance = "*rem_balance" ) // Migrator Metas @@ -1188,7 +1200,6 @@ const ( MetaExists = "*exists" MetaTimings = "*timings" MetaRSR = "*rsr" - MetaStatS = "*stats" MetaDestinations = "*destinations" MetaLessThan = "*lt" MetaLessOrEqual = "*lte" @@ -1570,6 +1581,8 @@ const ( AccountSv1AccountProfilesForEvent = "AccountSv1.AccountProfilesForEvent" AccountSv1MaxAbstracts = "AccountSv1.MaxAbstracts" AccountSv1DebitAbstracts = "AccountSv1.DebitAbstracts" + AccountSv1ActionSetBalance = "AccountSv1.ActionSetBalance" + AccountSv1ActionRemoveBalance = "AccountSv1.ActionRemoveBalance" ) const ( diff --git a/utils/decimal.go b/utils/decimal.go index 033aa0ed4..1d89b4f9d 100644 --- a/utils/decimal.go +++ b/utils/decimal.go @@ -20,6 +20,7 @@ package utils import ( "bytes" + "fmt" "strconv" "strings" "time" @@ -136,3 +137,11 @@ func (d *Decimal) Clone() *Decimal { func (d *Decimal) Compare(d2 *Decimal) int { return d.Big.Cmp(d2.Big) } + +func NewDecimalFromString(value string) (*Decimal, error) { + z, ok := new(decimal.Big).SetString(value) + if !ok { + return nil, fmt.Errorf("can't convert <%+v> to decimal", value) + } + return &Decimal{z}, nil +} diff --git a/utils/map_test.go b/utils/map_test.go index 3331f4d6c..1ded39e33 100644 --- a/utils/map_test.go +++ b/utils/map_test.go @@ -403,7 +403,7 @@ func TestFlagsWithParamsClone(t *testing.T) { MetaRoutes: nil, MetaThresholds: {MetaIDs: {"ID1", "ID2", "ID3"}, MetaDerivedReply: {}}, MetaAttributes: {"*disabled": {}}, - MetaStatS: {MetaIDs: {"ID"}}, + MetaStats: {MetaIDs: {"ID"}}, } cln := fWp.Clone()