mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Merge branch 'master' of https://github.com/cgrates/cgrates
This commit is contained in:
@@ -1467,12 +1467,12 @@ func TestApierLocalSetDC(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
dcs1 := utils.DerivedChargers{
|
||||
dcs1 := &utils.DerivedChargers{Chargers: []*utils.DerivedCharger{
|
||||
&utils.DerivedCharger{RunId: "extra1", ReqTypeField: "^prepaid", DirectionField: "*default", TenantField: "*default", CategoryField: "*default",
|
||||
AccountField: "rif", SubjectField: "rif", DestinationField: "*default", SetupTimeField: "*default", AnswerTimeField: "*default", UsageField: "*default"},
|
||||
&utils.DerivedCharger{RunId: "extra2", ReqTypeField: "*default", DirectionField: "*default", TenantField: "*default", CategoryField: "*default",
|
||||
AccountField: "ivo", SubjectField: "ivo", DestinationField: "*default", SetupTimeField: "*default", AnswerTimeField: "*default", UsageField: "*default"},
|
||||
}
|
||||
}}
|
||||
attrs := AttrSetDerivedChargers{Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "dan", Subject: "dan", DerivedChargers: dcs1}
|
||||
var reply string
|
||||
if err := rater.Call("ApierV1.SetDerivedChargers", attrs, &reply); err != nil {
|
||||
@@ -1487,12 +1487,12 @@ func TestApierLocalGetDC(t *testing.T) {
|
||||
return
|
||||
}
|
||||
attrs := utils.AttrDerivedChargers{Tenant: "cgrates.org", Category: "call", Direction: "*out", Account: "dan", Subject: "dan"}
|
||||
eDcs := utils.DerivedChargers{
|
||||
eDcs := utils.DerivedChargers{Chargers: []*utils.DerivedCharger{
|
||||
&utils.DerivedCharger{RunId: "extra1", ReqTypeField: "^prepaid", DirectionField: "*default", TenantField: "*default", CategoryField: "*default",
|
||||
AccountField: "rif", SubjectField: "rif", DestinationField: "*default", SetupTimeField: "*default", AnswerTimeField: "*default", UsageField: "*default"},
|
||||
&utils.DerivedCharger{RunId: "extra2", ReqTypeField: "*default", DirectionField: "*default", TenantField: "*default", CategoryField: "*default",
|
||||
AccountField: "ivo", SubjectField: "ivo", DestinationField: "*default", SetupTimeField: "*default", AnswerTimeField: "*default", UsageField: "*default"},
|
||||
}
|
||||
}}
|
||||
var dcs utils.DerivedChargers
|
||||
if err := rater.Call("ApierV1.GetDerivedChargers", attrs, &dcs); err != nil {
|
||||
t.Error("Unexpected error", err.Error())
|
||||
|
||||
@@ -33,15 +33,15 @@ func (self *ApierV1) GetDerivedChargers(attrs utils.AttrDerivedChargers, reply *
|
||||
if hDc, err := engine.HandleGetDerivedChargers(self.RatingDb, &attrs); err != nil {
|
||||
return utils.NewErrServerError(err)
|
||||
} else if hDc != nil {
|
||||
*reply = hDc
|
||||
*reply = *hDc
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type AttrSetDerivedChargers struct {
|
||||
Direction, Tenant, Category, Account, Subject string
|
||||
DerivedChargers utils.DerivedChargers
|
||||
Overwrite bool // Do not overwrite if present in redis
|
||||
Direction, Tenant, Category, Account, Subject, DestinationIds string
|
||||
DerivedChargers *utils.DerivedChargers
|
||||
Overwrite bool // Do not overwrite if present in redis
|
||||
}
|
||||
|
||||
func (self *ApierV1) SetDerivedChargers(attrs AttrSetDerivedChargers, reply *string) (err error) {
|
||||
@@ -60,7 +60,7 @@ func (self *ApierV1) SetDerivedChargers(attrs AttrSetDerivedChargers, reply *str
|
||||
if len(attrs.Subject) == 0 {
|
||||
attrs.Subject = utils.ANY
|
||||
}
|
||||
for _, dc := range attrs.DerivedChargers {
|
||||
for _, dc := range attrs.DerivedChargers.Chargers {
|
||||
if _, err = utils.ParseRSRFields(dc.RunFilters, utils.INFIELD_SEP); err != nil { // Make sure rules are OK before loading in db
|
||||
return fmt.Errorf("%s:%s", utils.ErrParserError.Error(), err.Error())
|
||||
}
|
||||
|
||||
@@ -48,12 +48,12 @@ func TestGetEmptyDC(t *testing.T) {
|
||||
*/
|
||||
|
||||
func TestSetDC(t *testing.T) {
|
||||
dcs1 := utils.DerivedChargers{
|
||||
dcs1 := &utils.DerivedChargers{Chargers: []*utils.DerivedCharger{
|
||||
&utils.DerivedCharger{RunId: "extra1", ReqTypeField: "^prepaid", DirectionField: "*default", TenantField: "*default", CategoryField: "*default",
|
||||
AccountField: "rif", SubjectField: "rif", DestinationField: "*default", SetupTimeField: "*default", AnswerTimeField: "*default", UsageField: "*default"},
|
||||
&utils.DerivedCharger{RunId: "extra2", ReqTypeField: "*default", DirectionField: "*default", TenantField: "*default", CategoryField: "*default",
|
||||
AccountField: "ivo", SubjectField: "ivo", DestinationField: "*default", SetupTimeField: "*default", AnswerTimeField: "*default", UsageField: "*default"},
|
||||
}
|
||||
}}
|
||||
attrs := AttrSetDerivedChargers{Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "dan", Subject: "dan", DerivedChargers: dcs1}
|
||||
var reply string
|
||||
if err := apierDcT.SetDerivedChargers(attrs, &reply); err != nil {
|
||||
@@ -65,12 +65,12 @@ func TestSetDC(t *testing.T) {
|
||||
|
||||
func TestGetDC(t *testing.T) {
|
||||
attrs := utils.AttrDerivedChargers{Tenant: "cgrates.org", Category: "call", Direction: "*out", Account: "dan", Subject: "dan"}
|
||||
eDcs := utils.DerivedChargers{
|
||||
eDcs := utils.DerivedChargers{Chargers: []*utils.DerivedCharger{
|
||||
&utils.DerivedCharger{RunId: "extra1", ReqTypeField: "^prepaid", DirectionField: "*default", TenantField: "*default", CategoryField: "*default",
|
||||
AccountField: "rif", SubjectField: "rif", DestinationField: "*default", SetupTimeField: "*default", AnswerTimeField: "*default", UsageField: "*default"},
|
||||
&utils.DerivedCharger{RunId: "extra2", ReqTypeField: "*default", DirectionField: "*default", TenantField: "*default", CategoryField: "*default",
|
||||
AccountField: "ivo", SubjectField: "ivo", DestinationField: "*default", SetupTimeField: "*default", AnswerTimeField: "*default", UsageField: "*default"},
|
||||
}
|
||||
}}
|
||||
var dcs utils.DerivedChargers
|
||||
if err := apierDcT.GetDerivedChargers(attrs, &dcs); err != nil {
|
||||
t.Error("Unexpected error", err.Error())
|
||||
|
||||
@@ -257,7 +257,7 @@ CREATE TABLE tp_lcr_rules (
|
||||
`subject` varchar(64) NOT NULL,
|
||||
`destination_tag` varchar(64) NOT NULL,
|
||||
`rp_category` varchar(32) NOT NULL,
|
||||
`strategy` varchar(16) NOT NULL,
|
||||
`strategy` varchar(18) NOT NULL,
|
||||
`strategy_params` varchar(256) NOT NULL,
|
||||
`activation_time` varchar(24) NOT NULL,
|
||||
`weight` DECIMAL(8,2) NOT NULL,
|
||||
@@ -280,6 +280,7 @@ CREATE TABLE tp_derived_chargers (
|
||||
`category` varchar(32) NOT NULL,
|
||||
`account` varchar(24) NOT NULL,
|
||||
`subject` varchar(64) NOT NULL,
|
||||
`destination_ids` varchar(64) NOT NULL,
|
||||
`runid` varchar(24) NOT NULL,
|
||||
`run_filters` varchar(256) NOT NULL,
|
||||
`req_type_field` varchar(24) NOT NULL,
|
||||
|
||||
@@ -252,7 +252,7 @@ CREATE TABLE tp_lcr_rules (
|
||||
subject VARCHAR(64) NOT NULL,
|
||||
destination_tag VARCHAR(64) NOT NULL,
|
||||
rp_category VARCHAR(32) NOT NULL,
|
||||
strategy VARCHAR(16) NOT NULL,
|
||||
strategy VARCHAR(18) NOT NULL,
|
||||
strategy_params VARCHAR(256) NOT NULL,
|
||||
activation_time VARCHAR(24) NOT NULL,
|
||||
weight NUMERIC(8,2) NOT NULL,
|
||||
@@ -275,6 +275,7 @@ CREATE TABLE tp_derived_chargers (
|
||||
category VARCHAR(32) NOT NULL,
|
||||
account VARCHAR(24) NOT NULL,
|
||||
subject VARCHAR(64) NOT NULL,
|
||||
destination_ids VARCHAR(64) NOT NULL,
|
||||
runid VARCHAR(24) NOT NULL,
|
||||
run_filters VARCHAR(256) NOT NULL,
|
||||
req_type_field VARCHAR(24) NOT NULL,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#Direction[0],Tenant[1],Category[2],Account[3],Subject[4],RunId[5],RunFilter[6],ReqTypeField[7],DirectionField[8],TenantField[9],CategoryField[10],AccountField[11],SubjectField[12],DestinationField[13],SetupTimeField[14],PddField[15],AnswerTimeField[16],UsageField[17],SupplierField[18],DisconnectCause[19],RatedField[20],CostField[21]
|
||||
*out,cgrates.org,call,dan,dan,extra1,,^prepaid,,,,^rif,^rif,,,,,^1s,*default,*default,*default,*default
|
||||
*out,cgrates.org,call,dan,dan,extra2,,,,,,^ivo,^ivo,,,,,,*default,*default,*default,*default
|
||||
*out,cgrates.org,call,dan,dan,extra3,~filterhdr1:s/(.+)/special_run3/,,,,,^runusr3,^runusr3,,,,,,*default,*default,*default,*default
|
||||
*out,cgrates.org,call,dan,*any,extra1,,,,,,^rif2,^rif2,,,,,,*default,*default,*default,*default
|
||||
#Direction[0],Tenant[1],Category[2],Account[3],Subject[4],DestinationIds[5],RunId[6],RunFilter[7],ReqTypeField[8],DirectionField[9],TenantField[10],CategoryField[11],AccountField[12],SubjectField[13],DestinationField[14],SetupTimeField[15],PddField[16],AnswerTimeField[17],UsageField[18],SupplierField[19],DisconnectCause[20],RatedField[21],CostField[22]
|
||||
*out,cgrates.org,call,dan,dan,,extra1,,^prepaid,,,,^rif,^rif,,,,,^1s,*default,*default,*default,*default
|
||||
*out,cgrates.org,call,dan,dan,,extra2,,,,,,^ivo,^ivo,,,,,,*default,*default,*default,*default
|
||||
*out,cgrates.org,call,dan,dan,,extra3,~filterhdr1:s/(.+)/special_run3/,,,,,^runusr3,^runusr3,,,,,,*default,*default,*default,*default
|
||||
*out,cgrates.org,call,dan,*any,,extra1,,,,,,^rif2,^rif2,,,,,,*default,*default,*default,*default
|
||||
|
||||
|
@@ -1,2 +1,2 @@
|
||||
#Direction[0],Tenant[1],Category[2],Account[3],Subject[4],RunId[5],RunFilter[6],ReqTypeField[7],DirectionField[8],TenantField[9],CategoryField[10],AccountField[11],SubjectField[12],DestinationField[13],SetupTimeField[14],PddField[15],AnswerTimeField[16],UsageField[17],SupplierField[18],DisconnectCause[19],RatedField[20],CostField[21]
|
||||
*out,cgrates.org,call,1001,1001,derived_run1,,^*rated,*default,*default,*default,*default,^1002,*default,*default,*default,*default,*default,*default,*default,*default,*default
|
||||
#Direction[0],Tenant[1],Category[2],Account[3],Subject[4],DestinationIds[5],RunId[6],RunFilter[7],ReqTypeField[8],DirectionField[9],TenantField[10],CategoryField[11],AccountField[12],SubjectField[13],DestinationField[14],SetupTimeField[15],PddField[16],AnswerTimeField[17],UsageField[18],SupplierField[19],DisconnectCause[20],RatedField[21],CostField[22]
|
||||
*out,cgrates.org,call,1001,1001,,derived_run1,,^*rated,*default,*default,*default,*default,^1002,*default,*default,*default,*default,*default,*default,*default,*default,*default
|
||||
|
||||
|
@@ -273,7 +273,7 @@ func (self *CdrServer) deriveCdrs(storedCdr *StoredCdr) ([]*StoredCdr, error) {
|
||||
utils.Logger.Err(fmt.Sprintf("Could not get derived charging for cgrid %s, error: %s", storedCdr.CgrId, err.Error()))
|
||||
return nil, err
|
||||
}
|
||||
for _, dc := range dcs {
|
||||
for _, dc := range dcs.Chargers {
|
||||
runFilters, _ := utils.ParseRSRFields(dc.RunFilters, utils.INFIELD_SEP)
|
||||
matchingAllFilters := true
|
||||
for _, dcRunFilter := range runFilters {
|
||||
|
||||
@@ -19,12 +19,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
package engine
|
||||
|
||||
import (
|
||||
"github.com/cgrates/cgrates/cache2go"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
// Handles retrieving of DerivedChargers profile based on longest match from AccountingDb
|
||||
func HandleGetDerivedChargers(ratingStorage RatingStorage, attrs *utils.AttrDerivedChargers) (utils.DerivedChargers, error) {
|
||||
var dcs utils.DerivedChargers
|
||||
func HandleGetDerivedChargers(ratingStorage RatingStorage, attrs *utils.AttrDerivedChargers) (*utils.DerivedChargers, error) {
|
||||
dcs := &utils.DerivedChargers{}
|
||||
strictKey := utils.DerivedChargersKey(attrs.Direction, attrs.Tenant, attrs.Category, attrs.Account, attrs.Subject)
|
||||
anySubjKey := utils.DerivedChargersKey(attrs.Direction, attrs.Tenant, attrs.Category, attrs.Account, utils.ANY)
|
||||
anyAcntKey := utils.DerivedChargersKey(attrs.Direction, attrs.Tenant, attrs.Category, utils.ANY, utils.ANY)
|
||||
@@ -33,10 +34,31 @@ func HandleGetDerivedChargers(ratingStorage RatingStorage, attrs *utils.AttrDeri
|
||||
for _, dcKey := range []string{strictKey, anySubjKey, anyAcntKey, anyCategKey, anyTenantKey} {
|
||||
if dcsDb, err := ratingStorage.GetDerivedChargers(dcKey, false); err != nil && err != utils.ErrNotFound {
|
||||
return nil, err
|
||||
} else if dcsDb != nil {
|
||||
} else if dcsDb != nil && DerivedChargersMatchesDest(dcsDb, attrs.Destination) {
|
||||
dcs = dcsDb
|
||||
break
|
||||
}
|
||||
}
|
||||
return dcs, nil
|
||||
}
|
||||
|
||||
func DerivedChargersMatchesDest(dcs *utils.DerivedChargers, dest string) bool {
|
||||
if len(dcs.DestinationIds) == 0 || dcs.DestinationIds[utils.ANY] {
|
||||
return true
|
||||
}
|
||||
// check destination ids
|
||||
for _, p := range utils.SplitPrefix(dest, MIN_PREFIX_MATCH) {
|
||||
if x, err := cache2go.Get(utils.DESTINATION_PREFIX + p); err == nil {
|
||||
destIds := x.(map[interface{}]struct{})
|
||||
for value := range dcs.DestinationIds {
|
||||
for idId := range destIds {
|
||||
dId := idId.(string)
|
||||
if value == dId {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -18,15 +18,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
package engine
|
||||
|
||||
/*
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
/*
|
||||
var cfgDcT *config.CGRConfig
|
||||
var acntDb AccountingStorage
|
||||
|
||||
@@ -94,3 +92,30 @@ func TestHandleGetStoredDC(t *testing.T) {
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
func TestHandleDeivedChargersMatchDestRet(t *testing.T) {
|
||||
dcs := &utils.DerivedChargers{
|
||||
DestinationIds: utils.NewStringMap("RET"),
|
||||
}
|
||||
if !DerivedChargersMatchesDest(dcs, "0723045326") {
|
||||
t.Error("Derived charger failed to match dest")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleDeivedChargersMatchDestNat(t *testing.T) {
|
||||
dcs := &utils.DerivedChargers{
|
||||
DestinationIds: utils.NewStringMap("NAT"),
|
||||
}
|
||||
if !DerivedChargersMatchesDest(dcs, "0723045326") {
|
||||
t.Error("Derived charger failed to match dest")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleDeivedChargersMatchDestNatRet(t *testing.T) {
|
||||
dcs := &utils.DerivedChargers{
|
||||
DestinationIds: utils.NewStringMap("NAT", "RET"),
|
||||
}
|
||||
if !DerivedChargersMatchesDest(dcs, "0723045326") {
|
||||
t.Error("Derived charger failed to match dest")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,10 +208,10 @@ cgrates.org,alodis,TOPUP_EMPTY_AT,,true,true
|
||||
`
|
||||
|
||||
derivedCharges = `
|
||||
#Direction,Tenant,Category,Account,Subject,RunId,RunFilter,ReqTypeField,DirectionField,TenantField,TorField,AccountField,SubjectField,DestinationField,SetupTimeField,PddField,AnswerTimeField,UsageField,SupplierField,DisconnectCauseField,CostField,RatedField
|
||||
*out,cgrates.org,call,dan,dan,extra1,^filteredHeader1/filterValue1/,^prepaid,,,,rif,rif,,,,,,,,,
|
||||
*out,cgrates.org,call,dan,dan,extra2,,,,,,ivo,ivo,,,,,,,,,
|
||||
*out,cgrates.org,call,dan,*any,extra1,,,,,,rif2,rif2,,,,,,,,,
|
||||
#Direction,Tenant,Category,Account,Subject,DestinationIds,RunId,RunFilter,ReqTypeField,DirectionField,TenantField,TorField,AccountField,SubjectField,DestinationField,SetupTimeField,PddField,AnswerTimeField,UsageField,SupplierField,DisconnectCauseField,CostField,RatedField
|
||||
*out,cgrates.org,call,dan,dan,,extra1,^filteredHeader1/filterValue1/,^prepaid,,,,rif,rif,,,,,,,,,
|
||||
*out,cgrates.org,call,dan,dan,,extra2,,,,,,ivo,ivo,,,,,,,,,
|
||||
*out,cgrates.org,call,dan,*any,,extra1,,,,,,rif2,rif2,,,,,,,,,
|
||||
`
|
||||
cdrStats = `
|
||||
#Id[0],QueueLength[1],TimeWindow[2],SaveInterval[3],Metric[4],SetupInterval[5],TOR[6],CdrHost[7],CdrSource[8],ReqType[9],Direction[10],Tenant[11],Category[12],Account[13],Subject[14],DestinationPrefix[15],PddInterval[16],UsageInterval[17],Supplier[18],DisconnectCause[19],MediationRunIds[20],RatedAccount[21],RatedSubject[22],CostInterval[23],Triggers[24]
|
||||
@@ -222,7 +222,7 @@ CDRST2,10,10m,,ASR,,,,,,,cgrates.org,call,,,,,,,,,,,,
|
||||
CDRST2,,,,ACD,,,,,,,,,,,,,,,,,,,,
|
||||
`
|
||||
users = `
|
||||
#Tenant[0],UserName[1],AttributeName[2],AttributeValue[3]
|
||||
#Tenant[0],UserName[1],AttributeName[2],AttributeValue[3],Weight[4]
|
||||
cgrates.org,rif,false,test0,val0,10
|
||||
cgrates.org,rif,,test1,val1,10
|
||||
cgrates.org,dan,,another,value,10
|
||||
@@ -1095,20 +1095,22 @@ func TestLoadDerivedChargers(t *testing.T) {
|
||||
if len(csvr.derivedChargers) != 2 {
|
||||
t.Error("Failed to load derivedChargers: ", csvr.derivedChargers)
|
||||
}
|
||||
expCharger1 := utils.DerivedChargers{
|
||||
&utils.DerivedCharger{RunId: "extra1", RunFilters: "^filteredHeader1/filterValue1/", ReqTypeField: "^prepaid", DirectionField: utils.META_DEFAULT,
|
||||
TenantField: utils.META_DEFAULT, CategoryField: utils.META_DEFAULT, AccountField: "rif", SubjectField: "rif", DestinationField: utils.META_DEFAULT,
|
||||
SetupTimeField: utils.META_DEFAULT, PddField: utils.META_DEFAULT, AnswerTimeField: utils.META_DEFAULT, UsageField: utils.META_DEFAULT,
|
||||
SupplierField: utils.META_DEFAULT, DisconnectCauseField: utils.META_DEFAULT, CostField: utils.META_DEFAULT, RatedField: utils.META_DEFAULT},
|
||||
&utils.DerivedCharger{RunId: "extra2", ReqTypeField: utils.META_DEFAULT, DirectionField: utils.META_DEFAULT, TenantField: utils.META_DEFAULT,
|
||||
CategoryField: utils.META_DEFAULT, AccountField: "ivo", SubjectField: "ivo", DestinationField: utils.META_DEFAULT,
|
||||
SetupTimeField: utils.META_DEFAULT, PddField: utils.META_DEFAULT, AnswerTimeField: utils.META_DEFAULT, UsageField: utils.META_DEFAULT,
|
||||
SupplierField: utils.META_DEFAULT, DisconnectCauseField: utils.META_DEFAULT, CostField: utils.META_DEFAULT, RatedField: utils.META_DEFAULT},
|
||||
}
|
||||
expCharger1 := &utils.DerivedChargers{
|
||||
DestinationIds: utils.StringMap{},
|
||||
Chargers: []*utils.DerivedCharger{
|
||||
&utils.DerivedCharger{RunId: "extra1", RunFilters: "^filteredHeader1/filterValue1/", ReqTypeField: "^prepaid", DirectionField: utils.META_DEFAULT,
|
||||
TenantField: utils.META_DEFAULT, CategoryField: utils.META_DEFAULT, AccountField: "rif", SubjectField: "rif", DestinationField: utils.META_DEFAULT,
|
||||
SetupTimeField: utils.META_DEFAULT, PddField: utils.META_DEFAULT, AnswerTimeField: utils.META_DEFAULT, UsageField: utils.META_DEFAULT,
|
||||
SupplierField: utils.META_DEFAULT, DisconnectCauseField: utils.META_DEFAULT, CostField: utils.META_DEFAULT, RatedField: utils.META_DEFAULT},
|
||||
&utils.DerivedCharger{RunId: "extra2", ReqTypeField: utils.META_DEFAULT, DirectionField: utils.META_DEFAULT, TenantField: utils.META_DEFAULT,
|
||||
CategoryField: utils.META_DEFAULT, AccountField: "ivo", SubjectField: "ivo", DestinationField: utils.META_DEFAULT,
|
||||
SetupTimeField: utils.META_DEFAULT, PddField: utils.META_DEFAULT, AnswerTimeField: utils.META_DEFAULT, UsageField: utils.META_DEFAULT,
|
||||
SupplierField: utils.META_DEFAULT, DisconnectCauseField: utils.META_DEFAULT, CostField: utils.META_DEFAULT, RatedField: utils.META_DEFAULT},
|
||||
}}
|
||||
keyCharger1 := utils.DerivedChargersKey("*out", "cgrates.org", "call", "dan", "dan")
|
||||
|
||||
if !csvr.derivedChargers[keyCharger1].Equal(expCharger1) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", expCharger1[0], csvr.derivedChargers[keyCharger1][0])
|
||||
t.Errorf("Expecting: %+v, received: %+v", expCharger1.Chargers[0], csvr.derivedChargers[keyCharger1].Chargers[0])
|
||||
}
|
||||
}
|
||||
func TestLoadCdrStats(t *testing.T) {
|
||||
|
||||
@@ -472,7 +472,7 @@ func (tps TpDerivedChargers) GetDerivedChargers() (map[string]*utils.TPDerivedCh
|
||||
dcs := make(map[string]*utils.TPDerivedChargers)
|
||||
for _, tpDcMdl := range tps {
|
||||
tpDc := &utils.TPDerivedChargers{TPid: tpDcMdl.Tpid, Loadid: tpDcMdl.Loadid, Direction: tpDcMdl.Direction, Tenant: tpDcMdl.Tenant, Category: tpDcMdl.Category,
|
||||
Account: tpDcMdl.Account, Subject: tpDcMdl.Subject}
|
||||
Account: tpDcMdl.Account, Subject: tpDcMdl.Subject, DestinationIds: tpDcMdl.DestinationIds}
|
||||
tag := tpDc.GetDerivedChargesId()
|
||||
if _, hasIt := dcs[tag]; !hasIt {
|
||||
dcs[tag] = tpDc
|
||||
|
||||
@@ -493,9 +493,9 @@ func TestTPDerivedChargersAsExportSlice(t *testing.T) {
|
||||
},
|
||||
}
|
||||
expectedSlc := [][]string{
|
||||
[]string{"*out", "cgrates.org", "call", "1001", "1001",
|
||||
[]string{"*out", "cgrates.org", "call", "1001", "1001", "",
|
||||
"derived_run1", "", "^rated", utils.META_DEFAULT, utils.META_DEFAULT, utils.META_DEFAULT, utils.META_DEFAULT, "^1002", utils.META_DEFAULT, utils.META_DEFAULT, utils.META_DEFAULT, utils.META_DEFAULT, utils.META_DEFAULT, utils.META_DEFAULT, utils.META_DEFAULT, utils.META_DEFAULT, utils.META_DEFAULT},
|
||||
[]string{"*out", "cgrates.org", "call", "1001", "1001",
|
||||
[]string{"*out", "cgrates.org", "call", "1001", "1001", "",
|
||||
"derived_run2", "", "^rated", utils.META_DEFAULT, utils.META_DEFAULT, utils.META_DEFAULT, "^1002", utils.META_DEFAULT, utils.META_DEFAULT, utils.META_DEFAULT, utils.META_DEFAULT, utils.META_DEFAULT, utils.META_DEFAULT, utils.META_DEFAULT, utils.META_DEFAULT, utils.META_DEFAULT, utils.META_DEFAULT},
|
||||
}
|
||||
ms := APItoModelDerivedCharger(dcs)
|
||||
|
||||
@@ -255,23 +255,24 @@ type TpDerivedCharger struct {
|
||||
Category string `index:"2" re:"\w+\s*"`
|
||||
Account string `index:"3" re:"\w+\s*"`
|
||||
Subject string `index:"4" re:"\*any\s*|\w+\s*"`
|
||||
Runid string `index:"5" re:"\w+\s*"`
|
||||
RunFilters string `index:"6" re:"[~^]*[0-9A-Za-z_/:().+]+\s*"`
|
||||
ReqTypeField string `index:"7" re:"\*default\s*|[~^*]*[0-9A-Za-z_/:().+]+\s*"`
|
||||
DirectionField string `index:"8" re:"\*default\s*|[~^]*[0-9A-Za-z_/:().+]+\s*"`
|
||||
TenantField string `index:"9" re:"\*default\s*|[~^]*[0-9A-Za-z_/:().+]+\s*"`
|
||||
CategoryField string `index:"10" re:"\*default\s*|[~^]*[0-9A-Za-z_/:().+]+\s*"`
|
||||
AccountField string `index:"11" re:"\*default\s*|[~^]*[0-9A-Za-z_/:().+]+\s*"`
|
||||
SubjectField string `index:"12" re:"\*default\s*|[~^]*[0-9A-Za-z_/:().+]+\s*"`
|
||||
DestinationField string `index:"13" re:"\*default\s*|[~^]*[0-9A-Za-z_/:().+]+\s*"`
|
||||
SetupTimeField string `index:"14" re:"\*default\s*|[~^]*[0-9A-Za-z_/:().+]+\s*"`
|
||||
PddField string `index:"15" re:"\*default\s*|[~^]*[0-9A-Za-z_/:().+]+\s*"`
|
||||
AnswerTimeField string `index:"16" re:"\*default\s*|[~^]*[0-9A-Za-z_/:().+]+\s*"`
|
||||
UsageField string `index:"17" re:"\*default\s*|[~^]*[0-9A-Za-z_/:().+]+\s*"`
|
||||
SupplierField string `index:"18" re:"\*default\s*|[~^]*[0-9A-Za-z_/:().+]+\s*"`
|
||||
DisconnectCauseField string `index:"19" re:"\*default\s*|[~^]*[0-9A-Za-z_/:().+]+\s*"`
|
||||
RatedField string `index:"20" re:"\*default\s*|[~^]*[0-9A-Za-z_/:().+]+\s*"`
|
||||
CostField string `index:"21" re:"\*default\s*|[~^]*[0-9A-Za-z_/:().+]+\s*"`
|
||||
DestinationIds string `index:"5" re:""`
|
||||
Runid string `index:"6" re:"\w+\s*"`
|
||||
RunFilters string `index:"7" re:"[~^]*[0-9A-Za-z_/:().+]+\s*"`
|
||||
ReqTypeField string `index:"8" re:"\*default\s*|[~^*]*[0-9A-Za-z_/:().+]+\s*"`
|
||||
DirectionField string `index:"9" re:"\*default\s*|[~^]*[0-9A-Za-z_/:().+]+\s*"`
|
||||
TenantField string `index:"10" re:"\*default\s*|[~^]*[0-9A-Za-z_/:().+]+\s*"`
|
||||
CategoryField string `index:"11" re:"\*default\s*|[~^]*[0-9A-Za-z_/:().+]+\s*"`
|
||||
AccountField string `index:"12" re:"\*default\s*|[~^]*[0-9A-Za-z_/:().+]+\s*"`
|
||||
SubjectField string `index:"13" re:"\*default\s*|[~^]*[0-9A-Za-z_/:().+]+\s*"`
|
||||
DestinationField string `index:"14" re:"\*default\s*|[~^]*[0-9A-Za-z_/:().+]+\s*"`
|
||||
SetupTimeField string `index:"15" re:"\*default\s*|[~^]*[0-9A-Za-z_/:().+]+\s*"`
|
||||
PddField string `index:"16" re:"\*default\s*|[~^]*[0-9A-Za-z_/:().+]+\s*"`
|
||||
AnswerTimeField string `index:"17" re:"\*default\s*|[~^]*[0-9A-Za-z_/:().+]+\s*"`
|
||||
UsageField string `index:"18" re:"\*default\s*|[~^]*[0-9A-Za-z_/:().+]+\s*"`
|
||||
SupplierField string `index:"19" re:"\*default\s*|[~^]*[0-9A-Za-z_/:().+]+\s*"`
|
||||
DisconnectCauseField string `index:"20" re:"\*default\s*|[~^]*[0-9A-Za-z_/:().+]+\s*"`
|
||||
RatedField string `index:"21" re:"\*default\s*|[~^]*[0-9A-Za-z_/:().+]+\s*"`
|
||||
CostField string `index:"22" re:"\*default\s*|[~^]*[0-9A-Za-z_/:().+]+\s*"`
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
|
||||
@@ -294,12 +294,12 @@ func (rs *Responder) GetDerivedMaxSessionTime(ev *StoredCdr, reply *float64) err
|
||||
maxCallDuration := -1.0
|
||||
attrsDC := &utils.AttrDerivedChargers{Tenant: ev.GetTenant(utils.META_DEFAULT), Category: ev.GetCategory(utils.META_DEFAULT), Direction: ev.GetDirection(utils.META_DEFAULT),
|
||||
Account: ev.GetAccount(utils.META_DEFAULT), Subject: ev.GetSubject(utils.META_DEFAULT)}
|
||||
var dcs utils.DerivedChargers
|
||||
if err := rs.GetDerivedChargers(attrsDC, &dcs); err != nil {
|
||||
dcs := &utils.DerivedChargers{}
|
||||
if err := rs.GetDerivedChargers(attrsDC, dcs); err != nil {
|
||||
return err
|
||||
}
|
||||
dcs, _ = dcs.AppendDefaultRun()
|
||||
for _, dc := range dcs {
|
||||
for _, dc := range dcs.Chargers {
|
||||
if utils.IsSliceMember([]string{utils.META_RATED, utils.RATED}, ev.GetReqType(dc.ReqTypeField)) { // Only consider prepaid and pseudoprepaid for MaxSessionTime
|
||||
continue
|
||||
}
|
||||
@@ -382,8 +382,8 @@ func (rs *Responder) GetSessionRuns(ev *StoredCdr, sRuns *[]*SessionRun) error {
|
||||
}
|
||||
attrsDC := &utils.AttrDerivedChargers{Tenant: ev.GetTenant(utils.META_DEFAULT), Category: ev.GetCategory(utils.META_DEFAULT), Direction: ev.GetDirection(utils.META_DEFAULT),
|
||||
Account: ev.GetAccount(utils.META_DEFAULT), Subject: ev.GetSubject(utils.META_DEFAULT)}
|
||||
var dcs utils.DerivedChargers
|
||||
if err := rs.GetDerivedChargers(attrsDC, &dcs); err != nil {
|
||||
dcs := &utils.DerivedChargers{}
|
||||
if err := rs.GetDerivedChargers(attrsDC, dcs); err != nil {
|
||||
rs.getCache().Cache(utils.GET_SESS_RUNS_CACHE_PREFIX+ev.CgrId, &cache2go.CacheItem{
|
||||
Err: err,
|
||||
})
|
||||
@@ -391,7 +391,7 @@ func (rs *Responder) GetSessionRuns(ev *StoredCdr, sRuns *[]*SessionRun) error {
|
||||
}
|
||||
dcs, _ = dcs.AppendDefaultRun()
|
||||
sesRuns := make([]*SessionRun, 0)
|
||||
for _, dc := range dcs {
|
||||
for _, dc := range dcs.Chargers {
|
||||
if !utils.IsSliceMember([]string{utils.META_PREPAID, utils.PREPAID}, ev.GetReqType(dc.ReqTypeField)) {
|
||||
continue // We only consider prepaid sessions
|
||||
}
|
||||
@@ -426,7 +426,7 @@ func (rs *Responder) GetDerivedChargers(attrs *utils.AttrDerivedChargers, dcs *u
|
||||
if dcsH, err := HandleGetDerivedChargers(ratingStorage, attrs); err != nil {
|
||||
return err
|
||||
} else if dcsH != nil {
|
||||
*dcs = dcsH
|
||||
*dcs = *dcsH
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -36,8 +36,8 @@ func init() {
|
||||
// Test internal abilites of GetDerivedChargers
|
||||
func TestResponderGetDerivedChargers(t *testing.T) {
|
||||
|
||||
cfgedDC := utils.DerivedChargers{&utils.DerivedCharger{RunId: "responder1", ReqTypeField: utils.META_DEFAULT, DirectionField: "test", TenantField: "test",
|
||||
CategoryField: "test", AccountField: "test", SubjectField: "test", DestinationField: "test", SetupTimeField: "test", AnswerTimeField: "test", UsageField: "test"}}
|
||||
cfgedDC := &utils.DerivedChargers{DestinationIds: utils.StringMap{}, Chargers: []*utils.DerivedCharger{&utils.DerivedCharger{RunId: "responder1", ReqTypeField: utils.META_DEFAULT, DirectionField: "test", TenantField: "test",
|
||||
CategoryField: "test", AccountField: "test", SubjectField: "test", DestinationField: "test", SetupTimeField: "test", AnswerTimeField: "test", UsageField: "test"}}}
|
||||
rsponder = &Responder{}
|
||||
attrs := &utils.AttrDerivedChargers{Tenant: "cgrates.org", Category: "call", Direction: "*out", Account: "responder_test", Subject: "responder_test"}
|
||||
if err := ratingStorage.SetDerivedChargers(utils.DerivedChargersKey(utils.OUT, utils.ANY, utils.ANY, utils.ANY, utils.ANY), cfgedDC); err != nil {
|
||||
@@ -46,8 +46,8 @@ func TestResponderGetDerivedChargers(t *testing.T) {
|
||||
if err := ratingStorage.CacheRatingPrefixes(utils.DERIVEDCHARGERS_PREFIX); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
var dcs utils.DerivedChargers
|
||||
if err := rsponder.GetDerivedChargers(attrs, &dcs); err != nil {
|
||||
dcs := &utils.DerivedChargers{}
|
||||
if err := rsponder.GetDerivedChargers(attrs, dcs); err != nil {
|
||||
t.Error("Unexpected error", err.Error())
|
||||
} else if !reflect.DeepEqual(dcs, cfgedDC) {
|
||||
t.Errorf("Expecting: %v, received: %v ", cfgedDC, dcs)
|
||||
@@ -82,14 +82,14 @@ func TestResponderGetDerivedMaxSessionTime(t *testing.T) {
|
||||
t.Error(err)
|
||||
}
|
||||
keyCharger1 := utils.ConcatenatedKey("*out", testTenant, "call", "dan", "dan")
|
||||
charger1 := utils.DerivedChargers{
|
||||
charger1 := &utils.DerivedChargers{Chargers: []*utils.DerivedCharger{
|
||||
&utils.DerivedCharger{RunId: "extra1", ReqTypeField: "^" + utils.META_PREPAID, DirectionField: "*default", TenantField: "*default", CategoryField: "*default",
|
||||
AccountField: "^dan", SubjectField: "^dan", DestinationField: "^+49151708707", SetupTimeField: "*default", AnswerTimeField: "*default", UsageField: "*default"},
|
||||
&utils.DerivedCharger{RunId: "extra2", ReqTypeField: "*default", DirectionField: "*default", TenantField: "*default", CategoryField: "*default",
|
||||
AccountField: "^ivo", SubjectField: "^ivo", DestinationField: "*default", SetupTimeField: "*default", AnswerTimeField: "*default", UsageField: "*default"},
|
||||
&utils.DerivedCharger{RunId: "extra3", ReqTypeField: "^" + utils.META_PSEUDOPREPAID, DirectionField: "*default", TenantField: "*default", CategoryField: "*default",
|
||||
AccountField: "^rif", SubjectField: "^rif", DestinationField: "^+49151708707", SetupTimeField: "*default", AnswerTimeField: "*default", UsageField: "*default"},
|
||||
}
|
||||
}}
|
||||
if err := ratingStorage.SetDerivedChargers(keyCharger1, charger1); err != nil {
|
||||
t.Error("Error on setting DerivedChargers", err.Error())
|
||||
}
|
||||
@@ -106,9 +106,9 @@ func TestResponderGetDerivedMaxSessionTime(t *testing.T) {
|
||||
} else if danStoredAcnt.BalanceMap[utils.VOICE][0].GetValue() != dansAccount.BalanceMap[utils.VOICE][0].GetValue() {
|
||||
t.Error("BalanceValue: ", danStoredAcnt.BalanceMap[utils.VOICE][0].GetValue())
|
||||
}
|
||||
var dcs utils.DerivedChargers
|
||||
dcs := &utils.DerivedChargers{}
|
||||
attrs := &utils.AttrDerivedChargers{Tenant: testTenant, Category: "call", Direction: "*out", Account: "dan", Subject: "dan"}
|
||||
if err := rsponder.GetDerivedChargers(attrs, &dcs); err != nil {
|
||||
if err := rsponder.GetDerivedChargers(attrs, dcs); err != nil {
|
||||
t.Error("Unexpected error", err.Error())
|
||||
} else if !reflect.DeepEqual(dcs, charger1) {
|
||||
t.Errorf("Expecting: %+v, received: %+v ", charger1, dcs)
|
||||
@@ -142,7 +142,7 @@ func TestResponderGetSessionRuns(t *testing.T) {
|
||||
CategoryField: "^0", AccountField: "^minu", SubjectField: "^rif", DestinationField: "^0256",
|
||||
SetupTimeField: utils.META_DEFAULT, PddField: utils.META_DEFAULT, AnswerTimeField: utils.META_DEFAULT, UsageField: utils.META_DEFAULT, SupplierField: utils.META_DEFAULT,
|
||||
DisconnectCauseField: utils.META_DEFAULT}
|
||||
charger1 := utils.DerivedChargers{extra1DC, extra2DC, extra3DC}
|
||||
charger1 := &utils.DerivedChargers{Chargers: []*utils.DerivedCharger{extra1DC, extra2DC, extra3DC}}
|
||||
if err := ratingStorage.SetDerivedChargers(keyCharger1, charger1); err != nil {
|
||||
t.Error("Error on setting DerivedChargers", err.Error())
|
||||
}
|
||||
|
||||
@@ -417,11 +417,11 @@ func (csvs *CSVStorage) GetTpDerivedChargers(filter *TpDerivedCharger) ([]TpDeri
|
||||
log.Print("bad line in derived chargers csv: ", err)
|
||||
return nil, err
|
||||
}
|
||||
if tpRate, err := csvLoad(TpDerivedCharger{}, record); err != nil {
|
||||
if tp, err := csvLoad(TpDerivedCharger{}, record); err != nil {
|
||||
log.Print("error loading derived charger: ", err)
|
||||
return nil, err
|
||||
} else {
|
||||
dc := tpRate.(TpDerivedCharger)
|
||||
dc := tp.(TpDerivedCharger)
|
||||
if filter != nil {
|
||||
dc.Tpid = filter.Tpid
|
||||
dc.Loadid = filter.Loadid
|
||||
|
||||
@@ -55,8 +55,8 @@ type RatingStorage interface {
|
||||
SetCdrStats(*CdrStats) error
|
||||
GetCdrStats(string) (*CdrStats, error)
|
||||
GetAllCdrStats() ([]*CdrStats, error)
|
||||
GetDerivedChargers(string, bool) (utils.DerivedChargers, error)
|
||||
SetDerivedChargers(string, utils.DerivedChargers) error
|
||||
GetDerivedChargers(string, bool) (*utils.DerivedChargers, error)
|
||||
SetDerivedChargers(string, *utils.DerivedChargers) error
|
||||
GetActions(string, bool) (Actions, error)
|
||||
SetActions(string, Actions) error
|
||||
GetSharedGroup(string, bool) (*SharedGroup, error)
|
||||
|
||||
@@ -722,11 +722,11 @@ func (ms *MapStorage) GetAllActionPlans() (ats map[string]ActionPlans, err error
|
||||
return
|
||||
}
|
||||
|
||||
func (ms *MapStorage) GetDerivedChargers(key string, skipCache bool) (dcs utils.DerivedChargers, err error) {
|
||||
func (ms *MapStorage) GetDerivedChargers(key string, skipCache bool) (dcs *utils.DerivedChargers, err error) {
|
||||
key = utils.DERIVEDCHARGERS_PREFIX + key
|
||||
if !skipCache {
|
||||
if x, err := cache2go.Get(key); err == nil {
|
||||
return x.(utils.DerivedChargers), nil
|
||||
return x.(*utils.DerivedChargers), nil
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
@@ -740,8 +740,8 @@ func (ms *MapStorage) GetDerivedChargers(key string, skipCache bool) (dcs utils.
|
||||
return
|
||||
}
|
||||
|
||||
func (ms *MapStorage) SetDerivedChargers(key string, dcs utils.DerivedChargers) error {
|
||||
if len(dcs) == 0 {
|
||||
func (ms *MapStorage) SetDerivedChargers(key string, dcs *utils.DerivedChargers) error {
|
||||
if dcs == nil || len(dcs.Chargers) == 0 {
|
||||
delete(ms.dict, utils.DERIVEDCHARGERS_PREFIX+key)
|
||||
cache2go.RemKey(utils.DERIVEDCHARGERS_PREFIX + key)
|
||||
return nil
|
||||
|
||||
@@ -1107,17 +1107,17 @@ func (ms *MongoStorage) GetAllActionPlans() (ats map[string]ActionPlans, err err
|
||||
return
|
||||
}
|
||||
|
||||
func (ms *MongoStorage) GetDerivedChargers(key string, skipCache bool) (dcs utils.DerivedChargers, err error) {
|
||||
func (ms *MongoStorage) GetDerivedChargers(key string, skipCache bool) (dcs *utils.DerivedChargers, err error) {
|
||||
if !skipCache {
|
||||
if x, err := cache2go.Get(utils.DERIVEDCHARGERS_PREFIX + key); err == nil {
|
||||
return x.(utils.DerivedChargers), nil
|
||||
return x.(*utils.DerivedChargers), nil
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
var kv struct {
|
||||
Key string
|
||||
Value utils.DerivedChargers
|
||||
Value *utils.DerivedChargers
|
||||
}
|
||||
err = ms.db.C(colDcs).Find(bson.M{"key": key}).One(&kv)
|
||||
if err == nil {
|
||||
@@ -1127,8 +1127,8 @@ func (ms *MongoStorage) GetDerivedChargers(key string, skipCache bool) (dcs util
|
||||
return
|
||||
}
|
||||
|
||||
func (ms *MongoStorage) SetDerivedChargers(key string, dcs utils.DerivedChargers) (err error) {
|
||||
if len(dcs) == 0 {
|
||||
func (ms *MongoStorage) SetDerivedChargers(key string, dcs *utils.DerivedChargers) (err error) {
|
||||
if dcs == nil || len(dcs.Chargers) == 0 {
|
||||
cache2go.RemKey(utils.DERIVEDCHARGERS_PREFIX + key)
|
||||
err = ms.db.C(colDcs).Remove(bson.M{"key": key})
|
||||
if err != mgo.ErrNotFound {
|
||||
@@ -1138,7 +1138,7 @@ func (ms *MongoStorage) SetDerivedChargers(key string, dcs utils.DerivedChargers
|
||||
}
|
||||
_, err = ms.db.C(colDcs).Upsert(bson.M{"key": key}, &struct {
|
||||
Key string
|
||||
Value utils.DerivedChargers
|
||||
Value *utils.DerivedChargers
|
||||
}{Key: key, Value: dcs})
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -899,11 +899,11 @@ func (rs *RedisStorage) GetAllActionPlans() (ats map[string]ActionPlans, err err
|
||||
return
|
||||
}
|
||||
|
||||
func (rs *RedisStorage) GetDerivedChargers(key string, skipCache bool) (dcs utils.DerivedChargers, err error) {
|
||||
func (rs *RedisStorage) GetDerivedChargers(key string, skipCache bool) (dcs *utils.DerivedChargers, err error) {
|
||||
key = utils.DERIVEDCHARGERS_PREFIX + key
|
||||
if !skipCache {
|
||||
if x, err := cache2go.Get(key); err == nil {
|
||||
return x.(utils.DerivedChargers), nil
|
||||
return x.(*utils.DerivedChargers), nil
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
@@ -916,8 +916,8 @@ func (rs *RedisStorage) GetDerivedChargers(key string, skipCache bool) (dcs util
|
||||
return dcs, err
|
||||
}
|
||||
|
||||
func (rs *RedisStorage) SetDerivedChargers(key string, dcs utils.DerivedChargers) (err error) {
|
||||
if len(dcs) == 0 {
|
||||
func (rs *RedisStorage) SetDerivedChargers(key string, dcs *utils.DerivedChargers) (err error) {
|
||||
if dcs == nil || len(dcs.Chargers) == 0 {
|
||||
_, err = rs.db.Del(utils.DERIVEDCHARGERS_PREFIX + key)
|
||||
cache2go.RemKey(utils.DERIVEDCHARGERS_PREFIX + key)
|
||||
return err
|
||||
|
||||
@@ -56,12 +56,12 @@ func TestSetGetDerivedCharges(t *testing.T) {
|
||||
return
|
||||
}
|
||||
keyCharger1 := utils.ConcatenatedKey("*out", "cgrates.org", "call", "dan", "dan")
|
||||
charger1 := utils.DerivedChargers{
|
||||
charger1 := &utils.DerivedChargers{Chargers: []*utils.DerivedCharger{
|
||||
&utils.DerivedCharger{RunId: "extra1", ReqTypeField: "^prepaid", DirectionField: "*default", TenantField: "*default", CategoryField: "*default",
|
||||
AccountField: "rif", SubjectField: "rif", DestinationField: "*default", SetupTimeField: "*default", AnswerTimeField: "*default", UsageField: "*default"},
|
||||
&utils.DerivedCharger{RunId: "extra2", ReqTypeField: "*default", DirectionField: "*default", TenantField: "*default", CategoryField: "*default",
|
||||
AccountField: "ivo", SubjectField: "ivo", DestinationField: "*default", SetupTimeField: "*default", AnswerTimeField: "*default", UsageField: "*default"},
|
||||
}
|
||||
}}
|
||||
if err := rds.SetDerivedChargers(keyCharger1, charger1); err != nil {
|
||||
t.Error("Error on setting DerivedChargers", err.Error())
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ type TpReader struct {
|
||||
ratingProfiles map[string]*RatingProfile
|
||||
sharedGroups map[string]*SharedGroup
|
||||
lcrs map[string]*LCR
|
||||
derivedChargers map[string]utils.DerivedChargers
|
||||
derivedChargers map[string]*utils.DerivedChargers
|
||||
cdrStats map[string]*CdrStats
|
||||
users map[string]*UserProfile
|
||||
aliases map[string]*Alias
|
||||
@@ -62,7 +62,7 @@ func NewTpReader(rs RatingStorage, as AccountingStorage, lr LoadReader, tpid, ti
|
||||
cdrStats: make(map[string]*CdrStats),
|
||||
users: make(map[string]*UserProfile),
|
||||
aliases: make(map[string]*Alias),
|
||||
derivedChargers: make(map[string]utils.DerivedChargers),
|
||||
derivedChargers: make(map[string]*utils.DerivedChargers),
|
||||
}
|
||||
//add *any and *asap timing tag (in case of no timings file)
|
||||
tpr.timings[utils.ANY] = &utils.TPTiming{
|
||||
@@ -893,7 +893,10 @@ func (tpr *TpReader) LoadDerivedChargersFiltered(filter *TpDerivedCharger, save
|
||||
for _, tpDcs := range storDcs {
|
||||
tag := tpDcs.GetDerivedChargersKey()
|
||||
if _, hasIt := tpr.derivedChargers[tag]; !hasIt {
|
||||
tpr.derivedChargers[tag] = make(utils.DerivedChargers, 0) // Load object map since we use this method also from LoadDerivedChargers
|
||||
tpr.derivedChargers[tag] = &utils.DerivedChargers{
|
||||
DestinationIds: make(utils.StringMap),
|
||||
Chargers: make([]*utils.DerivedCharger, 0),
|
||||
} // Load object map since we use this method also from LoadDerivedChargers
|
||||
}
|
||||
for _, tpDc := range tpDcs.DerivedChargers {
|
||||
dc, err := utils.NewDerivedCharger(tpDc.RunId, tpDc.RunFilters, tpDc.ReqTypeField, tpDc.DirectionField, tpDc.TenantField, tpDc.CategoryField,
|
||||
@@ -902,7 +905,8 @@ func (tpr *TpReader) LoadDerivedChargersFiltered(filter *TpDerivedCharger, save
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tpr.derivedChargers[tag] = append(tpr.derivedChargers[tag], dc)
|
||||
tpr.derivedChargers[tag].DestinationIds.Copy(utils.ParseStringMap(tpDcs.DestinationIds))
|
||||
tpr.derivedChargers[tag].Chargers = append(tpr.derivedChargers[tag].Chargers, dc)
|
||||
}
|
||||
}
|
||||
if save {
|
||||
|
||||
@@ -394,6 +394,7 @@ type TPDerivedChargers struct {
|
||||
Category string
|
||||
Account string
|
||||
Subject string
|
||||
DestinationIds string
|
||||
DerivedChargers []*TPDerivedCharger
|
||||
}
|
||||
|
||||
@@ -805,7 +806,7 @@ type AttrGetDestination struct {
|
||||
}
|
||||
|
||||
type AttrDerivedChargers struct {
|
||||
Direction, Tenant, Category, Account, Subject string
|
||||
Direction, Tenant, Category, Account, Subject, Destination string
|
||||
}
|
||||
|
||||
func NewTAFromAccountKey(accountKey string) (*TenantAccount, error) {
|
||||
|
||||
@@ -165,40 +165,6 @@ type DerivedCharger struct {
|
||||
rsrRatedField *RSRField
|
||||
}
|
||||
|
||||
func DerivedChargersKey(direction, tenant, category, account, subject string) string {
|
||||
return ConcatenatedKey(direction, tenant, category, account, subject)
|
||||
}
|
||||
|
||||
type DerivedChargers []*DerivedCharger
|
||||
|
||||
// Precheck that RunId is unique
|
||||
func (dcs DerivedChargers) Append(dc *DerivedCharger) (DerivedChargers, error) {
|
||||
if dc.RunId == DEFAULT_RUNID {
|
||||
return nil, errors.New("Reserved RunId")
|
||||
}
|
||||
for _, dcLocal := range dcs {
|
||||
if dcLocal.RunId == dc.RunId {
|
||||
return nil, errors.New("Duplicated RunId")
|
||||
}
|
||||
}
|
||||
return append(dcs, dc), nil
|
||||
}
|
||||
|
||||
func (dcs DerivedChargers) AppendDefaultRun() (DerivedChargers, error) {
|
||||
dcDf, _ := NewDerivedCharger(DEFAULT_RUNID, "", META_DEFAULT, META_DEFAULT, META_DEFAULT, META_DEFAULT, META_DEFAULT,
|
||||
META_DEFAULT, META_DEFAULT, META_DEFAULT, META_DEFAULT, META_DEFAULT, META_DEFAULT, META_DEFAULT, META_DEFAULT, META_DEFAULT, META_DEFAULT)
|
||||
return append(dcs, dcDf), nil
|
||||
}
|
||||
|
||||
func (dcs DerivedChargers) Equal(other DerivedChargers) bool {
|
||||
for i, dc := range dcs {
|
||||
if !dc.Equal(other[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (dc *DerivedCharger) Equal(other *DerivedCharger) bool {
|
||||
return dc.RunId == other.RunId &&
|
||||
dc.RunFilters == other.RunFilters &&
|
||||
@@ -218,3 +184,43 @@ func (dc *DerivedCharger) Equal(other *DerivedCharger) bool {
|
||||
dc.CostField == other.CostField &&
|
||||
dc.RatedField == other.RatedField
|
||||
}
|
||||
|
||||
func DerivedChargersKey(direction, tenant, category, account, subject string) string {
|
||||
return ConcatenatedKey(direction, tenant, category, account, subject)
|
||||
}
|
||||
|
||||
type DerivedChargers struct {
|
||||
DestinationIds StringMap
|
||||
Chargers []*DerivedCharger
|
||||
}
|
||||
|
||||
// Precheck that RunId is unique
|
||||
func (dcs *DerivedChargers) Append(dc *DerivedCharger) (*DerivedChargers, error) {
|
||||
if dc.RunId == DEFAULT_RUNID {
|
||||
return nil, errors.New("Reserved RunId")
|
||||
}
|
||||
for _, dcLocal := range dcs.Chargers {
|
||||
if dcLocal.RunId == dc.RunId {
|
||||
return nil, errors.New("Duplicated RunId")
|
||||
}
|
||||
}
|
||||
dcs.Chargers = append(dcs.Chargers, dc)
|
||||
return dcs, nil
|
||||
}
|
||||
|
||||
func (dcs *DerivedChargers) AppendDefaultRun() (*DerivedChargers, error) {
|
||||
dcDf, _ := NewDerivedCharger(DEFAULT_RUNID, "", META_DEFAULT, META_DEFAULT, META_DEFAULT, META_DEFAULT, META_DEFAULT,
|
||||
META_DEFAULT, META_DEFAULT, META_DEFAULT, META_DEFAULT, META_DEFAULT, META_DEFAULT, META_DEFAULT, META_DEFAULT, META_DEFAULT, META_DEFAULT)
|
||||
dcs.Chargers = append(dcs.Chargers, dcDf)
|
||||
return dcs, nil
|
||||
}
|
||||
|
||||
func (dcs *DerivedChargers) Equal(other *DerivedChargers) bool {
|
||||
dcs.DestinationIds.Equal(other.DestinationIds)
|
||||
for i, dc := range dcs.Chargers {
|
||||
if !dc.Equal(other.Chargers[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -25,19 +25,20 @@ import (
|
||||
|
||||
func TestAppendDerivedChargers(t *testing.T) {
|
||||
var err error
|
||||
dcs := make(DerivedChargers, 0)
|
||||
|
||||
dcs := &DerivedChargers{Chargers: make([]*DerivedCharger, 0)}
|
||||
if _, err := dcs.Append(&DerivedCharger{RunId: DEFAULT_RUNID}); err == nil {
|
||||
t.Error("Failed to detect using of the default runid")
|
||||
}
|
||||
if dcs, err = dcs.Append(&DerivedCharger{RunId: "FIRST_RUNID"}); err != nil {
|
||||
t.Error("Failed to add runid")
|
||||
} else if len(dcs) != 1 {
|
||||
t.Error("Unexpected number of items inside DerivedChargers configuration", len(dcs))
|
||||
} else if len(dcs.Chargers) != 1 {
|
||||
t.Error("Unexpected number of items inside DerivedChargers configuration", len(dcs.Chargers))
|
||||
}
|
||||
if dcs, err = dcs.Append(&DerivedCharger{RunId: "SECOND_RUNID"}); err != nil {
|
||||
t.Error("Failed to add runid")
|
||||
} else if len(dcs) != 2 {
|
||||
t.Error("Unexpected number of items inside DerivedChargers configuration", len(dcs))
|
||||
} else if len(dcs.Chargers) != 2 {
|
||||
t.Error("Unexpected number of items inside DerivedChargers configuration", len(dcs.Chargers))
|
||||
}
|
||||
if _, err := dcs.Append(&DerivedCharger{RunId: "SECOND_RUNID"}); err == nil {
|
||||
t.Error("Failed to detect duplicate runid")
|
||||
@@ -135,25 +136,26 @@ func TestDerivedChargersKey(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestAppendDefaultRun(t *testing.T) {
|
||||
var dc1 DerivedChargers
|
||||
dc1 := &DerivedChargers{}
|
||||
dcDf := &DerivedCharger{RunId: DEFAULT_RUNID, RunFilters: "", ReqTypeField: META_DEFAULT, DirectionField: META_DEFAULT,
|
||||
TenantField: META_DEFAULT, CategoryField: META_DEFAULT, AccountField: META_DEFAULT, SubjectField: META_DEFAULT,
|
||||
DestinationField: META_DEFAULT, SetupTimeField: META_DEFAULT, PddField: META_DEFAULT, AnswerTimeField: META_DEFAULT, UsageField: META_DEFAULT, SupplierField: META_DEFAULT,
|
||||
DisconnectCauseField: META_DEFAULT, CostField: META_DEFAULT, RatedField: META_DEFAULT}
|
||||
eDc1 := DerivedChargers{dcDf}
|
||||
eDc1 := &DerivedChargers{Chargers: []*DerivedCharger{dcDf}}
|
||||
if dc1, _ = dc1.AppendDefaultRun(); !reflect.DeepEqual(dc1, eDc1) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", eDc1[0], dc1[0])
|
||||
t.Errorf("Expecting: %+v, received: %+v", eDc1.Chargers[0], dc1.Chargers[0])
|
||||
}
|
||||
dc2 := DerivedChargers{
|
||||
dc2 := &DerivedChargers{Chargers: []*DerivedCharger{
|
||||
&DerivedCharger{RunId: "extra1", RunFilters: "", ReqTypeField: "reqtype2", DirectionField: META_DEFAULT, TenantField: META_DEFAULT, CategoryField: META_DEFAULT,
|
||||
AccountField: "rif", SubjectField: "rif", DestinationField: META_DEFAULT, SetupTimeField: META_DEFAULT, PddField: META_DEFAULT, AnswerTimeField: META_DEFAULT, UsageField: META_DEFAULT,
|
||||
DisconnectCauseField: META_DEFAULT},
|
||||
&DerivedCharger{RunId: "extra2", ReqTypeField: META_DEFAULT, DirectionField: META_DEFAULT, TenantField: META_DEFAULT, CategoryField: META_DEFAULT,
|
||||
AccountField: "ivo", SubjectField: "ivo", DestinationField: META_DEFAULT, SetupTimeField: META_DEFAULT, PddField: META_DEFAULT, AnswerTimeField: META_DEFAULT,
|
||||
UsageField: META_DEFAULT, SupplierField: META_DEFAULT, DisconnectCauseField: META_DEFAULT},
|
||||
UsageField: META_DEFAULT, SupplierField: META_DEFAULT, DisconnectCauseField: META_DEFAULT}},
|
||||
}
|
||||
eDc2 := append(dc2, dcDf)
|
||||
eDc2 := &DerivedChargers{}
|
||||
eDc2.Chargers = append(dc2.Chargers, dcDf)
|
||||
if dc2, _ = dc2.AppendDefaultRun(); !reflect.DeepEqual(dc2, eDc2) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", eDc2, dc2)
|
||||
t.Errorf("Expecting: %+v, received: %+v", eDc2.Chargers, dc2.Chargers)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,12 +127,18 @@ func (sm StringMap) Slice() []string {
|
||||
return result
|
||||
}
|
||||
|
||||
func (sm StringMap) Copy(o StringMap) {
|
||||
for k, v := range o {
|
||||
sm[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
func (sm StringMap) String() string {
|
||||
return strings.Join(sm.Slice(), INFIELD_SEP)
|
||||
}
|
||||
|
||||
func (sm StringMap) GetOne() string {
|
||||
for key := range sm{
|
||||
for key := range sm {
|
||||
return key
|
||||
}
|
||||
return ""
|
||||
|
||||
Reference in New Issue
Block a user