mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Added cache for EventCost.FieldAsInterface
This commit is contained in:
committed by
Dan Christian Bogos
parent
51d32e9a79
commit
ffef415e8c
@@ -60,6 +60,7 @@ func NewCDRFromExternalCDR(extCdr *ExternalCDR, timezone string) (*CDR, error) {
|
||||
if err = json.Unmarshal([]byte(extCdr.CostDetails), cdr.CostDetails); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cdr.CostDetails.initCache()
|
||||
}
|
||||
if extCdr.ExtraFields != nil {
|
||||
cdr.ExtraFields = make(map[string]string)
|
||||
@@ -156,7 +157,7 @@ func (cdr *CDR) FieldAsString(rsrPrs *config.RSRParser) (parsed string, err erro
|
||||
config.NewNavigableMap(map[string]interface{}{
|
||||
utils.MetaReq: cdr.AsMapStringIface(),
|
||||
utils.MetaEC: cdr.CostDetails,
|
||||
}), utils.NestingSep)
|
||||
}), utils.NestingSep)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -169,7 +170,7 @@ func (cdr *CDR) FieldsAsString(rsrFlds config.RSRParsers) string {
|
||||
config.NewNavigableMap(map[string]interface{}{
|
||||
utils.MetaReq: cdr.AsMapStringIface(),
|
||||
utils.MetaEC: cdr.CostDetails,
|
||||
}), utils.NestingSep)
|
||||
}), utils.NestingSep)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
@@ -242,9 +243,7 @@ func (cdr *CDR) AsMapStringIface() (mp map[string]interface{}) {
|
||||
mp[utils.CostSource] = cdr.CostSource
|
||||
mp[utils.Cost] = cdr.Cost
|
||||
if cdr.CostDetails != nil {
|
||||
var result map[string]interface{}
|
||||
json.Unmarshal([]byte(utils.ToJSON(cdr.CostDetails)), &result)
|
||||
mp[utils.CostDetails] = result
|
||||
mp[utils.CostDetails] = cdr.CostDetails
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
package engine
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"testing"
|
||||
@@ -489,6 +488,7 @@ func TestCdrClone(t *testing.T) {
|
||||
Cost: utils.Float64Pointer(0.74),
|
||||
},
|
||||
}
|
||||
eOut.CostDetails.initCache()
|
||||
if rcv := cdr.Clone(); !reflect.DeepEqual(rcv, eOut) {
|
||||
t.Errorf("Expecting: %+v,\n received: %+v", eOut, rcv)
|
||||
}
|
||||
@@ -579,8 +579,6 @@ func TestCDRTestCDRAsMapStringIface2(t *testing.T) {
|
||||
CostDetails: NewEventCostFromCallCost(cc, "TestCDRTestCDRAsMapStringIface2", utils.MetaDefault),
|
||||
}
|
||||
|
||||
var result map[string]interface{}
|
||||
json.Unmarshal([]byte(utils.ToJSON(cdr.CostDetails)), &result)
|
||||
mp := map[string]interface{}{
|
||||
"field_extr1": "val_extr1",
|
||||
"fieldextr2": "valextr2",
|
||||
@@ -605,7 +603,7 @@ func TestCDRTestCDRAsMapStringIface2(t *testing.T) {
|
||||
utils.PreRated: false,
|
||||
utils.Partial: false,
|
||||
utils.ExtraInfo: cdr.ExtraInfo,
|
||||
utils.CostDetails: result,
|
||||
utils.CostDetails: cdr.CostDetails,
|
||||
}
|
||||
if cdrMp := cdr.AsMapStringIface(); !reflect.DeepEqual(mp, cdrMp) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", mp, cdrMp)
|
||||
|
||||
@@ -37,6 +37,7 @@ func NewBareEventCost() *EventCost {
|
||||
Rates: make(ChargedRates),
|
||||
Timings: make(ChargedTimings),
|
||||
Charges: make([]*ChargingInterval, 0),
|
||||
cache: config.NewNavigableMap(nil),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,6 +118,14 @@ type EventCost struct {
|
||||
RatingFilters RatingFilters
|
||||
Rates ChargedRates
|
||||
Timings ChargedTimings
|
||||
|
||||
cache *config.NavigableMap
|
||||
}
|
||||
|
||||
func (ec *EventCost) initCache() {
|
||||
if ec != nil {
|
||||
ec.cache = config.NewNavigableMap(nil)
|
||||
}
|
||||
}
|
||||
|
||||
func (ec *EventCost) ratingIDForRateInterval(ri *RateInterval, rf RatingMatchedFilters) string {
|
||||
@@ -180,6 +189,7 @@ func (ec *EventCost) Clone() (cln *EventCost) {
|
||||
return
|
||||
}
|
||||
cln = new(EventCost)
|
||||
cln.initCache()
|
||||
cln.CGRID = ec.CGRID
|
||||
cln.RunID = ec.RunID
|
||||
cln.StartTime = ec.StartTime
|
||||
@@ -845,6 +855,27 @@ func (ec *EventCost) FieldAsInterface(fldPath []string) (val interface{}, err er
|
||||
if len(fldPath) == 0 {
|
||||
return nil, utils.ErrNotFound
|
||||
}
|
||||
if val, err = ec.cache.FieldAsInterface(fldPath); err != nil {
|
||||
if err != utils.ErrNotFound { // item found in cache
|
||||
return
|
||||
}
|
||||
err = nil // cancel previous err
|
||||
} else if val == nil {
|
||||
return nil, utils.ErrNotFound
|
||||
} else {
|
||||
return // data found in cache
|
||||
}
|
||||
val, err = ec.fieldAsInterface(fldPath)
|
||||
if err == nil {
|
||||
ec.cache.Set(fldPath, val, false, false)
|
||||
} else if err == utils.ErrNotFound {
|
||||
ec.cache.Set(fldPath, nil, false, false)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// FieldAsInterface the implementation of FieldAsInterface
|
||||
func (ec *EventCost) fieldAsInterface(fldPath []string) (val interface{}, err error) {
|
||||
switch fldPath[0] {
|
||||
default: // "Charges[1]"
|
||||
opath, indx := utils.GetPathIndex(fldPath[0])
|
||||
@@ -888,16 +919,34 @@ func (ec *EventCost) FieldAsInterface(fldPath []string) (val interface{}, err er
|
||||
}
|
||||
return ec.Cost, nil
|
||||
case utils.AccountSummary:
|
||||
if len(fldPath) == 1 {
|
||||
return ec.AccountSummary, nil
|
||||
}
|
||||
return ec.AccountSummary.FieldAsInterface(fldPath[1:])
|
||||
case utils.Timings:
|
||||
if len(fldPath) == 1 {
|
||||
return ec.Timings, nil
|
||||
}
|
||||
return ec.Timings.FieldAsInterface(fldPath[1:])
|
||||
case utils.Rates:
|
||||
if len(fldPath) == 1 {
|
||||
return ec.Rates, nil
|
||||
}
|
||||
return ec.Rates.FieldAsInterface(fldPath[1:])
|
||||
case utils.RatingFilters:
|
||||
if len(fldPath) == 1 {
|
||||
return ec.RatingFilters, nil
|
||||
}
|
||||
return ec.RatingFilters.FieldAsInterface(fldPath[1:])
|
||||
case utils.Accounting:
|
||||
if len(fldPath) == 1 {
|
||||
return ec.Accounting, nil
|
||||
}
|
||||
return ec.Accounting.FieldAsInterface(fldPath[1:])
|
||||
case utils.Rating:
|
||||
if len(fldPath) == 1 {
|
||||
return ec.Rating, nil
|
||||
}
|
||||
return ec.Rating.FieldAsInterface(fldPath[1:])
|
||||
}
|
||||
return nil, fmt.Errorf("unsupported field prefix: <%s>", fldPath[0])
|
||||
|
||||
@@ -204,6 +204,7 @@ var testEC = &EventCost{
|
||||
StartTime: "00:00:00",
|
||||
},
|
||||
},
|
||||
cache: config.NewNavigableMap(nil),
|
||||
}
|
||||
|
||||
func TestECClone(t *testing.T) {
|
||||
@@ -2514,6 +2515,7 @@ func TestECSyncKeys(t *testing.T) {
|
||||
StartTime: "00:00:00",
|
||||
},
|
||||
},
|
||||
cache: config.NewNavigableMap(nil),
|
||||
}
|
||||
|
||||
ec.SyncKeys(refEC)
|
||||
|
||||
@@ -1019,7 +1019,6 @@ func TestPassFilterMissingField(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestEventCostFilter(t *testing.T) {
|
||||
|
||||
cfg, _ := config.NewDefaultCGRConfig()
|
||||
data := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items)
|
||||
dmFilterPass := NewDataManager(data, config.CgrConfig().CacheCfg(), nil)
|
||||
@@ -1153,7 +1152,7 @@ func TestEventCostFilter(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
cd.initCache()
|
||||
cgrDp := config.NewNavigableMap(map[string]interface{}{utils.MetaEC: cd})
|
||||
|
||||
if pass, err := filterS.Pass("cgrates.org",
|
||||
|
||||
@@ -124,6 +124,7 @@ func TestResponderGobSMCost(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error("decode error: ", err)
|
||||
}
|
||||
q.Cost.CostDetails.initCache()
|
||||
if !reflect.DeepEqual(attr, q) {
|
||||
t.Error("wrong transmission")
|
||||
}
|
||||
|
||||
@@ -906,6 +906,7 @@ func (ms *MongoStorage) GetSMCosts(cgrid, runid, originHost, originIDPrefix stri
|
||||
return err
|
||||
}
|
||||
clone := smCost
|
||||
clone.CostDetails.initCache()
|
||||
smcs = append(smcs, &clone)
|
||||
}
|
||||
if len(smcs) == 0 {
|
||||
@@ -1165,6 +1166,7 @@ func (ms *MongoStorage) GetCDRs(qryFltr *utils.CDRsFilter, remove bool) ([]*CDR,
|
||||
return err
|
||||
}
|
||||
clone := cdr
|
||||
clone.CostDetails.initCache()
|
||||
cdrs = append(cdrs, &clone)
|
||||
}
|
||||
if len(cdrs) == 0 {
|
||||
|
||||
@@ -863,6 +863,7 @@ func (self *SQLStorage) GetSMCosts(cgrid, runid, originHost, originIDPrefix stri
|
||||
if err := json.Unmarshal([]byte(result.CostDetails), smc.CostDetails); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
smc.CostDetails.initCache()
|
||||
smCosts = append(smCosts, smc)
|
||||
}
|
||||
if len(smCosts) == 0 {
|
||||
@@ -1158,6 +1159,7 @@ func (self *SQLStorage) GetCDRs(qryFltr *utils.CDRsFilter, remove bool) ([]*CDR,
|
||||
if cdr, err := NewCDRFromSQL(result); err != nil {
|
||||
return nil, 0, err
|
||||
} else {
|
||||
cdr.CostDetails.initCache()
|
||||
cdrs = append(cdrs, cdr)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user