diff --git a/apier/v1/cdrs_it_test.go b/apier/v1/cdrs_it_test.go index f94b17b92..49b4a3866 100644 --- a/apier/v1/cdrs_it_test.go +++ b/apier/v1/cdrs_it_test.go @@ -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, }, }, } diff --git a/apier/v1/config_it_test.go b/apier/v1/config_it_test.go index 4ebf7e9ab..1eaea3d14 100644 --- a/apier/v1/config_it_test.go +++ b/apier/v1/config_it_test.go @@ -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)) } } diff --git a/config/datadbcfg.go b/config/datadbcfg.go index f4dad7ee4..632cb0947 100644 --- a/config/datadbcfg.go +++ b/config/datadbcfg.go @@ -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 { diff --git a/config/rsrparser.go b/config/rsrparser.go index 286201402..526c2e5fc 100644 --- a/config/rsrparser.go +++ b/config/rsrparser.go @@ -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 } diff --git a/config/rsrparser_test.go b/config/rsrparser_test.go index ae3a2eb3d..69faf29f3 100644 --- a/config/rsrparser_test.go +++ b/config/rsrparser_test.go @@ -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) + } +} diff --git a/config/stordbcfg.go b/config/stordbcfg.go index ccd3218bf..fca0cf560 100644 --- a/config/stordbcfg.go +++ b/config/stordbcfg.go @@ -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 { diff --git a/config/stordbcfg_test.go b/config/stordbcfg_test.go index 1ef7e654d..816e04dd7 100644 --- a/config/stordbcfg_test.go +++ b/config/stordbcfg_test.go @@ -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", diff --git a/engine/mapevent.go b/engine/mapevent.go index 41959b564..e8accfbe8 100644 --- a/engine/mapevent.go +++ b/engine/mapevent.go @@ -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) } diff --git a/engine/mapevent_test.go b/engine/mapevent_test.go index d1b07f58b..84768fd9c 100644 --- a/engine/mapevent_test.go +++ b/engine/mapevent_test.go @@ -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) diff --git a/engine/safevent_test.go b/engine/safevent_test.go index 432459b98..ed1760aae 100644 --- a/engine/safevent_test.go +++ b/engine/safevent_test.go @@ -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) diff --git a/engine/storage_internal_datadb.go b/engine/storage_internal_datadb.go index a6a67ccb6..a924db839 100644 --- a/engine/storage_internal_datadb.go +++ b/engine/storage_internal_datadb.go @@ -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 } diff --git a/loaders/libloader_test.go b/loaders/libloader_test.go index 0546825d4..0d867f1f4 100644 --- a/loaders/libloader_test.go +++ b/loaders/libloader_test.go @@ -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 { diff --git a/packages/debian/changelog b/packages/debian/changelog index 10c30ec35..9f5deade1 100644 --- a/packages/debian/changelog +++ b/packages/debian/changelog @@ -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 Tue, 12 May 2020 13:08:15 +0300