Finish updating integration test after modification

This commit is contained in:
TeoV
2019-11-27 11:10:05 -05:00
parent 2ed33d6ab5
commit a2954c77c9
11 changed files with 117 additions and 130 deletions

View File

@@ -107,7 +107,7 @@ func (self *CsvRecordsProcessor) processFlatstoreRecord(record []string) ([]stri
// Takes the record from a slice and turns it into StoredCdrs, posting them to the cdrServer
func (self *CsvRecordsProcessor) processRecord(record []string) ([]*engine.CDR, error) {
csvProvider := config.NewSliceDP(record)
csvProvider := config.NewSliceDP(record, utils.MetaReq)
recordCdrs := make([]*engine.CDR, 0) // More CDRs based on the number of filters and field templates
for _, cdrcCfg := range self.cdrcCfgs { // cdrFields coming from more templates will produce individual storCdr records
tenant, err := cdrcCfg.Tenant.ParseDataProvider(csvProvider, utils.NestingSep) // each profile of cdrc can have different tenant
@@ -146,7 +146,7 @@ func (self *CsvRecordsProcessor) processRecord(record []string) ([]*engine.CDR,
func (self *CsvRecordsProcessor) recordToStoredCdr(record []string, cdrcCfg *config.CdrcCfg, tenant string) (*engine.CDR, error) {
storedCdr := &engine.CDR{OriginHost: "0.0.0.0", Source: cdrcCfg.CdrSourceId, ExtraFields: make(map[string]string), Cost: -1}
var err error
csvProvider := config.NewSliceDP(record) // used for filterS and for RSRParsers
csvProvider := config.NewSliceDP(record, utils.MetaReq) // used for filterS and for RSRParsers
var lazyHttpFields []*config.FCTemplate
fldVals := make(map[string]string)
for _, cdrFldCfg := range cdrcCfg.ContentFields {

View File

@@ -27,14 +27,15 @@ import (
)
//NewObjectDP constructs a DataProvider
func NewObjectDP(obj interface{}) (dP DataProvider) {
dP = &ObjectDP{obj: obj, cache: make(map[string]interface{})}
func NewObjectDP(obj interface{}, prfxSls []string) (dP DataProvider) {
dP = &ObjectDP{obj: obj, cache: make(map[string]interface{}), prfxSls: prfxSls}
return
}
type ObjectDP struct {
obj interface{}
cache map[string]interface{}
obj interface{}
cache map[string]interface{}
prfxSls []string
}
func (objDp *ObjectDP) setCache(path string, val interface{}) {
@@ -55,14 +56,26 @@ func (objDP *ObjectDP) String() string {
// FieldAsInterface is part of engine.DataProvider interface
func (objDP *ObjectDP) FieldAsInterface(fldPath []string) (data interface{}, err error) {
obj := objDP.obj
clnFldPath := fldPath
// []string{ BalanceMap *monetary[0] Value }
var has bool
if data, has = objDP.getCache(strings.Join(fldPath, utils.NestingSep)); has {
return
}
if len(objDP.prfxSls) != 0 {
if len(clnFldPath) < len(objDP.prfxSls) {
return nil, fmt.Errorf("invalid path <%s> compared to prefix <%s>", clnFldPath, objDP.prfxSls)
}
for i, prfx := range objDP.prfxSls {
if clnFldPath[i] != prfx {
return nil, fmt.Errorf("wrong prefix when compared <%s> with <%s>", clnFldPath, objDP.prfxSls)
}
}
clnFldPath = clnFldPath[len(objDP.prfxSls):]
}
var prevFld string
for _, fld := range fldPath {
for _, fld := range clnFldPath {
var slctrStr string
if splt := strings.Split(fld, utils.IdxStart); len(splt) != 1 { // check if we have selector
fld = splt[0]

View File

@@ -28,15 +28,17 @@ import (
)
// NewSliceDP constructs a DataProvider
func NewSliceDP(record []string) (dP DataProvider) {
dP = &SliceDP{req: record, cache: NewNavigableMap(nil)}
func NewSliceDP(record []string, pathPrfx string) (dP DataProvider) {
dP = &SliceDP{req: record, cache: NewNavigableMap(nil), pathPrfx: pathPrfx}
return
}
// SliceDP implements engine.DataProvider so we can pass it to filters
type SliceDP struct {
req []string
cache *NavigableMap
req []string
cache *NavigableMap
pathPrfx string // if this comes in path it will be ignored
// pathPrfx should be reviewed once the cdrc is removed
}
// String is part of engine.DataProvider interface
@@ -50,7 +52,11 @@ func (cP *SliceDP) FieldAsInterface(fldPath []string) (data interface{}, err err
if len(fldPath) == 0 {
return
}
if fldPath[0] != utils.MetaReq || len(fldPath) < 2 {
idx := fldPath[0]
if len(fldPath) == 2 {
idx = fldPath[1]
}
if cP.pathPrfx != utils.EmptyString && (fldPath[0] != cP.pathPrfx || len(fldPath) < 2) {
return "", utils.ErrPrefixNotFound(strings.Join(fldPath, utils.NestingSep))
}
if data, err = cP.cache.FieldAsInterface(fldPath); err == nil ||
@@ -58,7 +64,7 @@ func (cP *SliceDP) FieldAsInterface(fldPath []string) (data interface{}, err err
return
}
err = nil // cancel previous err
if cfgFieldIdx, err := strconv.Atoi(fldPath[1]); err != nil {
if cfgFieldIdx, err := strconv.Atoi(idx); err != nil {
return nil, fmt.Errorf("Ignoring record: %v with error : %+v", cP.req, err)
} else if len(cP.req) <= cfgFieldIdx {
return nil, utils.ErrNotFound

View File

@@ -48,17 +48,17 @@
"attributes_context":"*cdre",
"filters" :["*string:~*req.Source:test2"],
"content_fields": [
{"tag": "CGRID", "type": "*composed", "value": "~*req.CGRID"},
{"tag": "RunID", "type": "*composed", "value": "~*req.RunID"},
{"tag":"Source", "type": "*composed", "value": "~*req.Source"},
{"tag":"OriginID", "type": "*composed", "value": "~*req.OriginID"},
{"tag":"Tenant", "type": "*composed", "value": "~*req.Tenant"},
{"tag":"Category", "type": "*composed", "value": "~*req.Category"},
{"tag":"Account", "type": "*composed", "value": "~*req.Account"},
{"tag":"Subject", "type": "*composed", "value": "~*req.Subject"},
{"tag":"Destination", "type": "*composed", "value": "~*req.Destination"},
{"tag":"Usage", "type": "*composed", "value": "~*req.Usage"},
{"tag":"Cost", "type": "*composed", "value": "~*req.Cost", "rounding_decimals": 4},
{"tag": "CGRID", "type": "*composed", "value": "~CGRID"},
{"tag": "RunID", "type": "*composed", "value": "~RunID"},
{"tag":"Source", "type": "*composed", "value": "~Source"},
{"tag":"OriginID", "type": "*composed", "value": "~OriginID"},
{"tag":"Tenant", "type": "*composed", "value": "~Tenant"},
{"tag":"Category", "type": "*composed", "value": "~Category"},
{"tag":"Account", "type": "*composed", "value": "~Account"},
{"tag":"Subject", "type": "*composed", "value": "~Subject"},
{"tag":"Destination", "type": "*composed", "value": "~Destination"},
{"tag":"Usage", "type": "*composed", "value": "~Usage"},
{"tag":"Cost", "type": "*composed", "value": "~Cost", "rounding_decimals": 4},
],
},
},

View File

@@ -34,7 +34,7 @@
{
"id": "data_update_grp1",
"filters": ["*string:~*vars.*cmd:CCR", "*string:~*req.CC-Request-Type:2",
"*string:*req.Multiple-Services-Credit-Control.Rating-Group:1", "*prefix:*req.Service-Context-Id:gprs"],
"*string:~*req.Multiple-Services-Credit-Control.Rating-Group:1", "*prefix:~*req.Service-Context-Id:gprs"],
"flags": ["*update", "*accounts"],
"request_fields":[
{"tag": "TOR", "field_id": "ToR", "type": "*constant", "value": "*data"},

View File

@@ -103,12 +103,12 @@
"flags": ["*dryrun"],
"processed_path": "/tmp/ers2/out",
"content_fields":[ // import content_fields template, tag will match internally CDR field, in case of .csv value will be represented by index of the field value
{"tag": "TOR", "field_id": "ToR", "type": "*composed", "value": "*voice", "mandatory": true},
{"tag": "TOR", "field_id": "ToR", "type": "*constant", "value": "*voice", "mandatory": true},
{"tag": "OriginID", "field_id": "OriginID", "type": "*composed", "value": "~*req.0", "mandatory": true},
{"tag": "RequestType", "field_id": "RequestType", "type": "*composed", "value": "~*req.1", "mandatory": true},
{"tag": "Direction", "field_id": "Direction", "type": "*composed", "value": "*out", "mandatory": true},
{"tag": "Direction", "field_id": "Direction", "type": "*constant", "value": "*out", "mandatory": true},
{"tag": "Tenant", "field_id": "Tenant", "type": "*composed", "value": "~*req.2", "mandatory": true},
{"tag": "Category", "field_id": "Category", "type": "*composed", "value": "call", "mandatory": true},
{"tag": "Category", "field_id": "Category", "type": "*constant", "value": "call", "mandatory": true},
{"tag": "Account", "field_id": "Account", "type": "*composed", "value": "~*req.3", "mandatory": true},
{"tag": "Subject", "field_id": "Subject", "type": "*composed", "value": "~*req.3", "mandatory": true},
{"tag": "Destination", "field_id": "Destination", "type": "*composed", "value": "~*req.4:s/0([1-9]\\d+)/+49${1}/", "mandatory": true},
@@ -130,10 +130,10 @@
"processed_path": "/tmp/init_session/out",
"content_fields":[ // import content_fields template, tag will match internally CDR field, in case of .csv value will be represented by index of the field value
{"tag": "Tenant", "field_id": "Tenant", "type": "*variable", "value": "~*req.0", "mandatory": true},
{"tag": "TOR", "field_id": "ToR", "type": "*variable", "value": "*voice", "mandatory": true},
{"tag": "TOR", "field_id": "ToR", "type": "*constant", "value": "*voice", "mandatory": true},
{"tag": "OriginID", "field_id": "OriginID", "type": "*variable", "value": "~*req.2", "mandatory": true},
{"tag": "RequestType", "field_id": "RequestType", "type": "*variable", "value": "~*req.3", "mandatory": true},
{"tag": "Category", "field_id": "Category", "type": "*variable", "value": "call", "mandatory": true},
{"tag": "Category", "field_id": "Category", "type": "*constant", "value": "call", "mandatory": true},
{"tag": "Account", "field_id": "Account", "type": "*variable", "value": "~*req.4", "mandatory": true},
{"tag": "Subject", "field_id": "Subject", "type": "*variable", "value": "~*req.5", "mandatory": true},
{"tag": "Destination", "field_id": "Destination", "type": "*variable", "value": "~*req.6", "mandatory": true},
@@ -167,10 +167,10 @@
"processed_path": "/tmp/cdrs/out",
"content_fields":[ // import content_fields template, tag will match internally CDR field, in case of .csv value will be represented by index of the field value
{"tag": "Tenant", "field_id": "Tenant", "type": "*variable", "value": "~*req.0", "mandatory": true},
{"tag": "TOR", "field_id": "ToR", "type": "*variable", "value": "*voice", "mandatory": true},
{"tag": "TOR", "field_id": "ToR", "type": "*constant", "value": "*voice", "mandatory": true},
{"tag": "OriginID", "field_id": "OriginID", "type": "*variable", "value": "~*req.2", "mandatory": true},
{"tag": "RequestType", "field_id": "RequestType", "type": "*variable", "value": "~*req.3", "mandatory": true},
{"tag": "Category", "field_id": "Category", "type": "*variable", "value": "call", "mandatory": true},
{"tag": "Category", "field_id": "Category", "type": "*constant", "value": "call", "mandatory": true},
{"tag": "Account", "field_id": "Account", "type": "*variable", "value": "~*req.4", "mandatory": true},
{"tag": "Subject", "field_id": "Subject", "type": "*variable", "value": "~*req.5", "mandatory": true},
{"tag": "Destination", "field_id": "Destination", "type": "*variable", "value": "~*req.6", "mandatory": true},
@@ -192,13 +192,13 @@
"flags": ["*cdrs","*log"],
"filters":["*string:~*req.3:1002"],
"content_fields":[ // import content_fields template, tag will match internally CDR field, in case of .csv value will be represented by index of the field value
{"tag": "TOR", "field_id": "ToR", "type": "*composed", "value": "*voice", "mandatory": true},
{"tag": "TOR", "field_id": "ToR", "type": "*constant", "value": "*voice", "mandatory": true},
{"tag": "OriginID", "field_id": "OriginID", "type": "*composed", "value": "~*req.0", "mandatory": true},
{"tag": "RequestType", "field_id": "RequestType", "type": "*composed", "value": "~*req.1", "mandatory": true},
{"tag": "Tenant", "field_id": "Tenant", "type": "*composed", "value": "~*req.2", "mandatory": true},
{"tag": "Category", "field_id": "Category", "type": "*composed", "value": "call", "mandatory": true},
{"tag": "Account", "field_id": "Account", "type": "*composed", "value": "~*req.3", "mandatory": true},
{"tag": "Source", "field_id": "Source", "type": "*composed", "value": "ers_csv", "mandatory": true},
{"tag": "Source", "field_id": "Source", "type": "*constant", "value": "ers_csv", "mandatory": true},
{"tag": "Subject", "field_id": "Subject", "type": "*composed", "value": "~*req.3", "mandatory": true},
{"tag": "Destination", "field_id": "Destination", "type": "*composed", "value": "~*req.4:s/0([1-9]\\d+)/+49${1}/", "mandatory": true},
{"tag": "SetupTime", "field_id": "SetupTime", "type": "*composed", "value": "~*req.5", "mandatory": true},

View File

@@ -2523,7 +2523,7 @@ func TestECSyncKeys(t *testing.T) {
}
func TestECAsDataProvider(t *testing.T) {
ecDP := config.NewObjectDP(testEC)
ecDP := config.NewObjectDP(testEC, nil)
if data, err := ecDP.FieldAsInterface([]string{"RunID"}); err != nil {
t.Error(err)
} else if data != utils.META_DEFAULT {

View File

@@ -126,7 +126,7 @@ func (fS *FilterS) Pass(tenant string, filterIDs []string,
continue
}
for _, fltr := range f.Rules {
fieldNameDP, err = fS.getFieldNameDataProvider(ev, &fltr.FieldName, tenant)
fieldNameDP, err = fS.getFieldNameDataProvider(ev, fltr.FieldName, tenant)
if err != nil {
return pass, err
}
@@ -227,24 +227,14 @@ func NewFilterRule(rfType, fieldName string, vals []string) (*FilterRule, error)
return rf, nil
}
//itemFilter is used for *stats and *resources filter type
type itemFilter struct {
ItemID string
FilterType string
FilterValue string
}
// FilterRule filters requests coming into various places
// Pass rule: default negative, one mathing rule should pass the filter
type FilterRule struct {
Type string // Filter type (*string, *timing, *rsr_filters, *stats, *lt, *lte, *gt, *gte)
FieldName string // Name of the field providing us the Values to check (used in case of some )
Values []string // Filter definition
rsrFields config.RSRParsers // Cache here the RSRFilter Values
negative *bool
statItems []*itemFilter // Cached compiled itemFilter out of Values
resourceItems []*itemFilter // Cached compiled itemFilter out of Values
accountItems []*itemFilter // Cached compiled itemFilter out of Values
Type string // Filter type (*string, *timing, *rsr_filters, *stats, *lt, *lte, *gt, *gte)
FieldName string // Name of the field providing us the Values to check (used in case of some )
Values []string // Filter definition
rsrFields config.RSRParsers // Cache here the RSRFilter Values
negative *bool
}
// Separate method to compile RSR fields
@@ -496,15 +486,15 @@ func (fltr *FilterRule) passEqualTo(fielNameDP config.DataProvider, fieldValuesD
}
func (fS *FilterS) getFieldNameDataProvider(initialDP config.DataProvider,
fieldName *string, tenant string) (dp config.DataProvider, err error) {
fieldName string, tenant string) (dp config.DataProvider, err error) {
switch {
case strings.HasPrefix(*fieldName, utils.DynamicDataPrefix+utils.MetaAccounts):
case strings.HasPrefix(fieldName, utils.DynamicDataPrefix+utils.MetaAccounts):
// sample of fieldName : ~*accounts.1001.BalanceMap.*monetary[0].Value
// split the field name in 3 parts
// fieldNameType (~*accounts), accountID(1001) and quried part (BalanceMap.*monetary[0].Value)
splitFldName := strings.SplitN(*fieldName, utils.NestingSep, 3)
splitFldName := strings.SplitN(fieldName, utils.NestingSep, 3)
if len(splitFldName) != 3 {
return nil, fmt.Errorf("invalid fieldname <%s>", *fieldName)
return nil, fmt.Errorf("invalid fieldname <%s>", fieldName)
}
var account *Account
if err = fS.ralSConns.Call(utils.ApierV2GetAccount,
@@ -512,27 +502,24 @@ func (fS *FilterS) getFieldNameDataProvider(initialDP config.DataProvider,
return
}
//construct dataProvider from account and set it furthder
dp = config.NewObjectDP(account)
// remove from fieldname the fielNameType and the AccountID
*fieldName = utils.DynamicDataPrefix + splitFldName[2]
case strings.HasPrefix(*fieldName, utils.DynamicDataPrefix+utils.MetaResources):
dp = config.NewObjectDP(account, []string{utils.MetaAccounts, splitFldName[1]})
case strings.HasPrefix(fieldName, utils.DynamicDataPrefix+utils.MetaResources):
// sample of fieldName : ~*resources.ResourceID.Field
splitFldName := strings.SplitN(*fieldName, utils.NestingSep, 3)
splitFldName := strings.SplitN(fieldName, utils.NestingSep, 3)
if len(splitFldName) != 3 {
return nil, fmt.Errorf("invalid fieldname <%s>", *fieldName)
return nil, fmt.Errorf("invalid fieldname <%s>", fieldName)
}
var reply *Resource
if err := fS.resSConns.Call(utils.ResourceSv1GetResource,
&utils.TenantID{Tenant: tenant, ID: splitFldName[1]}, &reply); err != nil {
return nil, err
}
dp = config.NewObjectDP(reply)
*fieldName = utils.DynamicDataPrefix + splitFldName[2]
case strings.HasPrefix(*fieldName, utils.DynamicDataPrefix+utils.MetaStats):
// sample of fieldName : ~*resources.ResourceID.Field
splitFldName := strings.SplitN(*fieldName, utils.NestingSep, 3)
dp = config.NewObjectDP(reply, []string{utils.MetaResources, reply.ID})
case strings.HasPrefix(fieldName, utils.DynamicDataPrefix+utils.MetaStats):
// sample of fieldName : ~*stats.StatID.*acd
splitFldName := strings.SplitN(fieldName, utils.NestingSep, 3)
if len(splitFldName) != 3 {
return nil, fmt.Errorf("invalid fieldname <%s>", *fieldName)
return nil, fmt.Errorf("invalid fieldname <%s>", fieldName)
}
var statValues map[string]float64
@@ -541,26 +528,23 @@ func (fS *FilterS) getFieldNameDataProvider(initialDP config.DataProvider,
&statValues); err != nil {
return nil, err
}
//convert statValues to map[string]interface{}
ifaceStatValues := make(map[string]interface{})
for key, val := range statValues {
ifaceStatValues[key] = val
evNm := config.NewNavigableMap(nil)
for k, v := range statValues {
evNm.Set([]string{utils.MetaStats, splitFldName[1], k}, v, false, false)
}
//convert ifaceStatValues into a NavigableMap
dp = config.NewNavigableMap(ifaceStatValues)
*fieldName = utils.DynamicDataPrefix + splitFldName[2]
case strings.HasPrefix(*fieldName, utils.DynamicDataPrefix+utils.MetaReq),
strings.HasPrefix(*fieldName, utils.DynamicDataPrefix+utils.MetaVars),
strings.HasPrefix(*fieldName, utils.DynamicDataPrefix+utils.MetaCgreq),
strings.HasPrefix(*fieldName, utils.DynamicDataPrefix+utils.MetaCgrep),
strings.HasPrefix(*fieldName, utils.DynamicDataPrefix+utils.MetaRep),
strings.HasPrefix(*fieldName, utils.DynamicDataPrefix+utils.MetaCGRAReq),
strings.HasPrefix(*fieldName, utils.DynamicDataPrefix+utils.MetaAct):
dp = evNm
case strings.HasPrefix(fieldName, utils.DynamicDataPrefix+utils.MetaReq),
strings.HasPrefix(fieldName, utils.DynamicDataPrefix+utils.MetaVars),
strings.HasPrefix(fieldName, utils.DynamicDataPrefix+utils.MetaCgreq),
strings.HasPrefix(fieldName, utils.DynamicDataPrefix+utils.MetaCgrep),
strings.HasPrefix(fieldName, utils.DynamicDataPrefix+utils.MetaRep),
strings.HasPrefix(fieldName, utils.DynamicDataPrefix+utils.MetaCGRAReq),
strings.HasPrefix(fieldName, utils.DynamicDataPrefix+utils.MetaAct):
dp = initialDP
// don't need to take out the prefix because the navigable map have ~*req prefix
case *fieldName == utils.EmptyString:
case fieldName == utils.EmptyString:
default:
return nil, utils.ErrPrefixNotFound(fmt.Sprintf(" data provider prefix for <%s>", *fieldName))
return nil, utils.ErrPrefixNotFound(fmt.Sprintf(" data provider prefix for <%s>", fieldName))
}
return
}
@@ -569,7 +553,7 @@ func (fS *FilterS) getFieldValuesDataProviders(initialDP config.DataProvider,
values []string, tenant string) (dp []config.DataProvider, err error) {
dp = make([]config.DataProvider, len(values))
for i := range values {
if dp[i], err = fS.getFieldValueDataProvider(initialDP, &values[i], tenant); err != nil {
if dp[i], err = fS.getFieldValueDataProvider(initialDP, values[i], tenant); err != nil {
return
}
}
@@ -577,15 +561,15 @@ func (fS *FilterS) getFieldValuesDataProviders(initialDP config.DataProvider,
}
func (fS *FilterS) getFieldValueDataProvider(initialDP config.DataProvider,
fieldValue *string, tenant string) (dp config.DataProvider, err error) {
fieldValue string, tenant string) (dp config.DataProvider, err error) {
switch {
case strings.HasPrefix(*fieldValue, utils.DynamicDataPrefix+utils.MetaAccounts):
case strings.HasPrefix(fieldValue, utils.DynamicDataPrefix+utils.MetaAccounts):
// sample of fieldName : ~*accounts.1001.BalanceMap.*monetary[0].Value
// split the field name in 3 parts
// fieldNameType (~*accounts), accountID(1001) and quried part (BalanceMap.*monetary[0].Value)
splitFldName := strings.SplitN(*fieldValue, utils.NestingSep, 3)
splitFldName := strings.SplitN(fieldValue, utils.NestingSep, 3)
if len(splitFldName) != 3 {
return nil, fmt.Errorf("invalid fieldname <%s>", *fieldValue)
return nil, fmt.Errorf("invalid fieldname <%s>", fieldValue)
}
var account *Account
if err = fS.ralSConns.Call(utils.ApierV2GetAccount,
@@ -593,27 +577,24 @@ func (fS *FilterS) getFieldValueDataProvider(initialDP config.DataProvider,
return
}
//construct dataProvider from account and set it furthder
dp = config.NewObjectDP(account)
// remove from fieldname the fielNameType and the AccountID
*fieldValue = utils.DynamicDataPrefix + splitFldName[2]
case strings.HasPrefix(*fieldValue, utils.DynamicDataPrefix+utils.MetaResources):
dp = config.NewObjectDP(account, []string{utils.MetaAccounts, account.ID})
case strings.HasPrefix(fieldValue, utils.DynamicDataPrefix+utils.MetaResources):
// sample of fieldName : ~*resources.ResourceID.Field
splitFldName := strings.SplitN(*fieldValue, utils.NestingSep, 3)
splitFldName := strings.SplitN(fieldValue, utils.NestingSep, 3)
if len(splitFldName) != 3 {
return nil, fmt.Errorf("invalid fieldname <%s>", *fieldValue)
return nil, fmt.Errorf("invalid fieldname <%s>", fieldValue)
}
var reply *Resource
if err := fS.resSConns.Call(utils.ResourceSv1GetResource,
&utils.TenantID{Tenant: tenant, ID: splitFldName[1]}, &reply); err != nil {
return nil, err
}
dp = config.NewObjectDP(reply)
*fieldValue = utils.DynamicDataPrefix + splitFldName[2]
case strings.HasPrefix(*fieldValue, utils.DynamicDataPrefix+utils.MetaStats):
dp = config.NewObjectDP(reply, []string{utils.MetaResources, reply.ID})
case strings.HasPrefix(fieldValue, utils.DynamicDataPrefix+utils.MetaStats):
// sample of fieldName : ~*resources.ResourceID.Field
splitFldName := strings.SplitN(*fieldValue, utils.NestingSep, 3)
splitFldName := strings.SplitN(fieldValue, utils.NestingSep, 3)
if len(splitFldName) != 3 {
return nil, fmt.Errorf("invalid fieldname <%s>", *fieldValue)
return nil, fmt.Errorf("invalid fieldname <%s>", fieldValue)
}
var statValues map[string]float64
@@ -622,21 +603,20 @@ func (fS *FilterS) getFieldValueDataProvider(initialDP config.DataProvider,
&statValues); err != nil {
return nil, err
}
//convert statValues to map[string]interface{}
ifaceStatValues := make(map[string]interface{})
for key, val := range statValues {
ifaceStatValues[key] = val
ifaceMetric := make(map[string]interface{})
for k, v := range statValues {
ifaceMetric[k] = v
}
//convert ifaceStatValues into a NavigableMap
dp = config.NewNavigableMap(ifaceStatValues)
*fieldValue = utils.DynamicDataPrefix + splitFldName[2]
case strings.HasPrefix(*fieldValue, utils.DynamicDataPrefix+utils.MetaReq),
strings.HasPrefix(*fieldValue, utils.DynamicDataPrefix+utils.MetaVars),
strings.HasPrefix(*fieldValue, utils.DynamicDataPrefix+utils.MetaCgreq),
strings.HasPrefix(*fieldValue, utils.DynamicDataPrefix+utils.MetaCgrep),
strings.HasPrefix(*fieldValue, utils.DynamicDataPrefix+utils.MetaRep),
strings.HasPrefix(*fieldValue, utils.DynamicDataPrefix+utils.MetaCGRAReq),
strings.HasPrefix(*fieldValue, utils.DynamicDataPrefix+utils.MetaAct):
evNm := config.NewNavigableMap(nil)
evNm.Set([]string{utils.MetaStats, splitFldName[1]}, ifaceMetric, false, false)
dp = evNm
case strings.HasPrefix(fieldValue, utils.DynamicDataPrefix+utils.MetaReq),
strings.HasPrefix(fieldValue, utils.DynamicDataPrefix+utils.MetaVars),
strings.HasPrefix(fieldValue, utils.DynamicDataPrefix+utils.MetaCgreq),
strings.HasPrefix(fieldValue, utils.DynamicDataPrefix+utils.MetaCgrep),
strings.HasPrefix(fieldValue, utils.DynamicDataPrefix+utils.MetaRep),
strings.HasPrefix(fieldValue, utils.DynamicDataPrefix+utils.MetaCGRAReq),
strings.HasPrefix(fieldValue, utils.DynamicDataPrefix+utils.MetaAct):
dp = initialDP
default: // in case of constant we give an empty DataProvider ( empty navigable map )
dp = config.NewNavigableMap(nil)

View File

@@ -143,7 +143,7 @@ func (rdr *CSVFileER) processFile(fPath, fName string) (err error) {
}
rowNr++ // increment the rowNr after checking if it's not the end of file
agReq := agents.NewAgentRequest(
config.NewSliceDP(record), reqVars,
config.NewSliceDP(record, utils.EmptyString), reqVars,
nil, nil, rdr.Config().Tenant,
rdr.cgrCfg.GeneralCfg().DefaultTenant,
utils.FirstNonEmpty(rdr.Config().Timezone,

View File

@@ -372,12 +372,8 @@ func testV1FltrGetThresholdForEvent2(t *testing.T) {
func testV1FltrPopulateResources(t *testing.T) {
//create a resourceProfile
rlsConfig := &engine.ResourceProfile{
Tenant: "cgrates.org",
ID: "ResTest",
ActivationInterval: &utils.ActivationInterval{
ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),
ExpiryTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),
},
Tenant: "cgrates.org",
ID: "ResTest",
UsageTTL: time.Duration(1) * time.Minute,
Limit: 10,
AllocationMessage: "MessageAllocation",
@@ -442,10 +438,6 @@ func testV1FltrPopulateResources(t *testing.T) {
Tenant: "cgrates.org",
ID: "TH_ResTest",
FilterIDs: []string{"FLTR_TH_Resource", "*string:~*req.Account:2020"},
ActivationInterval: &utils.ActivationInterval{
ActivationTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC),
ExpiryTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC),
},
MaxHits: -1,
MinSleep: time.Duration(1 * time.Millisecond),
Weight: 10.0,
@@ -559,10 +551,6 @@ func testV1FltrAccounts(t *testing.T) {
Tenant: "cgrates.org",
ID: "TH_Account",
FilterIDs: []string{"FLTR_TH_Accounts", "*string:~*req.Account:1001"},
ActivationInterval: &utils.ActivationInterval{
ActivationTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC),
ExpiryTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC),
},
MaxHits: -1,
MinSleep: time.Duration(1 * time.Millisecond),
Weight: 90.0,

View File

@@ -37,7 +37,7 @@ func TestAccountNewObjectDPFieldAsInterface(t *testing.T) {
},
},
}
accDP := config.NewObjectDP(acc)
accDP := config.NewObjectDP(acc, nil)
if data, err := accDP.FieldAsInterface([]string{"BalanceMap", "*monetary[0]", "Value"}); err != nil {
t.Error(err)
} else if data != 20. {
@@ -65,7 +65,7 @@ func TestAccountNewObjectDPFieldAsInterfaceFromCache(t *testing.T) {
},
},
}
accDP := config.NewObjectDP(acc)
accDP := config.NewObjectDP(acc, nil)
if data, err := accDP.FieldAsInterface([]string{"BalanceMap", "*monetary[0]", "Value"}); err != nil {
t.Error(err)