diff --git a/engine/account.go b/engine/account.go index 1613fe624..9ee49fe19 100644 --- a/engine/account.go +++ b/engine/account.go @@ -1168,14 +1168,14 @@ func (acc *Account) GetBalanceWithID(blcType, blcID string) (blc *Balance) { // FieldAsInterface func to help EventCost FieldAsInterface func (as *AccountSummary) FieldAsInterface(fldPath []string) (val interface{}, err error) { - if len(fldPath) == 0 { + if as == nil || len(fldPath) == 0 { return nil, utils.ErrNotFound } switch fldPath[0] { default: opath, indx := utils.GetPathIndex(fldPath[0]) if opath == utils.BalanceSummaries && indx != nil { - if len(as.BalanceSummaries) < *indx { + if len(as.BalanceSummaries) <= *indx { return nil, utils.ErrNotFound } bl := as.BalanceSummaries[*indx] diff --git a/engine/balances.go b/engine/balances.go index 22e4cd761..788c2c24a 100644 --- a/engine/balances.go +++ b/engine/balances.go @@ -898,7 +898,7 @@ func (bs BalanceSummaries) BalanceSummaryWithUUD(bsUUID string) (b *BalanceSumma // FieldAsInterface func to help EventCost FieldAsInterface func (bl *BalanceSummary) FieldAsInterface(fldPath []string) (val interface{}, err error) { - if len(fldPath) != 1 { + if bl == nil || len(fldPath) != 1 { return nil, utils.ErrNotFound } switch fldPath[0] { diff --git a/engine/eventcost.go b/engine/eventcost.go index 8f9bfcb8f..bbcd888d2 100644 --- a/engine/eventcost.go +++ b/engine/eventcost.go @@ -932,7 +932,7 @@ func (ec *EventCost) fieldAsInterface(fldPath []string) (val interface{}, err er return nil, fmt.Errorf("unsupported field prefix: <%s>", opath) } if indx != nil { - if len(ec.Charges) < *indx { + if len(ec.Charges) <= *indx { return nil, utils.ErrNotFound } return ec.getChargesForPath(fldPath[1:], ec.Charges[*indx]) @@ -1027,6 +1027,9 @@ func (ec *EventCost) getChargesForPath(fldPath []string, chr *ChargingInterval) } return chr.Increments, nil } + if len(chr.Increments) <= *indx { + return nil, utils.ErrNotFound + } incr := chr.Increments[*indx] if len(fldPath) == 1 { return incr, nil @@ -1056,6 +1059,9 @@ func (ec *EventCost) getRatingForPath(fldPath []string, rating *RatingUnit) (val return nil, utils.ErrNotFound } if indx != nil { + if len(rts) <= *indx { + return nil, utils.ErrNotFound + } rt := rts[*indx] if len(fldPath) == 1 { return rt, nil diff --git a/engine/eventcost_test.go b/engine/eventcost_test.go index d2691c133..debf68a2f 100644 --- a/engine/eventcost_test.go +++ b/engine/eventcost_test.go @@ -266,7 +266,6 @@ func TestECClone(t *testing.T) { if _, has := testEC.Accounting["a012888"]; !has { t.Error("Key removed from testEC") } - } func TestECComputeAndReset(t *testing.T) { @@ -3006,3 +3005,48 @@ func TestECAsCallCost3(t *testing.T) { } } + +func TestECAsDataProvider2(t *testing.T) { + ecDP := testEC + if data, err := ecDP.FieldAsInterface([]string{"RunID"}); err != nil { + t.Error(err) + } else if data != utils.MetaDefault { + t.Errorf("Expecting: <%s> \nreceived: <%s>", utils.MetaDefault, data) + } + if data, err := ecDP.FieldAsInterface([]string{"AccountSummary", "ID"}); err != nil { + t.Error(err) + } else if data != "dan" { + t.Errorf("Expecting: <%s> \nreceived: <%s>", "data", data) + } + if data, err := ecDP.FieldAsInterface([]string{"AccountSummary", "BalanceSummaries[1]", "UUID"}); err != nil { + t.Error(err) + } else if data != "7a54a9e9-d610-4c82-bcb5-a315b9a65010" { + t.Errorf("Expecting: <%s> \nreceived: <%s>", "4b8b53d7-c1a1-4159-b845-4623a00a0165", data) + } + if data, err := ecDP.FieldAsInterface([]string{"AccountSummary", "BalanceSummaries[2]", "Type"}); err != nil { + t.Error(err) + } else if data != "*voice" { + t.Errorf("Expecting: <%s> \nreceived: <%s>", "*voice", data) + } + ecDP = &EventCost{AccountSummary: &AccountSummary{}} + ecDP.initCache() + if _, err := ecDP.FieldAsInterface([]string{"AccountSummary", "BalanceSummaries[0]", "Type"}); err == nil || err.Error() != utils.ErrNotFound.Error() { + t.Errorf("Unexpected error:%v", err) + } + if _, err := ecDP.FieldAsInterface([]string{"Charges[0]", "Increments"}); err == nil || err.Error() != utils.ErrNotFound.Error() { + t.Errorf("Unexpected error:%v", err) + } + ecDP.Charges = []*ChargingInterval{{}} + if _, err := ecDP.FieldAsInterface([]string{"Charges[0]", "Increments[0]"}); err == nil || err.Error() != utils.ErrNotFound.Error() { + t.Errorf("Unexpected error:%v", err) + } + ecDP.Rating = Rating{"": {}} + ecDP.Rates = ChargedRates{"": {}, "b": {}} + if _, err := ecDP.FieldAsInterface([]string{"Charges[0]", "Rating", "Rates[0]"}); err == nil || err.Error() != utils.ErrNotFound.Error() { + t.Errorf("Unexpected error:%v", err) + } + + if _, err := ecDP.FieldAsInterface([]string{"Rates", "b[0]"}); err == nil || err.Error() != utils.ErrNotFound.Error() { + t.Errorf("Unexpected error:%v", err) + } +} diff --git a/engine/libeventcost.go b/engine/libeventcost.go index 0b73074f9..beb365fc7 100644 --- a/engine/libeventcost.go +++ b/engine/libeventcost.go @@ -194,7 +194,7 @@ type BalanceCharge struct { // FieldAsInterface func to help EventCost FieldAsInterface func (bc *BalanceCharge) FieldAsInterface(fldPath []string) (val interface{}, err error) { - if len(fldPath) != 1 { + if bc == nil || len(fldPath) != 1 { return nil, utils.ErrNotFound } switch fldPath[0] { @@ -263,11 +263,11 @@ func (rf RatingMatchedFilters) Clone() (cln map[string]interface{}) { } // FieldAsInterface func to help EventCost FieldAsInterface -func (rf *RatingMatchedFilters) FieldAsInterface(fldPath []string) (val interface{}, err error) { - if len(fldPath) != 1 { +func (rf RatingMatchedFilters) FieldAsInterface(fldPath []string) (val interface{}, err error) { + if rf == nil || len(fldPath) != 1 { return nil, utils.ErrNotFound } - ct, has := (*rf)[fldPath[0]] + ct, has := rf[fldPath[0]] if !has || ct == nil { return nil, utils.ErrNotFound } @@ -300,7 +300,7 @@ func (ct *ChargedTiming) Clone() (cln *ChargedTiming) { } // FieldAsInterface func to help EventCost FieldAsInterface -func (ct *ChargedTiming) FieldAsInterface(fldPath []string) (val interface{}, err error) { +func (ct ChargedTiming) FieldAsInterface(fldPath []string) (val interface{}, err error) { if len(fldPath) != 1 { return nil, utils.ErrNotFound } @@ -352,7 +352,7 @@ func (ru *RatingUnit) Clone() (cln *RatingUnit) { } // FieldAsInterface func to help EventCost FieldAsInterface -func (ru *RatingUnit) FieldAsInterface(fldPath []string) (val interface{}, err error) { +func (ru RatingUnit) FieldAsInterface(fldPath []string) (val interface{}, err error) { if len(fldPath) != 1 { return nil, utils.ErrNotFound } @@ -407,11 +407,11 @@ func (rfs RatingFilters) Clone() (cln RatingFilters) { } // FieldAsInterface func to help EventCost FieldAsInterface -func (rfs *RatingFilters) FieldAsInterface(fldPath []string) (val interface{}, err error) { - if len(fldPath) == 0 { +func (rfs RatingFilters) FieldAsInterface(fldPath []string) (val interface{}, err error) { + if rfs == nil || len(fldPath) == 0 { return nil, utils.ErrNotFound } - ct, has := (*rfs)[fldPath[0]] + ct, has := rfs[fldPath[0]] if !has || ct == nil { return nil, utils.ErrNotFound } @@ -450,11 +450,11 @@ func (crus Rating) Clone() (cln Rating) { } // FieldAsInterface func to help EventCost FieldAsInterface -func (crus *Rating) FieldAsInterface(fldPath []string) (val interface{}, err error) { - if len(fldPath) == 0 { +func (crus Rating) FieldAsInterface(fldPath []string) (val interface{}, err error) { + if crus == nil || len(fldPath) == 0 { return nil, utils.ErrNotFound } - rt, has := (*crus)[fldPath[0]] + rt, has := crus[fldPath[0]] if !has || rt == nil { return nil, utils.ErrNotFound } @@ -468,17 +468,17 @@ func (crus *Rating) FieldAsInterface(fldPath []string) (val interface{}, err err type ChargedRates map[string]RateGroups // FieldAsInterface func to help EventCost FieldAsInterface -func (crs *ChargedRates) FieldAsInterface(fldPath []string) (val interface{}, err error) { - if len(fldPath) == 0 { +func (crs ChargedRates) FieldAsInterface(fldPath []string) (val interface{}, err error) { + if crs == nil || len(fldPath) == 0 { return nil, utils.ErrNotFound } opath, indx := utils.GetPathIndex(fldPath[0]) - cr, has := (*crs)[opath] + cr, has := crs[opath] if !has || cr == nil { return nil, utils.ErrNotFound } if indx != nil { - if len(cr) < *indx { + if len(cr) <= *indx { return nil, utils.ErrNotFound } rg := cr[*indx] @@ -522,11 +522,11 @@ func (crs ChargedRates) Clone() (cln ChargedRates) { type ChargedTimings map[string]*ChargedTiming // FieldAsInterface func to help EventCost FieldAsInterface -func (cts *ChargedTimings) FieldAsInterface(fldPath []string) (val interface{}, err error) { - if len(fldPath) == 0 { +func (cts ChargedTimings) FieldAsInterface(fldPath []string) (val interface{}, err error) { + if cts == nil || len(fldPath) == 0 { return nil, utils.ErrNotFound } - ct, has := (*cts)[fldPath[0]] + ct, has := cts[fldPath[0]] if !has || ct == nil { return nil, utils.ErrNotFound } @@ -590,11 +590,11 @@ func (cbs Accounting) Clone() (cln Accounting) { } // FieldAsInterface func to help EventCost FieldAsInterface -func (cbs *Accounting) FieldAsInterface(fldPath []string) (val interface{}, err error) { - if len(fldPath) == 0 { +func (cbs Accounting) FieldAsInterface(fldPath []string) (val interface{}, err error) { + if cbs == nil || len(fldPath) == 0 { return nil, utils.ErrNotFound } - ac, has := (*cbs)[fldPath[0]] + ac, has := cbs[fldPath[0]] if !has || ac == nil { return nil, utils.ErrNotFound } diff --git a/engine/rateinterval.go b/engine/rateinterval.go index befd983f0..c06315bdb 100644 --- a/engine/rateinterval.go +++ b/engine/rateinterval.go @@ -235,7 +235,7 @@ type Rate struct { // FieldAsInterface func to help EventCost FieldAsInterface func (r *Rate) FieldAsInterface(fldPath []string) (val interface{}, err error) { - if len(fldPath) != 1 { + if r == nil || len(fldPath) != 1 { return nil, utils.ErrNotFound } switch fldPath[0] { diff --git a/utils/mapstorage.go b/utils/mapstorage.go index 963c40ab7..534d785fe 100644 --- a/utils/mapstorage.go +++ b/utils/mapstorage.go @@ -58,7 +58,6 @@ func (ms MapStorage) FieldAsInterface(fldPath []string) (val interface{}, err er if len(fldPath) == 1 { if indx == nil { return - } switch rv := val.(type) { case []string: