Calculate cost from routes with rateS and move ArgsCostForEvent in utils

This commit is contained in:
TeoV
2020-11-17 17:23:57 +02:00
committed by Dan Christian Bogos
parent 1c0dc4f06a
commit 979a2818a7
7 changed files with 86 additions and 61 deletions

View File

@@ -211,7 +211,7 @@ func (rSv1 *RateSv1) Call(serviceMethod string,
return utils.APIerRPCCall(rSv1, serviceMethod, args, reply)
}
func (rSv1 *RateSv1) CostForEvent(args *rates.ArgsCostForEvent, rpCost *engine.RateProfileCost) (err error) {
func (rSv1 *RateSv1) CostForEvent(args *utils.ArgsCostForEvent, rpCost *engine.RateProfileCost) (err error) {
return rSv1.rS.V1CostForEvent(args, rpCost)
}

View File

@@ -29,7 +29,6 @@ import (
"github.com/cgrates/cgrates/config"
"github.com/cgrates/cgrates/engine"
"github.com/cgrates/cgrates/rates"
"github.com/cgrates/cgrates/utils"
)
@@ -823,7 +822,7 @@ func testV1RateCostForEventWithDefault(t *testing.T) {
}
var rply *engine.RateProfileCost
argsRt := &rates.ArgsCostForEvent{
argsRt := &utils.ArgsCostForEvent{
CGREventWithOpts: &utils.CGREventWithOpts{
CGREvent: &utils.CGREvent{
Tenant: "cgrates.org",
@@ -863,7 +862,7 @@ func testV1RateCostForEventWithDefault(t *testing.T) {
func testV1RateCostForEventWithUsage(t *testing.T) {
var rply *engine.RateProfileCost
argsRt := &rates.ArgsCostForEvent{
argsRt := &utils.ArgsCostForEvent{
CGREventWithOpts: &utils.CGREventWithOpts{
Opts: map[string]interface{}{
utils.OptsRatesUsage: "2m10s",
@@ -929,7 +928,7 @@ func testV1RateCostForEventWithUsage(t *testing.T) {
t.Errorf("Expected %+v \n, received %+v", utils.ToJSON(exp), utils.ToJSON(rply))
}
argsRt2 := &rates.ArgsCostForEvent{
argsRt2 := &utils.ArgsCostForEvent{
CGREventWithOpts: &utils.CGREventWithOpts{
Opts: map[string]interface{}{
utils.OptsRatesUsage: "4h10m15s",
@@ -978,7 +977,7 @@ func testV1RateCostForEventWithUsage(t *testing.T) {
func testV1RateCostForEventWithWrongUsage(t *testing.T) {
var rply *engine.RateProfileCost
argsRt := &rates.ArgsCostForEvent{
argsRt := &utils.ArgsCostForEvent{
CGREventWithOpts: &utils.CGREventWithOpts{
Opts: map[string]interface{}{
utils.OptsRatesUsage: "wrongUsage",
@@ -1020,7 +1019,7 @@ func testV1RateCostForEventWithStartTime(t *testing.T) {
}
var rply *engine.RateProfileCost
argsRt := &rates.ArgsCostForEvent{
argsRt := &utils.ArgsCostForEvent{
CGREventWithOpts: &utils.CGREventWithOpts{
Opts: map[string]interface{}{
utils.OptsRatesStartTime: time.Date(2018, 8, 24, 16, 00, 26, 0, time.UTC),
@@ -1059,7 +1058,7 @@ func testV1RateCostForEventWithStartTime(t *testing.T) {
t.Errorf("Expected %+v \n, received %+v", utils.ToJSON(exp), utils.ToJSON(rply))
}
argsRt2 := &rates.ArgsCostForEvent{
argsRt2 := &utils.ArgsCostForEvent{
CGREventWithOpts: &utils.CGREventWithOpts{
Opts: map[string]interface{}{
utils.OptsRatesStartTime: time.Date(2018, 8, 24, 16, 00, 26, 0, time.UTC).String(),
@@ -1082,7 +1081,7 @@ func testV1RateCostForEventWithStartTime(t *testing.T) {
func testV1RateCostForEventWithWrongStartTime(t *testing.T) {
var rply *engine.RateProfileCost
argsRt := &rates.ArgsCostForEvent{
argsRt := &utils.ArgsCostForEvent{
CGREventWithOpts: &utils.CGREventWithOpts{
Opts: map[string]interface{}{
utils.OptsRatesStartTime: "wrongTime",
@@ -1104,7 +1103,7 @@ func testV1RateCostForEventWithWrongStartTime(t *testing.T) {
func testV1RateCostForEventWithOpts(t *testing.T) {
var rply *engine.RateProfileCost
argsRt := &rates.ArgsCostForEvent{
argsRt := &utils.ArgsCostForEvent{
CGREventWithOpts: &utils.CGREventWithOpts{
Opts: map[string]interface{}{
utils.OptsRatesStartTime: time.Date(2018, 8, 24, 16, 00, 26, 0, time.UTC),
@@ -1171,7 +1170,7 @@ func testV1RateCostForEventWithOpts(t *testing.T) {
t.Errorf("Expected %+v \n, received %+v", utils.ToJSON(exp), utils.ToJSON(rply))
}
argsRt2 := &rates.ArgsCostForEvent{
argsRt2 := &utils.ArgsCostForEvent{
CGREventWithOpts: &utils.CGREventWithOpts{
Opts: map[string]interface{}{
utils.OptsRatesStartTime: time.Date(2018, 8, 24, 16, 00, 26, 0, time.UTC),
@@ -1269,7 +1268,7 @@ func testV1RateCostForEventSpecial(t *testing.T) {
}
var rply *engine.RateProfileCost
argsRt := &rates.ArgsCostForEvent{
argsRt := &utils.ArgsCostForEvent{
CGREventWithOpts: &utils.CGREventWithOpts{
Opts: map[string]interface{}{
utils.OptsRatesStartTime: time.Date(2020, 12, 23, 23, 0, 0, 0, time.UTC),
@@ -1409,7 +1408,7 @@ func testV1RateCostForEventThreeRates(t *testing.T) {
}
var rply *engine.RateProfileCost
argsRt := &rates.ArgsCostForEvent{
argsRt := &utils.ArgsCostForEvent{
CGREventWithOpts: &utils.CGREventWithOpts{
Opts: map[string]interface{}{
utils.OptsRatesStartTime: time.Date(2020, 12, 31, 10, 0, 0, 0, time.UTC),

View File

@@ -276,24 +276,49 @@ func (rpS *RouteService) costForEvent(ev *utils.CGREvent,
}
if accountMaxUsage == 0 || accountMaxUsage < initialUsage {
var rpCost map[string]interface{}
if err := rpS.connMgr.Call(rpS.cgrcfg.RouteSCfg().RALsConns, nil, utils.ResponderGetCostOnRatingPlans,
&utils.GetCostOnRatingPlansArgs{
Tenant: ev.Tenant,
Account: acnt,
Subject: subj,
Destination: dst,
SetupTime: sTime,
Usage: usage,
RatingPlanIDs: rpIDs,
}, &rpCost); err != nil {
return nil, err
}
for k, v := range rpCost { // do not overwrite the return map
costData[k] = v
var rateRply *RateProfileCost
if len(rpS.cgrcfg.RouteSCfg().RateSConns) != 0 {
if err := rpS.connMgr.Call(rpS.cgrcfg.RouteSCfg().RateSConns, nil, utils.RateSv1CostForEvent,
&utils.ArgsCostForEvent{
CGREventWithOpts: &utils.CGREventWithOpts{
Opts: map[string]interface{}{ // add the setup time and usage in opts
utils.OptsRatesStartTime: sTime,
utils.OptsRatesUsage: usage,
},
CGREvent: &utils.CGREvent{ // add the rest of the field in event
Tenant: ev.Tenant,
ID: utils.UUIDSha1Prefix(),
Event: map[string]interface{}{
utils.Account: acnt,
utils.Subject: subj,
utils.Destination: dst,
},
},
},
}, &rateRply); err != nil {
return nil, err
}
costData[utils.Cost] = rateRply.Cost
costData[utils.RateProfileMatched] = rateRply.ID
} else {
var rpCost map[string]interface{}
if err := rpS.connMgr.Call(rpS.cgrcfg.RouteSCfg().RALsConns, nil, utils.ResponderGetCostOnRatingPlans,
&utils.GetCostOnRatingPlansArgs{
Tenant: ev.Tenant,
Account: acnt,
Subject: subj,
Destination: dst,
SetupTime: sTime,
Usage: usage,
RatingPlanIDs: rpIDs,
}, &rpCost); err != nil {
return nil, err
}
for k, v := range rpCost { // do not overwrite the return map
costData[k] = v
}
}
}
return
}

View File

@@ -69,7 +69,7 @@ func (rS *RateS) Call(serviceMethod string, args interface{}, reply interface{})
}
// matchingRateProfileForEvent returns the matched RateProfile for the given event
func (rS *RateS) matchingRateProfileForEvent(tnt string, rPfIDs []string, args *ArgsCostForEvent) (rtPfl *engine.RateProfile, err error) {
func (rS *RateS) matchingRateProfileForEvent(tnt string, rPfIDs []string, args *utils.ArgsCostForEvent) (rtPfl *engine.RateProfile, err error) {
evNm := utils.MapStorage{
utils.MetaReq: args.CGREvent.Event,
utils.MetaOpts: args.Opts,
@@ -123,7 +123,7 @@ func (rS *RateS) matchingRateProfileForEvent(tnt string, rPfIDs []string, args *
}
// costForEvent computes the cost for an event based on a preselected rating profile
func (rS *RateS) rateProfileCostForEvent(rtPfl *engine.RateProfile, args *ArgsCostForEvent) (rpCost *engine.RateProfileCost, err error) {
func (rS *RateS) rateProfileCostForEvent(rtPfl *engine.RateProfile, args *utils.ArgsCostForEvent) (rpCost *engine.RateProfileCost, err error) {
var rtIDs utils.StringSet
if rtIDs, err = engine.MatchingItemIDsForEvent(
args.CGREventWithOpts.CGREvent.Event,
@@ -170,30 +170,8 @@ func (rS *RateS) rateProfileCostForEvent(rtPfl *engine.RateProfile, args *ArgsCo
return
}
// ArgsCostForEvent arguments used for proccess event
type ArgsCostForEvent struct {
RateProfileIDs []string
*utils.CGREventWithOpts
}
// StartTime returns the event time used to check active rate profiles
func (args *ArgsCostForEvent) StartTime(tmz string) (sTime time.Time, err error) {
if tIface, has := args.Opts[utils.OptsRatesStartTime]; has {
return utils.IfaceAsTime(tIface, tmz)
}
return time.Now(), nil
}
// usage returns the event time used to check active rate profiles
func (args *ArgsCostForEvent) Usage() (usage time.Duration, err error) {
if uIface, has := args.Opts[utils.OptsRatesUsage]; has {
return utils.IfaceAsDuration(uIface)
}
return time.Duration(time.Minute), nil
}
// V1CostForEvent will be called to calculate the cost for an event
func (rS *RateS) V1CostForEvent(args *ArgsCostForEvent, rpCost *engine.RateProfileCost) (err error) {
func (rS *RateS) V1CostForEvent(args *utils.ArgsCostForEvent, rpCost *engine.RateProfileCost) (err error) {
rPfIDs := make([]string, len(args.RateProfileIDs))
for i, rpID := range args.RateProfileIDs {
rPfIDs[i] = rpID

View File

@@ -96,7 +96,7 @@ func TestMatchingRateProfileEvent(t *testing.T) {
t.Error(err)
}
if rtPRf, err := rate.matchingRateProfileForEvent("cgrates.org", []string{},
&ArgsCostForEvent{
&utils.ArgsCostForEvent{
CGREventWithOpts: &utils.CGREventWithOpts{
CGREvent: &utils.CGREvent{
Tenant: "cgrates.org",
@@ -115,7 +115,7 @@ func TestMatchingRateProfileEvent(t *testing.T) {
}
if _, err := rate.matchingRateProfileForEvent("cgrates.org", []string{},
&ArgsCostForEvent{
&utils.ArgsCostForEvent{
CGREventWithOpts: &utils.CGREventWithOpts{
CGREvent: &utils.CGREvent{
Tenant: "cgrates.org",
@@ -131,7 +131,7 @@ func TestMatchingRateProfileEvent(t *testing.T) {
t.Error(err)
}
if _, err := rate.matchingRateProfileForEvent("cgrates.org", []string{},
&ArgsCostForEvent{
&utils.ArgsCostForEvent{
CGREventWithOpts: &utils.CGREventWithOpts{
CGREvent: &utils.CGREvent{
Tenant: "cgrates.org",
@@ -147,7 +147,7 @@ func TestMatchingRateProfileEvent(t *testing.T) {
t.Error(err)
}
if _, err := rate.matchingRateProfileForEvent("cgrates.org", []string{},
&ArgsCostForEvent{
&utils.ArgsCostForEvent{
CGREventWithOpts: &utils.CGREventWithOpts{
CGREvent: &utils.CGREvent{
Tenant: "cgrates.org",
@@ -164,7 +164,7 @@ func TestMatchingRateProfileEvent(t *testing.T) {
}
if _, err := rate.matchingRateProfileForEvent("cgrates.org", []string{"rp2"},
&ArgsCostForEvent{
&utils.ArgsCostForEvent{
CGREventWithOpts: &utils.CGREventWithOpts{
CGREvent: &utils.CGREvent{
Tenant: "cgrates.org",
@@ -182,7 +182,7 @@ func TestMatchingRateProfileEvent(t *testing.T) {
rpp.FilterIDs = []string{"*string:~*req.Account:1001;1002;1003", "*gt:~*req.Cost{*:10"}
if _, err := rate.matchingRateProfileForEvent("cgrates.org", []string{},
&ArgsCostForEvent{
&utils.ArgsCostForEvent{
CGREventWithOpts: &utils.CGREventWithOpts{
CGREvent: &utils.CGREvent{
Tenant: "cgrates.org",
@@ -200,7 +200,7 @@ func TestMatchingRateProfileEvent(t *testing.T) {
rate.dm = nil
if _, err := rate.matchingRateProfileForEvent("cgrates.org", []string{"rp3"},
&ArgsCostForEvent{
&utils.ArgsCostForEvent{
CGREventWithOpts: &utils.CGREventWithOpts{
CGREvent: &utils.CGREvent{
Tenant: "cgrates.org",

View File

@@ -1485,3 +1485,25 @@ type ArgExportCDRs struct {
Verbose bool // verbose is used to inform the user about the positive and negative exported cdrs
RPCCDRsFilter
}
// ArgsCostForEvent arguments used for process event
type ArgsCostForEvent struct {
RateProfileIDs []string
*CGREventWithOpts
}
// StartTime returns the event time used to check active rate profiles
func (args *ArgsCostForEvent) StartTime(tmz string) (sTime time.Time, err error) {
if tIface, has := args.Opts[OptsRatesStartTime]; has {
return IfaceAsTime(tIface, tmz)
}
return time.Now(), nil
}
// usage returns the event time used to check active rate profiles
func (args *ArgsCostForEvent) Usage() (usage time.Duration, err error) {
if uIface, has := args.Opts[OptsRatesUsage]; has {
return IfaceAsDuration(uIface)
}
return time.Duration(time.Minute), nil
}

View File

@@ -875,6 +875,7 @@ const (
HashtagSep = "#"
MetaRounding = "*rounding"
StatsNA = -1.0
RateProfileMatched = "RateProfileMatched"
)
// Migrator Action