mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Started adding FieldAsInterface for EventCost
This commit is contained in:
committed by
Dan Christian Bogos
parent
b79b1dc39d
commit
d8333b5b68
@@ -35,9 +35,9 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
apierCfgPath string
|
||||
apierCfg *config.CGRConfig
|
||||
apierRPC *rpc.Client
|
||||
apierCfgPath string
|
||||
apierCfg *config.CGRConfig
|
||||
apierRPC *rpc.Client
|
||||
APIerSv2ConfigDIR string //run tests for specific configuration
|
||||
|
||||
sTestsAPIer = []func(t *testing.T){
|
||||
|
||||
@@ -59,9 +59,9 @@ README:
|
||||
* Execute remote Apis and test their replies(follow testtp scenario so we can test load in dataDb also).
|
||||
*/
|
||||
var (
|
||||
cfgPath string
|
||||
cfg *config.CGRConfig
|
||||
rater *rpc.Client
|
||||
cfgPath string
|
||||
cfg *config.CGRConfig
|
||||
rater *rpc.Client
|
||||
APIerSv1ConfigDIR string
|
||||
|
||||
apierTests = []func(t *testing.T){
|
||||
|
||||
@@ -34,10 +34,10 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
apierCfgPath string
|
||||
apierCfg *config.CGRConfig
|
||||
apierRPC *rpc.Client
|
||||
dm *engine.DataManager // share db connection here so we can check data we set through APIs
|
||||
apierCfgPath string
|
||||
apierCfg *config.CGRConfig
|
||||
apierRPC *rpc.Client
|
||||
dm *engine.DataManager // share db connection here so we can check data we set through APIs
|
||||
APIerSv2ConfDIR string
|
||||
|
||||
sTestsv2it = []func(t *testing.T){
|
||||
|
||||
@@ -236,6 +236,13 @@ func (scfg *SessionSCfg) loadFromJsonCfg(jsnCfg *SessionSJsonCfg) (err error) {
|
||||
scfg.SessionTTLLastUsed = &sessionTTLLastUsed
|
||||
}
|
||||
}
|
||||
if jsnCfg.Session_ttl_usage != nil {
|
||||
if sessionTTLUsage, err := utils.ParseDurationWithNanosecs(*jsnCfg.Session_ttl_usage); err != nil {
|
||||
return err
|
||||
} else {
|
||||
scfg.SessionTTLUsage = &sessionTTLUsage
|
||||
}
|
||||
}
|
||||
if jsnCfg.Session_indexes != nil {
|
||||
scfg.SessionIndexes = utils.StringMapFromSlice(*jsnCfg.Session_indexes)
|
||||
}
|
||||
|
||||
@@ -20,11 +20,15 @@ package engine
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
// NewBareEventCost will intialize the EventCost with minimum information
|
||||
func NewBareEventCost() *EventCost {
|
||||
return &EventCost{
|
||||
Rating: make(Rating),
|
||||
@@ -36,6 +40,7 @@ func NewBareEventCost() *EventCost {
|
||||
}
|
||||
}
|
||||
|
||||
// NewEventCostFromCallCost will initilaize the EventCost from a CallCost
|
||||
func NewEventCostFromCallCost(cc *CallCost, cgrID, runID string) (ec *EventCost) {
|
||||
ec = NewBareEventCost()
|
||||
ec.CGRID = cgrID
|
||||
@@ -169,6 +174,7 @@ func (ec *EventCost) rateIntervalForRatingID(ratingID string) (ri *RateInterval)
|
||||
return
|
||||
}
|
||||
|
||||
// Clone will create a clone of the object
|
||||
func (ec *EventCost) Clone() (cln *EventCost) {
|
||||
if ec == nil {
|
||||
return
|
||||
@@ -228,7 +234,7 @@ func (ec *EventCost) ResetCounters() {
|
||||
}
|
||||
}
|
||||
|
||||
// ComputeCost iterates through Charges, computing EventCost.Cost
|
||||
// GetCost iterates through Charges, computing EventCost.Cost
|
||||
func (ec *EventCost) GetCost() float64 {
|
||||
if ec.Cost == nil {
|
||||
var cost float64
|
||||
@@ -241,7 +247,7 @@ func (ec *EventCost) GetCost() float64 {
|
||||
return *ec.Cost
|
||||
}
|
||||
|
||||
// ComputeUsage iterates through Charges, computing EventCost.Usage
|
||||
// GetUsage iterates through Charges, computing EventCost.Usage
|
||||
func (ec *EventCost) GetUsage() time.Duration {
|
||||
if ec.Usage == nil {
|
||||
var usage time.Duration
|
||||
@@ -264,7 +270,7 @@ func (ec *EventCost) ComputeEventCostUsageIndexes() {
|
||||
}
|
||||
}
|
||||
|
||||
// AsCallDescriptor converts an EventCost into a CallDescriptor
|
||||
// AsRefundIncrements converts an EventCost into a CallDescriptor
|
||||
func (ec *EventCost) AsRefundIncrements(tor string) (cd *CallDescriptor) {
|
||||
cd = &CallDescriptor{
|
||||
CgrID: ec.CGRID,
|
||||
@@ -463,7 +469,7 @@ func (ec *EventCost) appendCIlFromEC(oEC *EventCost, cIlIdx int) {
|
||||
func (ec *EventCost) appendChargingIntervalFromEventCost(oEC *EventCost, cIlIdx int) {
|
||||
lenChargers := len(ec.Charges)
|
||||
if lenChargers != 0 && ec.Charges[lenChargers-1].PartiallyEquals(oEC.Charges[cIlIdx]) {
|
||||
ec.Charges[lenChargers-1].CompressFactor += 1
|
||||
ec.Charges[lenChargers-1].CompressFactor++
|
||||
} else {
|
||||
ec.appendCIlFromEC(oEC, cIlIdx)
|
||||
}
|
||||
@@ -793,7 +799,7 @@ func (ec *EventCost) Trim(atUsage time.Duration) (srplusEC *EventCost, err error
|
||||
}
|
||||
if len(srplsIncrements) != 0 { // partially covering, need trim
|
||||
if lastActiveCIl.CompressFactor > 1 { // ChargingInterval not covering in full, need to split it
|
||||
lastActiveCIl.CompressFactor -= 1
|
||||
lastActiveCIl.CompressFactor--
|
||||
ec.Charges = append(ec.Charges, lastActiveCIl.Clone())
|
||||
lastActiveCIl = ec.Charges[len(ec.Charges)-1]
|
||||
lastActiveCIl.CompressFactor = 1
|
||||
@@ -833,3 +839,142 @@ func (ec *EventCost) Trim(atUsage time.Duration) (srplusEC *EventCost, err error
|
||||
ec.RemoveStaleReferences() // data should be transferred by now, can clean the old one
|
||||
return
|
||||
}
|
||||
|
||||
// getIndex returns the path and index if index present
|
||||
// path[index]=>path,index
|
||||
// path=>path,nil
|
||||
func getIndex(spath string) (opath string, idx *int) {
|
||||
idxStart := strings.Index(spath, utils.IdxStart)
|
||||
if idxStart == -1 || !strings.HasSuffix(spath, utils.IdxEnd) {
|
||||
return spath, nil
|
||||
}
|
||||
slctr := spath[idxStart+1 : len(spath)-1]
|
||||
opath = spath[:idxStart]
|
||||
if strings.HasPrefix(slctr, utils.DynamicDataPrefix) {
|
||||
return
|
||||
}
|
||||
idxVal, err := strconv.Atoi(slctr)
|
||||
if err != nil {
|
||||
return spath, nil
|
||||
}
|
||||
return opath, &idxVal
|
||||
}
|
||||
|
||||
// FieldAsInterface func to implement DataProvider
|
||||
func (ec *EventCost) FieldAsInterface(fldPath []string) (val interface{}, err error) {
|
||||
if len(fldPath) == 0 {
|
||||
return nil, utils.ErrNotFound
|
||||
}
|
||||
switch fldPath[0] {
|
||||
default: //"Charges [1]"
|
||||
opath, indx := getIndex(fldPath[0])
|
||||
if opath != utils.Charges {
|
||||
return nil, fmt.Errorf("unsupported field prefix: <%s>", opath)
|
||||
}
|
||||
if indx != nil {
|
||||
chr := ec.Charges[*indx]
|
||||
if len(fldPath) == 1 {
|
||||
return chr, nil
|
||||
}
|
||||
if fldPath[1] == utils.Rating {
|
||||
return ec.getRatingForPath(fldPath[2:], ec.Rating[chr.RatingID])
|
||||
}
|
||||
}
|
||||
case utils.Charges: // not needed?
|
||||
// return ec.Charges.FieldAsInterface(fldPath[1:])
|
||||
case utils.CGRID:
|
||||
if len(fldPath) != 1 {
|
||||
return nil, utils.ErrNotFound
|
||||
}
|
||||
return ec.CGRID, nil
|
||||
case utils.RunID:
|
||||
if len(fldPath) != 1 {
|
||||
return nil, utils.ErrNotFound
|
||||
}
|
||||
return ec.RunID, nil
|
||||
case utils.StartTime:
|
||||
if len(fldPath) != 1 {
|
||||
return nil, utils.ErrNotFound
|
||||
}
|
||||
return ec.StartTime, nil
|
||||
case utils.Usage:
|
||||
if len(fldPath) != 1 {
|
||||
return nil, utils.ErrNotFound
|
||||
}
|
||||
return ec.Usage, nil
|
||||
case utils.Cost:
|
||||
if len(fldPath) != 1 {
|
||||
return nil, utils.ErrNotFound
|
||||
}
|
||||
return ec.Cost, nil
|
||||
case utils.AccountSummary:
|
||||
// return ec.AccountSummary.FieldAsInterface(fldPath[1:])
|
||||
case utils.Timings: // not needed?
|
||||
// return ec.Timings.FieldAsInterface(fldPath[1:])
|
||||
case utils.Rates: // not needed?
|
||||
// return ec.Rates.FieldAsInterface(fldPath[1:])
|
||||
case utils.RatingFilters: // not needed?
|
||||
// return ec.RatingFilters.FieldAsInterface(fldPath[1:])
|
||||
case utils.Accounting: // not needed?
|
||||
// return ec.Accounting.FieldAsInterface(fldPath[1:])
|
||||
case utils.Rating: // not needed?
|
||||
// return ec.Rating.FieldAsInterface(fldPath[1:])
|
||||
}
|
||||
return nil, fmt.Errorf("unsupported field prefix: <%s>", fldPath[0])
|
||||
}
|
||||
|
||||
func (ec *EventCost) getRatingForPath(fldPath []string, rating *RatingUnit) (val interface{}, err error) {
|
||||
if rating == nil {
|
||||
return nil, utils.ErrNotFound
|
||||
}
|
||||
if len(fldPath) == 0 {
|
||||
return rating, nil
|
||||
}
|
||||
|
||||
switch fldPath[0] {
|
||||
default:
|
||||
opath, indx := getIndex(fldPath[0])
|
||||
if opath != utils.Rates {
|
||||
return nil, fmt.Errorf("unsupported field prefix: <%s>", opath)
|
||||
}
|
||||
rts, has := ec.Rates[rating.RatesID]
|
||||
if !has || rts == nil {
|
||||
return nil, utils.ErrNotFound
|
||||
}
|
||||
if indx != nil {
|
||||
rt := rts[*indx]
|
||||
if len(fldPath) == 1 {
|
||||
return rt, nil
|
||||
}
|
||||
return rt.FieldAsInterface(fldPath[1:])
|
||||
}
|
||||
case utils.Rates:
|
||||
rts, has := ec.Rates[rating.RatesID]
|
||||
if !has || rts == nil {
|
||||
return nil, utils.ErrNotFound
|
||||
}
|
||||
if len(fldPath) != 1 {
|
||||
return nil, utils.ErrNotFound // no field on slice
|
||||
}
|
||||
return rts, nil
|
||||
case utils.Timing:
|
||||
tmg, has := ec.Timings[rating.TimingID]
|
||||
if !has || tmg == nil {
|
||||
return nil, utils.ErrNotFound
|
||||
}
|
||||
if len(fldPath) == 1 {
|
||||
return tmg, nil
|
||||
}
|
||||
return tmg.FieldAsInterface(fldPath[1:])
|
||||
case utils.RatingFilter:
|
||||
rtFltr, has := ec.RatingFilters[rating.RatingFiltersID]
|
||||
if !has || rtFltr == nil {
|
||||
return nil, utils.ErrNotFound
|
||||
}
|
||||
if len(fldPath) == 1 {
|
||||
return rtFltr, nil
|
||||
}
|
||||
return rtFltr.FieldAsInterface(fldPath[1:])
|
||||
}
|
||||
return rating.FieldAsInterface(fldPath)
|
||||
}
|
||||
|
||||
@@ -160,8 +160,7 @@ func (spS *SupplierService) matchingSupplierProfilesForEvent(ev *utils.CGREvent,
|
||||
if singleResult {
|
||||
matchingSLP = make([]*SupplierProfile, 1)
|
||||
}
|
||||
evNm := config.NewNavigableMap(nil)
|
||||
evNm.Set([]string{utils.MetaReq}, ev.Event, false, false)
|
||||
evNm := config.NewNavigableMap(map[string]interface{}{utils.MetaReq: ev.Event})
|
||||
for lpID := range sPrflIDs {
|
||||
splPrfl, err := spS.dm.GetSupplierProfile(ev.Tenant, lpID, true, true, utils.NonTransactional)
|
||||
if err != nil {
|
||||
|
||||
@@ -147,8 +147,8 @@ func (srvMngr *ServiceManager) GetConfig() *config.CGRConfig {
|
||||
func (srvMngr *ServiceManager) StartServices() (err error) {
|
||||
go srvMngr.handleReload()
|
||||
for serviceName, shouldRun := range map[string]bool{
|
||||
utils.APIerSv1: srvMngr.GetConfig().ApierCfg().Enabled,
|
||||
utils.APIerSv2: srvMngr.GetConfig().ApierCfg().Enabled,
|
||||
utils.APIerSv1: srvMngr.GetConfig().ApierCfg().Enabled,
|
||||
utils.APIerSv2: srvMngr.GetConfig().ApierCfg().Enabled,
|
||||
utils.StorDB: srvMngr.GetConfig().RalsCfg().Enabled || srvMngr.GetConfig().CdrsCfg().Enabled,
|
||||
utils.AttributeS: srvMngr.GetConfig().AttributeSCfg().Enabled,
|
||||
utils.ChargerS: srvMngr.GetConfig().ChargerSCfg().Enabled,
|
||||
|
||||
@@ -48,6 +48,7 @@ type BiRPClient interface {
|
||||
|
||||
// getSessionTTL retrieves SessionTTL setting out of ev
|
||||
// if SessionTTLMaxDelay is present in ev, the return is randomized
|
||||
// ToDo: remove if not needed
|
||||
func getSessionTTL(ev *engine.MapEvent, cfgSessionTTL time.Duration,
|
||||
cfgSessionTTLMaxDelay *time.Duration) (ttl time.Duration, err error) {
|
||||
if ttl, err = ev.GetDuration(utils.SessionTTL); err != nil {
|
||||
|
||||
@@ -293,7 +293,7 @@ func (sS *SessionS) setSTerminator(s *Session) {
|
||||
s.sTerminator.timer.Stop()
|
||||
}
|
||||
}()
|
||||
time.Sleep(1) // force context switch to fix process message
|
||||
time.Sleep(1) // force context switching
|
||||
}
|
||||
|
||||
// forceSTerminate is called when a session times-out or it is forced from CGRateS side
|
||||
|
||||
@@ -490,6 +490,13 @@ const (
|
||||
Categories = "Categories"
|
||||
Blocker = "Blocker"
|
||||
RatingPlanID = "RatingPlanID"
|
||||
StartTime = "StartTime"
|
||||
AccountSummary = "AccountSummary"
|
||||
RatingFilters = "RatingFilters"
|
||||
RatingFilter = "RatingFilter"
|
||||
Accounting = "Accounting"
|
||||
Rating = "Rating"
|
||||
Charges = "Charges"
|
||||
MetaSessionS = "*sessions"
|
||||
MetaDefault = "*default"
|
||||
Error = "Error"
|
||||
@@ -1181,7 +1188,7 @@ const (
|
||||
APIerSv1GetAttributeProfile = "APIerSv1.GetAttributeProfile"
|
||||
APIerSv1GetAttributeProfileIDs = "APIerSv1.GetAttributeProfileIDs"
|
||||
APIerSv1RemoveAttributeProfile = "APIerSv1.RemoveAttributeProfile"
|
||||
APIerSv2SetAttributeProfile = "APIerSv2.SetAttributeProfile"
|
||||
APIerSv2SetAttributeProfile = "APIerSv2.SetAttributeProfile"
|
||||
AttributeSv1GetAttributeForEvent = "AttributeSv1.GetAttributeForEvent"
|
||||
AttributeSv1ProcessEvent = "AttributeSv1.ProcessEvent"
|
||||
AttributeSv1Ping = "AttributeSv1.Ping"
|
||||
|
||||
Reference in New Issue
Block a user