mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Merge pull request #2261 from Trial97/v0.10
Updated RSRParser to not split the string between grave accent for v0.10
This commit is contained in:
@@ -280,16 +280,16 @@ func testV1CDRsRefundOutOfSessionCost(t *testing.T) {
|
||||
Usage: utils.DurationPointer(time.Duration(3 * time.Minute)),
|
||||
Cost: utils.Float64Pointer(2.3),
|
||||
Charges: []*engine.ChargingInterval{
|
||||
&engine.ChargingInterval{
|
||||
{
|
||||
RatingID: "c1a5ab9",
|
||||
Increments: []*engine.ChargingIncrement{
|
||||
&engine.ChargingIncrement{
|
||||
{
|
||||
Usage: time.Duration(2 * time.Minute),
|
||||
Cost: 2.0,
|
||||
AccountingID: "a012888",
|
||||
CompressFactor: 1,
|
||||
},
|
||||
&engine.ChargingIncrement{
|
||||
{
|
||||
Usage: time.Duration(1 * time.Second),
|
||||
Cost: 0.005,
|
||||
AccountingID: "44d6c02",
|
||||
@@ -303,7 +303,7 @@ func testV1CDRsRefundOutOfSessionCost(t *testing.T) {
|
||||
Tenant: "cgrates.org",
|
||||
ID: "testV1CDRsRefundOutOfSessionCost",
|
||||
BalanceSummaries: []*engine.BalanceSummary{
|
||||
&engine.BalanceSummary{
|
||||
{
|
||||
UUID: balanceUuid,
|
||||
Type: utils.MONETARY,
|
||||
Value: 50,
|
||||
@@ -364,7 +364,7 @@ func testV1CDRsRefundOutOfSessionCost(t *testing.T) {
|
||||
utils.Account: "testV1CDRsRefundOutOfSessionCost",
|
||||
utils.Destination: "+4986517174963",
|
||||
utils.AnswerTime: time.Date(2019, 11, 27, 12, 21, 26, 0, time.UTC),
|
||||
utils.Usage: time.Duration(123) * time.Minute,
|
||||
utils.Usage: 123 * time.Minute,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -149,6 +149,7 @@ func testConfigSReloadConfigFromJSONSessionS(t *testing.T) {
|
||||
"MinCallDuration": 0.,
|
||||
"SessionTTL": 0.,
|
||||
"SessionTTLLastUsed": nil,
|
||||
"SessionTTLLastUsage": nil,
|
||||
"SessionTTLMaxDelay": nil,
|
||||
"SessionTTLUsage": nil,
|
||||
"StoreSCosts": false,
|
||||
@@ -166,7 +167,7 @@ func testConfigSReloadConfigFromJSONSessionS(t *testing.T) {
|
||||
}, &rpl); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(exp, rpl) {
|
||||
t.Errorf("Expected %+v , received: %+v ", exp, rpl)
|
||||
t.Errorf("Expected %+v , received: %+v ", utils.ToJSON(exp), utils.ToJSON(rpl))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -94,9 +94,8 @@ func (dbcfg *DataDbCfg) loadFromJsonCfg(jsnDbCfg *DbJsonCfg) (err error) {
|
||||
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
|
||||
if rplConn == utils.MetaInternal {
|
||||
return fmt.Errorf("Replication connection ID needs to be different than *internal")
|
||||
} else {
|
||||
dbcfg.RplConns[idx] = rplConn
|
||||
}
|
||||
dbcfg.RplConns[idx] = rplConn
|
||||
}
|
||||
}
|
||||
if jsnDbCfg.Items != nil {
|
||||
|
||||
@@ -35,6 +35,52 @@ func NewRSRParsers(parsersRules string, allFiltersMatch bool, rsrSeparator strin
|
||||
if parsersRules == "" {
|
||||
return
|
||||
}
|
||||
if count := strings.Count(parsersRules, "`"); count%2 != 0 { // check if we have matching `
|
||||
return nil, fmt.Errorf("Unclosed unspilit syntax")
|
||||
} else if count != 0 {
|
||||
var splitedRule []string
|
||||
for idx := strings.IndexByte(parsersRules, '`'); idx != -1; idx = strings.IndexByte(parsersRules, '`') {
|
||||
insideARulePrefix := !strings.HasSuffix(parsersRules[:idx], utils.INFIELD_SEP) // if doesn't have ; we need to concatenate it with last rule
|
||||
if insideARulePrefix {
|
||||
splitedRule = append(splitedRule, strings.Split(parsersRules[:idx], utils.INFIELD_SEP)...)
|
||||
} else {
|
||||
splitedRule = append(splitedRule, strings.Split(parsersRules[:idx-1], utils.INFIELD_SEP)...)
|
||||
}
|
||||
parsersRules = parsersRules[idx+1:]
|
||||
idx = strings.IndexByte(parsersRules, '`')
|
||||
if insideARulePrefix {
|
||||
splitedRule[len(splitedRule)-1] += parsersRules[:idx]
|
||||
} else {
|
||||
splitedRule = append(splitedRule, parsersRules[:idx])
|
||||
}
|
||||
parsersRules = parsersRules[idx+1:]
|
||||
count -= 2 // the number of ` remaining
|
||||
if len(parsersRules) == 0 {
|
||||
continue
|
||||
}
|
||||
insideARuleSufix := !strings.HasPrefix(parsersRules, utils.INFIELD_SEP) // if doesn't have ; we need to concatenate it with last rule
|
||||
if insideARuleSufix {
|
||||
idx = strings.IndexByte(parsersRules, ';')
|
||||
if idx == -1 {
|
||||
idx = len(parsersRules)
|
||||
splitedRule[len(splitedRule)-1] += parsersRules[:idx]
|
||||
break
|
||||
}
|
||||
splitedRule[len(splitedRule)-1] += parsersRules[:idx]
|
||||
} else {
|
||||
idx = 0
|
||||
}
|
||||
parsersRules = parsersRules[idx+1:]
|
||||
if len(parsersRules) == 0 {
|
||||
break
|
||||
}
|
||||
if count == 0 { // no more ` so add the rest
|
||||
splitedRule = append(splitedRule, strings.Split(parsersRules, utils.INFIELD_SEP)...)
|
||||
break
|
||||
}
|
||||
}
|
||||
return NewRSRParsersFromSlice(splitedRule, allFiltersMatch)
|
||||
}
|
||||
return NewRSRParsersFromSlice(strings.Split(parsersRules, rsrSeparator), allFiltersMatch)
|
||||
}
|
||||
|
||||
@@ -95,18 +141,6 @@ func (prsrs RSRParsers) ParseValue(value interface{}) (out string, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// ParseEvent will parse the event values into one output
|
||||
func (prsrs RSRParsers) ParseEvent(ev map[string]interface{}) (out string, err error) {
|
||||
for _, prsr := range prsrs {
|
||||
if outPrsr, err := prsr.ParseEvent(ev); err != nil {
|
||||
return "", err
|
||||
} else {
|
||||
out += outPrsr
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (prsrs RSRParsers) ParseDataProvider(dP utils.DataProvider, separator string) (out string, err error) {
|
||||
for _, prsr := range prsrs {
|
||||
if outPrsr, err := prsr.ParseDataProvider(dP, separator); err != nil {
|
||||
@@ -156,46 +190,37 @@ func NewRSRParser(parserRules string, allFiltersMatch bool) (rsrParser *RSRParse
|
||||
convsSplt := strings.Split(convertersStr, utils.ANDSep)
|
||||
rsrParser.converters = make(utils.DataConverters, len(convsSplt))
|
||||
for i, convStr := range convsSplt {
|
||||
if conv, err := utils.NewDataConverter(convStr); err != nil {
|
||||
var conv utils.DataConverter
|
||||
if conv, err = utils.NewDataConverter(convStr); err != nil {
|
||||
return nil,
|
||||
fmt.Errorf("invalid converter value in string: <%s>, err: %s",
|
||||
convStr, err.Error())
|
||||
} else {
|
||||
rsrParser.converters[i] = conv
|
||||
}
|
||||
rsrParser.converters[i] = conv
|
||||
}
|
||||
parserRules = parserRules[:idxConverters]
|
||||
}
|
||||
if !strings.HasPrefix(parserRules, utils.DynamicDataPrefix) { // special case when RSR is defined as static attribute=value
|
||||
var staticHdr, staticVal string
|
||||
if splt := strings.Split(parserRules, utils.AttrValueSep); len(splt) == 2 { // using '='' as separator since ':' is often use in date/time fields
|
||||
staticHdr, staticVal = splt[0], splt[1] // strip the separator
|
||||
if strings.HasSuffix(staticVal, utils.AttrValueSep) { // if value ends with sep, strip it since it is a part of the definition syntax
|
||||
staticVal = staticVal[:len(staticVal)-1]
|
||||
}
|
||||
} else if len(splt) > 2 {
|
||||
return nil, fmt.Errorf("invalid RSRField static rules: <%s>", parserRules)
|
||||
} else {
|
||||
staticVal = splt[0] // no attribute name
|
||||
}
|
||||
rsrParser.attrName = staticHdr
|
||||
rsrParser.attrValue = staticVal
|
||||
if !strings.HasPrefix(parserRules, utils.DynamicDataPrefix) ||
|
||||
len(parserRules) == 1 { // special case when RSR is defined as static attribute
|
||||
return
|
||||
}
|
||||
// dynamic content via attributeNames
|
||||
spltRules := spltRgxp.Split(parserRules, -1)
|
||||
rsrParser.attrName = spltRules[0][1:] // in form ~hdr_name
|
||||
rsrParser.path = spltRules[0][1:] // in form ~hdr_name
|
||||
if len(spltRules) > 1 {
|
||||
for _, ruleStr := range spltRules[1:] { // :s/ already removed through split
|
||||
allMatches := rulesRgxp.FindStringSubmatch(ruleStr)
|
||||
if len(allMatches) != 3 {
|
||||
return nil, fmt.Errorf("not enough members in Search&Replace, ruleStr: <%s>, matches: %v, ", ruleStr, allMatches)
|
||||
}
|
||||
if srRegexp, err := regexp.Compile(allMatches[1]); err != nil {
|
||||
var srRegexp *regexp.Regexp
|
||||
if srRegexp, err = regexp.Compile(allMatches[1]); err != nil {
|
||||
return nil, fmt.Errorf("invalid Search&Replace subfield rule: <%s>", allMatches[1])
|
||||
} else {
|
||||
rsrParser.rsrRules = append(rsrParser.rsrRules, &utils.ReSearchReplace{SearchRegexp: srRegexp, ReplaceTemplate: allMatches[2]})
|
||||
}
|
||||
rsrParser.rsrRules = append(rsrParser.rsrRules, &utils.ReSearchReplace{
|
||||
SearchRegexp: srRegexp,
|
||||
ReplaceTemplate: allMatches[2],
|
||||
})
|
||||
}
|
||||
}
|
||||
return
|
||||
@@ -214,8 +239,7 @@ type RSRParser struct {
|
||||
Rules string // Rules container holding the string rules, public so it can be stored
|
||||
AllFiltersMatch bool // all filters must match policy
|
||||
|
||||
attrName string // instruct extracting info out of header in event
|
||||
attrValue string // if populated, enforces parsing always to this value
|
||||
path string // instruct extracting info out of header in event
|
||||
rsrRules []*utils.ReSearchReplace // rules to use when parsing value
|
||||
converters utils.DataConverters // set of converters to apply on output
|
||||
filters utils.RSRFilters // The value to compare when used as filter
|
||||
@@ -223,7 +247,7 @@ type RSRParser struct {
|
||||
|
||||
// AttrName exports the attribute name of the RSRParser
|
||||
func (prsr *RSRParser) AttrName() string {
|
||||
return prsr.attrName
|
||||
return prsr.path
|
||||
}
|
||||
|
||||
// Compile parses Rules string and repopulates other fields
|
||||
@@ -250,8 +274,8 @@ func (prsr *RSRParser) RegexpMatched() bool {
|
||||
|
||||
// parseValue the field value from a string
|
||||
func (prsr *RSRParser) parseValue(value string) string {
|
||||
if prsr.attrValue != "" { // Enforce parsing of static values
|
||||
return prsr.attrValue
|
||||
if prsr.path == "" { // Enforce parsing of static values
|
||||
return prsr.Rules
|
||||
}
|
||||
for _, rsRule := range prsr.rsrRules {
|
||||
value = rsRule.Process(value)
|
||||
@@ -271,20 +295,11 @@ func (prsr *RSRParser) ParseValue(value interface{}) (out string, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// ParseEvent will parse the value out considering converters and filters
|
||||
func (prsr *RSRParser) ParseEvent(ev map[string]interface{}) (out string, err error) {
|
||||
val, has := ev[prsr.attrName]
|
||||
if !has && prsr.attrValue == "" {
|
||||
return "", utils.ErrNotFound
|
||||
}
|
||||
return prsr.ParseValue(val)
|
||||
}
|
||||
|
||||
func (prsr *RSRParser) ParseDataProvider(dP utils.DataProvider, separator string) (out string, err error) {
|
||||
var outStr string
|
||||
if prsr.attrValue == "" {
|
||||
if prsr.path != "" {
|
||||
if outStr, err = dP.FieldAsString(
|
||||
strings.Split(prsr.attrName, separator)); err != nil &&
|
||||
strings.Split(prsr.path, separator)); err != nil &&
|
||||
(err != utils.ErrNotFound || prsr.filters.FilterRules() != "^$") {
|
||||
return
|
||||
}
|
||||
@@ -294,9 +309,9 @@ func (prsr *RSRParser) ParseDataProvider(dP utils.DataProvider, separator string
|
||||
|
||||
func (prsr *RSRParser) ParseDataProviderWithInterfaces(dP utils.DataProvider, separator string) (out string, err error) {
|
||||
var outIface interface{}
|
||||
if prsr.attrValue == "" {
|
||||
if prsr.path != "" {
|
||||
if outIface, err = dP.FieldAsInterface(
|
||||
strings.Split(prsr.attrName, separator)); err != nil &&
|
||||
strings.Split(prsr.path, separator)); err != nil &&
|
||||
(err != utils.ErrNotFound || prsr.filters.FilterRules() != "^$") {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -27,18 +27,18 @@ import (
|
||||
)
|
||||
|
||||
func TestNewRSRParsers(t *testing.T) {
|
||||
ruleStr := `Value1;Heade2=Value2;~Header3(Val3&!Val4);~Header4:s/a/${1}b/{*duration_seconds&*round:2}(b&c);Value5{*duration_seconds&*round:2}`
|
||||
ruleStr := `Value1;Value2;~Header3(Val3&!Val4);~Header4:s/a/${1}b/{*duration_seconds&*round:2}(b&c);Value5{*duration_seconds&*round:2}`
|
||||
eRSRParsers := RSRParsers{
|
||||
&RSRParser{Rules: "Value1", AllFiltersMatch: true, attrValue: "Value1"},
|
||||
&RSRParser{Rules: "Heade2=Value2", AllFiltersMatch: true, attrName: "Heade2", attrValue: "Value2"},
|
||||
&RSRParser{Rules: "~Header3(Val3&!Val4)", AllFiltersMatch: true, attrName: "Header3",
|
||||
&RSRParser{Rules: "Value1", AllFiltersMatch: true},
|
||||
&RSRParser{Rules: "Value2", AllFiltersMatch: true},
|
||||
&RSRParser{Rules: "~Header3(Val3&!Val4)", AllFiltersMatch: true, path: "Header3",
|
||||
filters: utils.RSRFilters{utils.NewRSRFilterMustCompile("Val3"),
|
||||
utils.NewRSRFilterMustCompile("!Val4")}},
|
||||
|
||||
&RSRParser{Rules: "~Header4:s/a/${1}b/{*duration_seconds&*round:2}(b&c)", AllFiltersMatch: true,
|
||||
attrName: "Header4",
|
||||
path: "Header4",
|
||||
rsrRules: []*utils.ReSearchReplace{
|
||||
&utils.ReSearchReplace{
|
||||
{
|
||||
SearchRegexp: regexp.MustCompile(`a`),
|
||||
ReplaceTemplate: "${1}b"}},
|
||||
converters: utils.DataConverters{utils.NewDataConverterMustCompile("*duration_seconds"),
|
||||
@@ -48,7 +48,6 @@ func TestNewRSRParsers(t *testing.T) {
|
||||
},
|
||||
|
||||
&RSRParser{Rules: "Value5{*duration_seconds&*round:2}", AllFiltersMatch: true,
|
||||
attrValue: "Value5",
|
||||
converters: utils.DataConverters{utils.NewDataConverterMustCompile("*duration_seconds"),
|
||||
utils.NewDataConverterMustCompile("*round:2")},
|
||||
},
|
||||
@@ -62,10 +61,10 @@ func TestNewRSRParsers(t *testing.T) {
|
||||
|
||||
func TestRSRParserCompile(t *testing.T) {
|
||||
ePrsr := &RSRParser{
|
||||
Rules: "~Header4:s/a/${1}b/{*duration_seconds&*round:2}(b&c)",
|
||||
attrName: "Header4",
|
||||
Rules: "~Header4:s/a/${1}b/{*duration_seconds&*round:2}(b&c)",
|
||||
path: "Header4",
|
||||
rsrRules: []*utils.ReSearchReplace{
|
||||
&utils.ReSearchReplace{
|
||||
{
|
||||
SearchRegexp: regexp.MustCompile(`a`),
|
||||
ReplaceTemplate: "${1}b"}},
|
||||
converters: utils.DataConverters{utils.NewDataConverterMustCompile("*duration_seconds"),
|
||||
@@ -83,20 +82,6 @@ func TestRSRParserCompile(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRSRParsersParseEvent(t *testing.T) {
|
||||
prsrs := NewRSRParsersMustCompile("~Header1;|;~Header2", true, utils.INFIELD_SEP)
|
||||
ev := map[string]interface{}{
|
||||
"Header1": "Value1",
|
||||
"Header2": "Value2",
|
||||
}
|
||||
eOut := "Value1|Value2"
|
||||
if out, err := prsrs.ParseEvent(ev); err != nil {
|
||||
t.Error(err)
|
||||
} else if eOut != out {
|
||||
t.Errorf("expecting: %s, received: %s", eOut, out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRSRParserConstant(t *testing.T) {
|
||||
rule := "cgrates.org"
|
||||
rsrParsers, err := NewRSRParsers(rule, true, utils.INFIELD_SEP)
|
||||
@@ -123,36 +108,6 @@ func TestRSRParserNotConstant(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRSRParsersParseEvent2(t *testing.T) {
|
||||
prsrs := NewRSRParsersMustCompile("~Header1.Test;|;~Header2.Test", true, utils.INFIELD_SEP)
|
||||
ev := map[string]interface{}{
|
||||
"Header1.Test": "Value1",
|
||||
"Header2.Test": "Value2",
|
||||
}
|
||||
eOut := "Value1|Value2"
|
||||
if out, err := prsrs.ParseEvent(ev); err != nil {
|
||||
t.Error(err)
|
||||
} else if eOut != out {
|
||||
t.Errorf("expecting: %s, received: %s", eOut, out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRSRParsersParseEvent3(t *testing.T) {
|
||||
prsr, err := NewRSRParser("~Category:s/(.*)/${1}_suffix/", true)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
ev := map[string]interface{}{
|
||||
"Category": "call",
|
||||
}
|
||||
eOut := "call_suffix"
|
||||
if out, err := prsr.ParseEvent(ev); err != nil {
|
||||
t.Error(err)
|
||||
} else if eOut != out {
|
||||
t.Errorf("expecting: %s, received: %s", eOut, out)
|
||||
}
|
||||
}
|
||||
|
||||
// TestRSRParsersParseInnerBraces makes sure the inner braces are allowed in a filter rule
|
||||
func TestRSRParsersParseInnerBracket(t *testing.T) {
|
||||
rule := "~*req.Service-Information.IN-Information.CalledPartyAddress(~^(00)*(33|0)890240004$)"
|
||||
@@ -165,3 +120,64 @@ func TestRSRParsersParseInnerBracket(t *testing.T) {
|
||||
t.Errorf("expecting: %s, received: %s", expAttrName, prsr.AttrName())
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewRSRParsersConstant(t *testing.T) {
|
||||
ruleStr := "`>;q=0.7;expires=3600`"
|
||||
eRSRParsers := RSRParsers{
|
||||
&RSRParser{Rules: ">;q=0.7;expires=3600", AllFiltersMatch: true},
|
||||
}
|
||||
if rsrParsers, err := NewRSRParsers(ruleStr, true, utils.INFIELD_SEP); err != nil {
|
||||
t.Error("Unexpected error: ", err.Error())
|
||||
} else if !reflect.DeepEqual(eRSRParsers, rsrParsers) {
|
||||
t.Errorf("expecting: %+v, received: %+v", eRSRParsers, rsrParsers)
|
||||
} else if out, err := rsrParsers.ParseDataProvider(utils.MapStorage{}, utils.NestingSep); err != nil {
|
||||
t.Error(err)
|
||||
} else if expected := ">;q=0.7;expires=3600"; out != expected {
|
||||
t.Errorf("Expected %+v ,received %+v", expected, out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewRSRParsersConstant2(t *testing.T) {
|
||||
ruleStr := "constant;something`>;q=0.7;expires=3600`new;constant"
|
||||
if rsrParsers, err := NewRSRParsers(ruleStr, true, utils.INFIELD_SEP); err != nil {
|
||||
t.Error("Unexpected error: ", err.Error())
|
||||
} else if out, err := rsrParsers.ParseDataProvider(utils.MapStorage{}, utils.NestingSep); err != nil {
|
||||
t.Error(err)
|
||||
} else if expected := "constantsomething>;q=0.7;expires=3600newconstant"; out != expected {
|
||||
t.Errorf("Expected %q ,received %q", expected, out)
|
||||
}
|
||||
|
||||
ruleStr = "constant;`>;q=0.7;expires=3600`;constant"
|
||||
if rsrParsers, err := NewRSRParsers(ruleStr, true, utils.INFIELD_SEP); err != nil {
|
||||
t.Error("Unexpected error: ", err.Error())
|
||||
} else if out, err := rsrParsers.ParseDataProvider(utils.MapStorage{}, utils.NestingSep); err != nil {
|
||||
t.Error(err)
|
||||
} else if expected := "constant>;q=0.7;expires=3600constant"; out != expected {
|
||||
t.Errorf("Expected %q ,received %q", expected, out)
|
||||
}
|
||||
|
||||
ruleStr = "constant;`>;q=0.7;expires=3600`constant"
|
||||
if rsrParsers, err := NewRSRParsers(ruleStr, true, utils.INFIELD_SEP); err != nil {
|
||||
t.Error("Unexpected error: ", err.Error())
|
||||
} else if out, err := rsrParsers.ParseDataProvider(utils.MapStorage{}, utils.NestingSep); err != nil {
|
||||
t.Error(err)
|
||||
} else if expected := "constant>;q=0.7;expires=3600constant"; out != expected {
|
||||
t.Errorf("Expected %q ,received %q", expected, out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRSRParserCompileConstant(t *testing.T) {
|
||||
ePrsr := &RSRParser{
|
||||
Rules: "*constant:>;q=0.7;expires=3600",
|
||||
AllFiltersMatch: true,
|
||||
}
|
||||
prsr := &RSRParser{
|
||||
Rules: "*constant:>;q=0.7;expires=3600",
|
||||
AllFiltersMatch: true,
|
||||
}
|
||||
if err := prsr.Compile(); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(ePrsr, prsr) {
|
||||
t.Errorf("expecting: %+v, received: %+v", ePrsr, prsr)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +95,6 @@ func (dbcfg *StorDbCfg) loadFromJsonCfg(jsnDbCfg *DbJsonCfg) (err error) {
|
||||
dbcfg.SSLMode = *jsnDbCfg.Sslmode
|
||||
}
|
||||
if jsnDbCfg.Items != nil {
|
||||
dbcfg.Items = make(map[string]*ItemOpt)
|
||||
for kJsn, vJsn := range *jsnDbCfg.Items {
|
||||
val := new(ItemOpt)
|
||||
if err := val.loadFromJsonCfg(vJsn); err != nil {
|
||||
|
||||
@@ -135,6 +135,7 @@ func TestStoreDbCfgloadFromJsonCfgPort(t *testing.T) {
|
||||
|
||||
func TestStorDbCfgAsMapInterface(t *testing.T) {
|
||||
var dbcfg StorDbCfg
|
||||
dbcfg.Items = make(map[string]*ItemOpt)
|
||||
cfgJSONStr := `{
|
||||
"stor_db": {
|
||||
"db_type": "*mysql",
|
||||
|
||||
@@ -257,6 +257,7 @@ func (me MapEvent) AsCDR(cfg *config.CGRConfig, tnt, tmz string) (cdr *CDR, err
|
||||
if cdr.CostDetails, err = IfaceAsEventCost(v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cdr.CostDetails.initCache()
|
||||
case utils.ExtraInfo:
|
||||
cdr.ExtraInfo = utils.IfaceAsString(v)
|
||||
case utils.OrderID:
|
||||
@@ -265,11 +266,6 @@ func (me MapEvent) AsCDR(cfg *config.CGRConfig, tnt, tmz string) (cdr *CDR, err
|
||||
}
|
||||
}
|
||||
}
|
||||
if cdr.CostDetails == nil {
|
||||
cdr.CostDetails = NewBareEventCost()
|
||||
} else {
|
||||
cdr.CostDetails.initCache()
|
||||
}
|
||||
if cfg != nil {
|
||||
cdr.AddDefaults(cfg)
|
||||
}
|
||||
|
||||
@@ -311,7 +311,7 @@ func TestMapEventAsMapString(t *testing.T) {
|
||||
|
||||
func TestMapEventAsCDR(t *testing.T) {
|
||||
me := NewMapEvent(nil)
|
||||
expected := &CDR{Cost: -1.0, ExtraFields: make(map[string]string), CostDetails: NewBareEventCost()}
|
||||
expected := &CDR{Cost: -1.0, ExtraFields: make(map[string]string)}
|
||||
if rply, err := me.AsCDR(nil, utils.EmptyString, utils.EmptyString); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(expected, rply) {
|
||||
@@ -330,7 +330,6 @@ func TestMapEventAsCDR(t *testing.T) {
|
||||
Tenant: cfg.GeneralCfg().DefaultTenant,
|
||||
Category: cfg.GeneralCfg().DefaultCategory,
|
||||
ExtraFields: make(map[string]string),
|
||||
CostDetails: NewBareEventCost(),
|
||||
}
|
||||
if rply, err := me.AsCDR(cfg, utils.EmptyString, utils.EmptyString); err != nil {
|
||||
t.Error(err)
|
||||
@@ -372,8 +371,7 @@ func TestMapEventAsCDR(t *testing.T) {
|
||||
|
||||
me = MapEvent{"ExtraField1": 5, "ExtraField2": "extra"}
|
||||
expected = &CDR{
|
||||
Cost: -1.0,
|
||||
CostDetails: NewBareEventCost(),
|
||||
Cost: -1.0,
|
||||
ExtraFields: map[string]string{
|
||||
"ExtraField1": "5",
|
||||
"ExtraField2": "extra",
|
||||
@@ -405,7 +403,6 @@ func TestMapEventAsCDR(t *testing.T) {
|
||||
Tenant: cfg.GeneralCfg().DefaultTenant,
|
||||
Category: cfg.GeneralCfg().DefaultCategory,
|
||||
ExtraInfo: "ACCOUNT_NOT_FOUND",
|
||||
CostDetails: NewBareEventCost(),
|
||||
}
|
||||
if rply, err := me.AsCDR(cfg, utils.EmptyString, utils.EmptyString); err != nil {
|
||||
t.Error(err)
|
||||
@@ -449,8 +446,7 @@ func TestMapEventAsCDR(t *testing.T) {
|
||||
"ExtraField1": "5",
|
||||
"ExtraField2": "extra",
|
||||
},
|
||||
ExtraInfo: "ACCOUNT_NOT_FOUND",
|
||||
CostDetails: NewBareEventCost(),
|
||||
ExtraInfo: "ACCOUNT_NOT_FOUND",
|
||||
}
|
||||
if rply, err := me.AsCDR(cfg, utils.EmptyString, utils.EmptyString); err != nil {
|
||||
t.Error(err)
|
||||
|
||||
@@ -625,7 +625,7 @@ func TestSafEventAsMapString(t *testing.T) {
|
||||
|
||||
func TestSafEventAsCDR(t *testing.T) {
|
||||
se := SafEvent{Me: NewMapEvent(nil)}
|
||||
expected := &CDR{Cost: -1.0, ExtraFields: make(map[string]string), CostDetails: NewBareEventCost()}
|
||||
expected := &CDR{Cost: -1.0, ExtraFields: make(map[string]string)}
|
||||
if rply, err := se.AsCDR(nil, utils.EmptyString, utils.EmptyString); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(expected, rply) {
|
||||
@@ -644,7 +644,6 @@ func TestSafEventAsCDR(t *testing.T) {
|
||||
Tenant: cfg.GeneralCfg().DefaultTenant,
|
||||
Category: cfg.GeneralCfg().DefaultCategory,
|
||||
ExtraFields: make(map[string]string),
|
||||
CostDetails: NewBareEventCost(),
|
||||
}
|
||||
if rply, err := se.AsCDR(cfg, utils.EmptyString, utils.EmptyString); err != nil {
|
||||
t.Error(err)
|
||||
@@ -677,8 +676,7 @@ func TestSafEventAsCDR(t *testing.T) {
|
||||
}
|
||||
se = SafEvent{Me: MapEvent{"ExtraField1": 5, "ExtraField2": "extra"}}
|
||||
expected = &CDR{
|
||||
Cost: -1.0,
|
||||
CostDetails: NewBareEventCost(),
|
||||
Cost: -1.0,
|
||||
ExtraFields: map[string]string{
|
||||
"ExtraField1": "5",
|
||||
"ExtraField2": "extra",
|
||||
@@ -708,7 +706,6 @@ func TestSafEventAsCDR(t *testing.T) {
|
||||
RequestType: cfg.GeneralCfg().DefaultReqType,
|
||||
Tenant: cfg.GeneralCfg().DefaultTenant,
|
||||
Category: cfg.GeneralCfg().DefaultCategory,
|
||||
CostDetails: NewBareEventCost(),
|
||||
}
|
||||
if rply, err := se.AsCDR(cfg, utils.EmptyString, utils.EmptyString); err != nil {
|
||||
t.Error(err)
|
||||
@@ -742,7 +739,6 @@ func TestSafEventAsCDR(t *testing.T) {
|
||||
ToR: utils.VOICE,
|
||||
RequestType: cfg.GeneralCfg().DefaultReqType,
|
||||
Category: cfg.GeneralCfg().DefaultCategory,
|
||||
CostDetails: NewBareEventCost(),
|
||||
}
|
||||
if rply, err := se.AsCDR(cfg, "itsyscom.com", utils.EmptyString); err != nil {
|
||||
t.Error(err)
|
||||
|
||||
@@ -34,158 +34,158 @@ import (
|
||||
func newInternalDBCfg(itemsCacheCfg map[string]*config.ItemOpt, isDataDB bool) map[string]*ltcache.CacheConfig {
|
||||
if isDataDB {
|
||||
return map[string]*ltcache.CacheConfig{
|
||||
utils.CacheDestinations: <cache.CacheConfig{
|
||||
utils.CacheDestinations: {
|
||||
MaxItems: itemsCacheCfg[utils.CacheDestinations].Limit,
|
||||
TTL: itemsCacheCfg[utils.CacheDestinations].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.CacheDestinations].StaticTTL,
|
||||
},
|
||||
utils.CacheReverseDestinations: <cache.CacheConfig{
|
||||
utils.CacheReverseDestinations: {
|
||||
MaxItems: itemsCacheCfg[utils.CacheReverseDestinations].Limit,
|
||||
TTL: itemsCacheCfg[utils.CacheReverseDestinations].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.CacheReverseDestinations].StaticTTL,
|
||||
},
|
||||
utils.CacheActions: <cache.CacheConfig{
|
||||
utils.CacheActions: {
|
||||
MaxItems: itemsCacheCfg[utils.CacheActions].Limit,
|
||||
TTL: itemsCacheCfg[utils.CacheActions].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.CacheActions].StaticTTL,
|
||||
},
|
||||
utils.CacheActionPlans: <cache.CacheConfig{
|
||||
utils.CacheActionPlans: {
|
||||
MaxItems: itemsCacheCfg[utils.CacheActionPlans].Limit,
|
||||
TTL: itemsCacheCfg[utils.CacheActionPlans].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.CacheActionPlans].StaticTTL,
|
||||
},
|
||||
utils.CacheAccountActionPlans: <cache.CacheConfig{
|
||||
utils.CacheAccountActionPlans: {
|
||||
MaxItems: itemsCacheCfg[utils.CacheAccountActionPlans].Limit,
|
||||
TTL: itemsCacheCfg[utils.CacheAccountActionPlans].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.CacheAccountActionPlans].StaticTTL,
|
||||
},
|
||||
utils.CacheActionTriggers: <cache.CacheConfig{
|
||||
utils.CacheActionTriggers: {
|
||||
MaxItems: itemsCacheCfg[utils.CacheActionTriggers].Limit,
|
||||
TTL: itemsCacheCfg[utils.CacheActionTriggers].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.CacheActionTriggers].StaticTTL,
|
||||
},
|
||||
utils.CacheRatingPlans: <cache.CacheConfig{
|
||||
utils.CacheRatingPlans: {
|
||||
MaxItems: itemsCacheCfg[utils.CacheRatingPlans].Limit,
|
||||
TTL: itemsCacheCfg[utils.CacheRatingPlans].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.CacheRatingPlans].StaticTTL,
|
||||
},
|
||||
utils.CacheRatingProfiles: <cache.CacheConfig{
|
||||
utils.CacheRatingProfiles: {
|
||||
MaxItems: itemsCacheCfg[utils.CacheRatingProfiles].Limit,
|
||||
TTL: itemsCacheCfg[utils.CacheRatingProfiles].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.CacheRatingProfiles].StaticTTL,
|
||||
},
|
||||
utils.CacheAccounts: <cache.CacheConfig{
|
||||
utils.CacheAccounts: {
|
||||
MaxItems: itemsCacheCfg[utils.CacheAccounts].Limit,
|
||||
TTL: itemsCacheCfg[utils.CacheAccounts].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.CacheAccounts].StaticTTL,
|
||||
},
|
||||
utils.CacheSharedGroups: <cache.CacheConfig{
|
||||
utils.CacheSharedGroups: {
|
||||
MaxItems: itemsCacheCfg[utils.CacheSharedGroups].Limit,
|
||||
TTL: itemsCacheCfg[utils.CacheSharedGroups].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.CacheSharedGroups].StaticTTL,
|
||||
},
|
||||
|
||||
utils.CacheTimings: <cache.CacheConfig{
|
||||
utils.CacheTimings: {
|
||||
MaxItems: itemsCacheCfg[utils.CacheTimings].Limit,
|
||||
TTL: itemsCacheCfg[utils.CacheTimings].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.CacheTimings].StaticTTL,
|
||||
},
|
||||
utils.CacheFilters: <cache.CacheConfig{
|
||||
utils.CacheFilters: {
|
||||
MaxItems: itemsCacheCfg[utils.CacheFilters].Limit,
|
||||
TTL: itemsCacheCfg[utils.CacheFilters].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.CacheFilters].StaticTTL,
|
||||
},
|
||||
utils.CacheResourceProfiles: <cache.CacheConfig{
|
||||
utils.CacheResourceProfiles: {
|
||||
MaxItems: itemsCacheCfg[utils.CacheResourceProfiles].Limit,
|
||||
TTL: itemsCacheCfg[utils.CacheResourceProfiles].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.CacheResourceProfiles].StaticTTL,
|
||||
},
|
||||
utils.CacheResourceFilterIndexes: <cache.CacheConfig{
|
||||
utils.CacheResourceFilterIndexes: {
|
||||
MaxItems: itemsCacheCfg[utils.MetaFilterIndexes].Limit,
|
||||
TTL: itemsCacheCfg[utils.MetaFilterIndexes].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.MetaFilterIndexes].StaticTTL,
|
||||
},
|
||||
utils.CacheResources: <cache.CacheConfig{
|
||||
utils.CacheResources: {
|
||||
MaxItems: itemsCacheCfg[utils.CacheResources].Limit,
|
||||
TTL: itemsCacheCfg[utils.CacheResources].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.CacheResources].StaticTTL,
|
||||
},
|
||||
utils.CacheStatFilterIndexes: <cache.CacheConfig{
|
||||
utils.CacheStatFilterIndexes: {
|
||||
MaxItems: itemsCacheCfg[utils.MetaFilterIndexes].Limit,
|
||||
TTL: itemsCacheCfg[utils.MetaFilterIndexes].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.MetaFilterIndexes].StaticTTL,
|
||||
},
|
||||
utils.CacheStatQueueProfiles: <cache.CacheConfig{
|
||||
utils.CacheStatQueueProfiles: {
|
||||
MaxItems: itemsCacheCfg[utils.CacheStatQueueProfiles].Limit,
|
||||
TTL: itemsCacheCfg[utils.CacheStatQueueProfiles].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.CacheStatQueueProfiles].StaticTTL,
|
||||
},
|
||||
utils.CacheStatQueues: <cache.CacheConfig{
|
||||
utils.CacheStatQueues: {
|
||||
MaxItems: itemsCacheCfg[utils.CacheStatQueues].Limit,
|
||||
TTL: itemsCacheCfg[utils.CacheStatQueues].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.CacheStatQueues].StaticTTL,
|
||||
},
|
||||
utils.CacheThresholdFilterIndexes: <cache.CacheConfig{
|
||||
utils.CacheThresholdFilterIndexes: {
|
||||
MaxItems: itemsCacheCfg[utils.MetaFilterIndexes].Limit,
|
||||
TTL: itemsCacheCfg[utils.MetaFilterIndexes].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.MetaFilterIndexes].StaticTTL,
|
||||
},
|
||||
utils.CacheThresholdProfiles: <cache.CacheConfig{
|
||||
utils.CacheThresholdProfiles: {
|
||||
MaxItems: itemsCacheCfg[utils.CacheThresholdProfiles].Limit,
|
||||
TTL: itemsCacheCfg[utils.CacheThresholdProfiles].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.CacheThresholdProfiles].StaticTTL,
|
||||
},
|
||||
utils.CacheThresholds: <cache.CacheConfig{
|
||||
utils.CacheThresholds: {
|
||||
MaxItems: itemsCacheCfg[utils.CacheThresholds].Limit,
|
||||
TTL: itemsCacheCfg[utils.CacheThresholds].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.CacheThresholds].StaticTTL,
|
||||
},
|
||||
utils.CacheSupplierFilterIndexes: <cache.CacheConfig{
|
||||
utils.CacheSupplierFilterIndexes: {
|
||||
MaxItems: itemsCacheCfg[utils.MetaFilterIndexes].Limit,
|
||||
TTL: itemsCacheCfg[utils.MetaFilterIndexes].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.MetaFilterIndexes].StaticTTL,
|
||||
},
|
||||
utils.CacheSupplierProfiles: <cache.CacheConfig{
|
||||
utils.CacheSupplierProfiles: {
|
||||
MaxItems: itemsCacheCfg[utils.CacheSupplierProfiles].Limit,
|
||||
TTL: itemsCacheCfg[utils.CacheSupplierProfiles].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.CacheSupplierProfiles].StaticTTL,
|
||||
},
|
||||
utils.CacheChargerFilterIndexes: <cache.CacheConfig{
|
||||
utils.CacheChargerFilterIndexes: {
|
||||
MaxItems: itemsCacheCfg[utils.MetaFilterIndexes].Limit,
|
||||
TTL: itemsCacheCfg[utils.MetaFilterIndexes].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.MetaFilterIndexes].StaticTTL,
|
||||
},
|
||||
utils.CacheChargerProfiles: <cache.CacheConfig{
|
||||
utils.CacheChargerProfiles: {
|
||||
MaxItems: itemsCacheCfg[utils.CacheChargerProfiles].Limit,
|
||||
TTL: itemsCacheCfg[utils.CacheChargerProfiles].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.CacheChargerProfiles].StaticTTL,
|
||||
},
|
||||
utils.CacheAttributeFilterIndexes: <cache.CacheConfig{
|
||||
utils.CacheAttributeFilterIndexes: {
|
||||
MaxItems: itemsCacheCfg[utils.MetaFilterIndexes].Limit,
|
||||
TTL: itemsCacheCfg[utils.MetaFilterIndexes].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.MetaFilterIndexes].StaticTTL,
|
||||
},
|
||||
utils.CacheAttributeProfiles: <cache.CacheConfig{
|
||||
utils.CacheAttributeProfiles: {
|
||||
MaxItems: itemsCacheCfg[utils.CacheAttributeProfiles].Limit,
|
||||
TTL: itemsCacheCfg[utils.CacheAttributeProfiles].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.CacheAttributeProfiles].StaticTTL,
|
||||
},
|
||||
utils.CacheDispatcherFilterIndexes: <cache.CacheConfig{
|
||||
utils.CacheDispatcherFilterIndexes: {
|
||||
MaxItems: itemsCacheCfg[utils.MetaFilterIndexes].Limit,
|
||||
TTL: itemsCacheCfg[utils.MetaFilterIndexes].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.MetaFilterIndexes].StaticTTL,
|
||||
},
|
||||
utils.CacheDispatcherProfiles: <cache.CacheConfig{
|
||||
utils.CacheDispatcherProfiles: {
|
||||
MaxItems: itemsCacheCfg[utils.CacheDispatcherProfiles].Limit,
|
||||
TTL: itemsCacheCfg[utils.CacheDispatcherProfiles].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.CacheDispatcherProfiles].StaticTTL,
|
||||
},
|
||||
utils.CacheDispatcherHosts: <cache.CacheConfig{
|
||||
utils.CacheDispatcherHosts: {
|
||||
MaxItems: itemsCacheCfg[utils.CacheDispatcherHosts].Limit,
|
||||
TTL: itemsCacheCfg[utils.CacheDispatcherHosts].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.CacheDispatcherHosts].StaticTTL,
|
||||
},
|
||||
utils.CacheLoadIDs: <cache.CacheConfig{
|
||||
utils.CacheLoadIDs: {
|
||||
MaxItems: itemsCacheCfg[utils.CacheLoadIDs].Limit,
|
||||
TTL: itemsCacheCfg[utils.CacheLoadIDs].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.CacheLoadIDs].StaticTTL,
|
||||
@@ -193,117 +193,117 @@ func newInternalDBCfg(itemsCacheCfg map[string]*config.ItemOpt, isDataDB bool) m
|
||||
}
|
||||
} else {
|
||||
return map[string]*ltcache.CacheConfig{
|
||||
utils.TBLVersions: <cache.CacheConfig{
|
||||
utils.TBLVersions: {
|
||||
MaxItems: itemsCacheCfg[utils.TBLVersions].Limit,
|
||||
TTL: itemsCacheCfg[utils.TBLVersions].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.TBLVersions].StaticTTL,
|
||||
},
|
||||
utils.TBLTPTimings: <cache.CacheConfig{
|
||||
utils.TBLTPTimings: {
|
||||
MaxItems: itemsCacheCfg[utils.TBLTPTimings].Limit,
|
||||
TTL: itemsCacheCfg[utils.TBLTPTimings].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.TBLTPTimings].StaticTTL,
|
||||
},
|
||||
utils.TBLTPDestinations: <cache.CacheConfig{
|
||||
utils.TBLTPDestinations: {
|
||||
MaxItems: itemsCacheCfg[utils.TBLTPDestinations].Limit,
|
||||
TTL: itemsCacheCfg[utils.TBLTPDestinations].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.TBLTPDestinations].StaticTTL,
|
||||
},
|
||||
utils.TBLTPRates: <cache.CacheConfig{
|
||||
utils.TBLTPRates: {
|
||||
MaxItems: itemsCacheCfg[utils.TBLTPRates].Limit,
|
||||
TTL: itemsCacheCfg[utils.TBLTPRates].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.TBLTPRates].StaticTTL,
|
||||
},
|
||||
utils.TBLTPDestinationRates: <cache.CacheConfig{
|
||||
utils.TBLTPDestinationRates: {
|
||||
MaxItems: itemsCacheCfg[utils.TBLTPDestinationRates].Limit,
|
||||
TTL: itemsCacheCfg[utils.TBLTPDestinationRates].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.TBLTPDestinationRates].StaticTTL,
|
||||
},
|
||||
utils.TBLTPRatingPlans: <cache.CacheConfig{
|
||||
utils.TBLTPRatingPlans: {
|
||||
MaxItems: itemsCacheCfg[utils.TBLTPRatingPlans].Limit,
|
||||
TTL: itemsCacheCfg[utils.TBLTPRatingPlans].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.TBLTPRatingPlans].StaticTTL,
|
||||
},
|
||||
utils.TBLTPRateProfiles: <cache.CacheConfig{
|
||||
utils.TBLTPRateProfiles: {
|
||||
MaxItems: itemsCacheCfg[utils.TBLTPRateProfiles].Limit,
|
||||
TTL: itemsCacheCfg[utils.TBLTPRateProfiles].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.TBLTPRateProfiles].StaticTTL,
|
||||
},
|
||||
utils.TBLTPSharedGroups: <cache.CacheConfig{
|
||||
utils.TBLTPSharedGroups: {
|
||||
MaxItems: itemsCacheCfg[utils.TBLTPSharedGroups].Limit,
|
||||
TTL: itemsCacheCfg[utils.TBLTPSharedGroups].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.TBLTPSharedGroups].StaticTTL,
|
||||
},
|
||||
utils.TBLTPActions: <cache.CacheConfig{
|
||||
utils.TBLTPActions: {
|
||||
MaxItems: itemsCacheCfg[utils.TBLTPActions].Limit,
|
||||
TTL: itemsCacheCfg[utils.TBLTPActions].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.TBLTPActions].StaticTTL,
|
||||
},
|
||||
utils.TBLTPActionTriggers: <cache.CacheConfig{
|
||||
utils.TBLTPActionTriggers: {
|
||||
MaxItems: itemsCacheCfg[utils.TBLTPActionTriggers].Limit,
|
||||
TTL: itemsCacheCfg[utils.TBLTPActionTriggers].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.TBLTPActionTriggers].StaticTTL,
|
||||
},
|
||||
utils.TBLTPAccountActions: <cache.CacheConfig{
|
||||
utils.TBLTPAccountActions: {
|
||||
MaxItems: itemsCacheCfg[utils.TBLTPAccountActions].Limit,
|
||||
TTL: itemsCacheCfg[utils.TBLTPAccountActions].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.TBLTPAccountActions].StaticTTL,
|
||||
},
|
||||
utils.TBLTPResources: <cache.CacheConfig{
|
||||
utils.TBLTPResources: {
|
||||
MaxItems: itemsCacheCfg[utils.TBLTPResources].Limit,
|
||||
TTL: itemsCacheCfg[utils.TBLTPResources].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.TBLTPResources].StaticTTL,
|
||||
},
|
||||
utils.TBLTPStats: <cache.CacheConfig{
|
||||
utils.TBLTPStats: {
|
||||
MaxItems: itemsCacheCfg[utils.TBLTPStats].Limit,
|
||||
TTL: itemsCacheCfg[utils.TBLTPStats].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.TBLTPStats].StaticTTL,
|
||||
},
|
||||
utils.TBLTPThresholds: <cache.CacheConfig{
|
||||
utils.TBLTPThresholds: {
|
||||
MaxItems: itemsCacheCfg[utils.TBLTPThresholds].Limit,
|
||||
TTL: itemsCacheCfg[utils.TBLTPThresholds].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.TBLTPThresholds].StaticTTL,
|
||||
},
|
||||
utils.TBLTPFilters: <cache.CacheConfig{
|
||||
utils.TBLTPFilters: {
|
||||
MaxItems: itemsCacheCfg[utils.TBLTPFilters].Limit,
|
||||
TTL: itemsCacheCfg[utils.TBLTPFilters].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.TBLTPFilters].StaticTTL,
|
||||
},
|
||||
utils.SessionCostsTBL: <cache.CacheConfig{
|
||||
utils.SessionCostsTBL: {
|
||||
MaxItems: itemsCacheCfg[utils.SessionCostsTBL].Limit,
|
||||
TTL: itemsCacheCfg[utils.SessionCostsTBL].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.SessionCostsTBL].StaticTTL,
|
||||
},
|
||||
utils.TBLTPActionPlans: <cache.CacheConfig{
|
||||
utils.TBLTPActionPlans: {
|
||||
MaxItems: itemsCacheCfg[utils.TBLTPActionPlans].Limit,
|
||||
TTL: itemsCacheCfg[utils.TBLTPActionPlans].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.TBLTPActionPlans].StaticTTL,
|
||||
},
|
||||
utils.TBLTPSuppliers: <cache.CacheConfig{
|
||||
utils.TBLTPSuppliers: {
|
||||
MaxItems: itemsCacheCfg[utils.TBLTPSuppliers].Limit,
|
||||
TTL: itemsCacheCfg[utils.TBLTPSuppliers].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.TBLTPSuppliers].StaticTTL,
|
||||
},
|
||||
utils.TBLTPAttributes: <cache.CacheConfig{
|
||||
utils.TBLTPAttributes: {
|
||||
MaxItems: itemsCacheCfg[utils.TBLTPAttributes].Limit,
|
||||
TTL: itemsCacheCfg[utils.TBLTPAttributes].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.TBLTPAttributes].StaticTTL,
|
||||
},
|
||||
utils.TBLTPChargers: <cache.CacheConfig{
|
||||
utils.TBLTPChargers: {
|
||||
MaxItems: itemsCacheCfg[utils.TBLTPChargers].Limit,
|
||||
TTL: itemsCacheCfg[utils.TBLTPChargers].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.TBLTPChargers].StaticTTL,
|
||||
},
|
||||
utils.TBLTPDispatchers: <cache.CacheConfig{
|
||||
utils.TBLTPDispatchers: {
|
||||
MaxItems: itemsCacheCfg[utils.TBLTPDispatchers].Limit,
|
||||
TTL: itemsCacheCfg[utils.TBLTPDispatchers].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.TBLTPDispatchers].StaticTTL,
|
||||
},
|
||||
utils.TBLTPDispatcherHosts: <cache.CacheConfig{
|
||||
utils.TBLTPDispatcherHosts: {
|
||||
MaxItems: itemsCacheCfg[utils.TBLTPDispatcherHosts].Limit,
|
||||
TTL: itemsCacheCfg[utils.TBLTPDispatcherHosts].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.TBLTPDispatcherHosts].StaticTTL,
|
||||
},
|
||||
utils.CDRsTBL: <cache.CacheConfig{
|
||||
utils.CDRsTBL: {
|
||||
MaxItems: itemsCacheCfg[utils.CDRsTBL].Limit,
|
||||
TTL: itemsCacheCfg[utils.CDRsTBL].TTL,
|
||||
StaticTTL: itemsCacheCfg[utils.CDRsTBL].StaticTTL,
|
||||
@@ -501,7 +501,7 @@ func (iDB *InternalDB) GetStorageType() string {
|
||||
}
|
||||
|
||||
func (iDB *InternalDB) IsDBEmpty() (resp bool, err error) {
|
||||
for cacheInstance, _ := range utils.CacheInstanceToPrefix {
|
||||
for cacheInstance := range utils.CacheInstanceToPrefix {
|
||||
if len(iDB.db.GetItemIDs(cacheInstance, utils.EmptyString)) != 0 {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
@@ -28,53 +28,53 @@ import (
|
||||
|
||||
func TestDataUpdateFromCSVOneFile(t *testing.T) {
|
||||
attrSFlds := []*config.FCTemplate{
|
||||
&config.FCTemplate{Tag: "TenantID",
|
||||
{Tag: "TenantID",
|
||||
Path: "Tenant",
|
||||
Type: utils.META_COMPOSED,
|
||||
Value: config.NewRSRParsersMustCompile("~0", true, utils.INFIELD_SEP),
|
||||
Mandatory: true},
|
||||
&config.FCTemplate{Tag: "ProfileID",
|
||||
{Tag: "ProfileID",
|
||||
Path: "ID",
|
||||
Type: utils.META_COMPOSED,
|
||||
Value: config.NewRSRParsersMustCompile("~1", true, utils.INFIELD_SEP),
|
||||
Mandatory: true},
|
||||
&config.FCTemplate{Tag: "Contexts",
|
||||
{Tag: "Contexts",
|
||||
Path: "Contexts",
|
||||
Type: utils.META_COMPOSED,
|
||||
Value: config.NewRSRParsersMustCompile("~2", true, utils.INFIELD_SEP)},
|
||||
&config.FCTemplate{Tag: "FilterIDs",
|
||||
{Tag: "FilterIDs",
|
||||
Path: "FilterIDs",
|
||||
Type: utils.META_COMPOSED,
|
||||
Value: config.NewRSRParsersMustCompile("~3", true, utils.INFIELD_SEP)},
|
||||
&config.FCTemplate{Tag: "ActivationInterval",
|
||||
{Tag: "ActivationInterval",
|
||||
Path: "ActivationInterval",
|
||||
Type: utils.META_COMPOSED,
|
||||
Value: config.NewRSRParsersMustCompile("~4", true, utils.INFIELD_SEP)},
|
||||
&config.FCTemplate{Tag: "Path",
|
||||
{Tag: "Path",
|
||||
Path: "Path",
|
||||
Type: utils.META_COMPOSED,
|
||||
Value: config.NewRSRParsersMustCompile("~5", true, utils.INFIELD_SEP)},
|
||||
&config.FCTemplate{Tag: "Initial",
|
||||
{Tag: "Initial",
|
||||
Path: "Initial",
|
||||
Type: utils.META_COMPOSED,
|
||||
Value: config.NewRSRParsersMustCompile("~6", true, utils.INFIELD_SEP)},
|
||||
&config.FCTemplate{Tag: "Substitute",
|
||||
{Tag: "Substitute",
|
||||
Path: "Substitute",
|
||||
Type: utils.META_COMPOSED,
|
||||
Value: config.NewRSRParsersMustCompile("~7", true, utils.INFIELD_SEP)},
|
||||
&config.FCTemplate{Tag: "Append",
|
||||
{Tag: "Append",
|
||||
Path: "Append",
|
||||
Type: utils.META_COMPOSED,
|
||||
Value: config.NewRSRParsersMustCompile("~8", true, utils.INFIELD_SEP)},
|
||||
&config.FCTemplate{Tag: "Weight",
|
||||
{Tag: "Weight",
|
||||
Path: "Weight",
|
||||
Type: utils.META_COMPOSED,
|
||||
Value: config.NewRSRParsersMustCompile("~9", true, utils.INFIELD_SEP)},
|
||||
}
|
||||
|
||||
rows := [][]string{
|
||||
[]string{"cgrates.org", "ATTR_1", "*sessions;*cdrs", "*string:Account:1007", "2014-01-14T00:00:00Z", "Account", "*any", "1001", "false", "10"},
|
||||
[]string{"cgrates.org", "ATTR_1", "", "", "", "Subject", "*any", "1001", "true", ""},
|
||||
{"cgrates.org", "ATTR_1", "*sessions;*cdrs", "*string:Account:1007", "2014-01-14T00:00:00Z", "Account", "*any", "1001", "false", "10"},
|
||||
{"cgrates.org", "ATTR_1", "", "", "", "Subject", "*any", "1001", "true", ""},
|
||||
}
|
||||
lData := make(LoaderData)
|
||||
if err := lData.UpdateFromCSV("Attributes.csv", rows[0], attrSFlds,
|
||||
@@ -118,53 +118,53 @@ func TestDataUpdateFromCSVOneFile(t *testing.T) {
|
||||
|
||||
func TestDataUpdateFromCSVOneFile2(t *testing.T) {
|
||||
attrSFlds := []*config.FCTemplate{
|
||||
&config.FCTemplate{Tag: "TenantID",
|
||||
{Tag: "TenantID",
|
||||
Path: "Tenant",
|
||||
Type: utils.MetaVariable,
|
||||
Value: config.NewRSRParsersMustCompile("~0", true, utils.INFIELD_SEP),
|
||||
Mandatory: true},
|
||||
&config.FCTemplate{Tag: "ProfileID",
|
||||
{Tag: "ProfileID",
|
||||
Path: "ID",
|
||||
Type: utils.MetaVariable,
|
||||
Value: config.NewRSRParsersMustCompile("~1", true, utils.INFIELD_SEP),
|
||||
Mandatory: true},
|
||||
&config.FCTemplate{Tag: "Contexts",
|
||||
{Tag: "Contexts",
|
||||
Path: "Contexts",
|
||||
Type: utils.MetaVariable,
|
||||
Value: config.NewRSRParsersMustCompile("~2", true, utils.INFIELD_SEP)},
|
||||
&config.FCTemplate{Tag: "FilterIDs",
|
||||
{Tag: "FilterIDs",
|
||||
Path: "FilterIDs",
|
||||
Type: utils.MetaVariable,
|
||||
Value: config.NewRSRParsersMustCompile("~3", true, utils.INFIELD_SEP)},
|
||||
&config.FCTemplate{Tag: "ActivationInterval",
|
||||
{Tag: "ActivationInterval",
|
||||
Path: "ActivationInterval",
|
||||
Type: utils.MetaVariable,
|
||||
Value: config.NewRSRParsersMustCompile("~4", true, utils.INFIELD_SEP)},
|
||||
&config.FCTemplate{Tag: "Path",
|
||||
{Tag: "Path",
|
||||
Path: "Path",
|
||||
Type: utils.MetaVariable,
|
||||
Value: config.NewRSRParsersMustCompile("~5", true, utils.INFIELD_SEP)},
|
||||
&config.FCTemplate{Tag: "Initial",
|
||||
{Tag: "Initial",
|
||||
Path: "Initial",
|
||||
Type: utils.MetaVariable,
|
||||
Value: config.NewRSRParsersMustCompile("~6", true, utils.INFIELD_SEP)},
|
||||
&config.FCTemplate{Tag: "Substitute",
|
||||
{Tag: "Substitute",
|
||||
Path: "Substitute",
|
||||
Type: utils.MetaVariable,
|
||||
Value: config.NewRSRParsersMustCompile("~7", true, utils.INFIELD_SEP)},
|
||||
&config.FCTemplate{Tag: "Append",
|
||||
{Tag: "Append",
|
||||
Path: "Append",
|
||||
Type: utils.MetaVariable,
|
||||
Value: config.NewRSRParsersMustCompile("~8", true, utils.INFIELD_SEP)},
|
||||
&config.FCTemplate{Tag: "Weight",
|
||||
{Tag: "Weight",
|
||||
Path: "Weight",
|
||||
Type: utils.MetaVariable,
|
||||
Value: config.NewRSRParsersMustCompile("~9", true, utils.INFIELD_SEP)},
|
||||
}
|
||||
|
||||
rows := [][]string{
|
||||
[]string{"cgrates.org", "ATTR_1", "*sessions;*cdrs", "*string:Account:1007", "2014-01-14T00:00:00Z", "Account", "*any", "1001", "false", "10"},
|
||||
[]string{"cgrates.org", "ATTR_1", "", "", "", "Subject", "*any", "1001", "true", ""},
|
||||
{"cgrates.org", "ATTR_1", "*sessions;*cdrs", "*string:Account:1007", "2014-01-14T00:00:00Z", "Account", "*any", "1001", "false", "10"},
|
||||
{"cgrates.org", "ATTR_1", "", "", "", "Subject", "*any", "1001", "true", ""},
|
||||
}
|
||||
lData := make(LoaderData)
|
||||
if err := lData.UpdateFromCSV("Attributes.csv", rows[0], attrSFlds,
|
||||
@@ -208,45 +208,45 @@ func TestDataUpdateFromCSVOneFile2(t *testing.T) {
|
||||
|
||||
func TestDataUpdateFromCSVMultiFiles(t *testing.T) {
|
||||
attrSFlds := []*config.FCTemplate{
|
||||
&config.FCTemplate{Tag: "TenantID",
|
||||
{Tag: "TenantID",
|
||||
Path: "Tenant",
|
||||
Type: utils.MetaString,
|
||||
Value: config.NewRSRParsersMustCompile("cgrates.org", true, utils.INFIELD_SEP),
|
||||
Mandatory: true},
|
||||
&config.FCTemplate{Tag: "ProfileID",
|
||||
{Tag: "ProfileID",
|
||||
Path: "ID",
|
||||
Type: utils.META_COMPOSED,
|
||||
Value: config.NewRSRParsersMustCompile("~File2.csv:1", true, utils.INFIELD_SEP),
|
||||
Mandatory: true},
|
||||
&config.FCTemplate{Tag: "Contexts",
|
||||
{Tag: "Contexts",
|
||||
Path: "Contexts",
|
||||
Type: utils.MetaString,
|
||||
Value: config.NewRSRParsersMustCompile("*any", true, utils.INFIELD_SEP)},
|
||||
&config.FCTemplate{Tag: "Path",
|
||||
{Tag: "Path",
|
||||
Path: "Path",
|
||||
Type: utils.META_COMPOSED,
|
||||
Value: config.NewRSRParsersMustCompile("~File1.csv:5", true, utils.INFIELD_SEP)},
|
||||
&config.FCTemplate{Tag: "Initial",
|
||||
{Tag: "Initial",
|
||||
Path: "Initial",
|
||||
Type: utils.META_COMPOSED,
|
||||
Value: config.NewRSRParsersMustCompile("~File1.csv:6", true, utils.INFIELD_SEP)},
|
||||
&config.FCTemplate{Tag: "Substitute",
|
||||
{Tag: "Substitute",
|
||||
Path: "Substitute",
|
||||
Type: utils.META_COMPOSED,
|
||||
Value: config.NewRSRParsersMustCompile("~File1.csv:7", true, utils.INFIELD_SEP)},
|
||||
&config.FCTemplate{Tag: "Append",
|
||||
{Tag: "Append",
|
||||
Path: "Append",
|
||||
Type: utils.MetaString,
|
||||
Value: config.NewRSRParsersMustCompile("true", true, utils.INFIELD_SEP)},
|
||||
&config.FCTemplate{Tag: "Weight",
|
||||
{Tag: "Weight",
|
||||
Path: "Weight",
|
||||
Type: utils.MetaString,
|
||||
Value: config.NewRSRParsersMustCompile("10", true, utils.INFIELD_SEP)},
|
||||
}
|
||||
|
||||
loadRun1 := map[string][]string{
|
||||
"File1.csv": []string{"ignored", "ignored", "ignored", "ignored", "ignored", "Subject", "*any", "1001", "ignored", "ignored"},
|
||||
"File2.csv": []string{"ignored", "ATTR_1"},
|
||||
"File1.csv": {"ignored", "ignored", "ignored", "ignored", "ignored", "Subject", "*any", "1001", "ignored", "ignored"},
|
||||
"File2.csv": {"ignored", "ATTR_1"},
|
||||
}
|
||||
lData := make(LoaderData)
|
||||
for fName, record := range loadRun1 {
|
||||
|
||||
@@ -8,6 +8,8 @@ cgrates (0.10.2~dev) UNRELEASED; urgency=medium
|
||||
* [General] Added *mo+extraDuration time support (e.g. *mo+1h will
|
||||
be time.Now() + 1 month + 1 hour)
|
||||
* [SessionS] Use correctly SessionTTLUsage when calculate end usage in case of terminate session from ttl mechanism
|
||||
* [RSRParsers] Removed attribute sistem from RSRParser
|
||||
* [RSRParsers] Added grave accent(`) char as a delimiter to not split tge RSR value
|
||||
|
||||
-- DanB <danb@cgrates.org> Tue, 12 May 2020 13:08:15 +0300
|
||||
|
||||
|
||||
Reference in New Issue
Block a user