mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-14 20:59:53 +05:00
Added ratePRofileRatesFOrEvent apis + tests
This commit is contained in:
committed by
Dan Christian Bogos
parent
f5f6dd746a
commit
dcdd696932
@@ -268,6 +268,11 @@ func (rSv1 *RateSv1) RateProfilesForEvent(ctx *context.Context, args *utils.CGRE
|
||||
return rSv1.rS.V1RateProfilesForEvent(ctx, args, rpIDs)
|
||||
}
|
||||
|
||||
// RateProfilesForEvent returns the list of rates that are matching the event from a specific profile
|
||||
func (rSv1 *RateSv1) RateProfileRatesForEvent(ctx *context.Context, args *utils.CGREvent, rateIDs *[]string) (err error) {
|
||||
return rSv1.rS.V1RateProfileRatesForEvent(ctx, args, rateIDs)
|
||||
}
|
||||
|
||||
// CostForEvent returs the costs for the event and all the rate profile information
|
||||
func (rSv1 *RateSv1) CostForEvent(ctx *context.Context, args *utils.CGREvent, rpCost *utils.RateProfileCost) (err error) {
|
||||
return rSv1.rS.V1CostForEvent(ctx, args, rpCost)
|
||||
|
||||
@@ -76,6 +76,7 @@ var (
|
||||
testRateProfileSetMultipleRatesInProfile,
|
||||
testRateProfileUpdateProfileRatesOverwrite,
|
||||
testRateProfilesForEventMatchingEvents,
|
||||
testRateProfileRatesForEventMatchingEvents,
|
||||
testRateSKillEngine,
|
||||
}
|
||||
)
|
||||
@@ -1999,21 +2000,18 @@ func testRateProfilesForEventMatchingEvents(t *testing.T) {
|
||||
}
|
||||
ratePrf4 := &utils.APIRateProfile{
|
||||
RateProfile: &utils.RateProfile{
|
||||
Tenant: utils.CGRateSorg,
|
||||
ID: "RT_104",
|
||||
FilterIDs: []string{"*exists:~*req.Destination:"},
|
||||
MinCost: utils.NewDecimal(22, 2),
|
||||
MaxCost: utils.NewDecimal(500000, 6),
|
||||
MaxCostStrategy: "*free",
|
||||
Tenant: utils.CGRateSorg,
|
||||
ID: "RT_104",
|
||||
FilterIDs: []string{"*exists:~*req.Destination:"},
|
||||
Rates: map[string]*utils.Rate{
|
||||
"RT_Destination": {
|
||||
ID: "RT_Destination",
|
||||
"RT_Everytime": {
|
||||
ID: "RT_Everytime",
|
||||
Weights: utils.DynamicWeights{
|
||||
{
|
||||
Weight: 0,
|
||||
},
|
||||
},
|
||||
ActivationTimes: "* 16 * * *",
|
||||
ActivationTimes: "* 14 * * *",
|
||||
IntervalRates: []*utils.IntervalRate{
|
||||
{
|
||||
IntervalStart: utils.NewDecimal(0, 0),
|
||||
@@ -2149,6 +2147,135 @@ func testRateProfilesForEventMatchingEvents(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func testRateProfileRatesForEventMatchingEvents(t *testing.T) {
|
||||
// now for 2 of our profiles, we will set some rates and see what rates are matching our event
|
||||
ratePrf1 := &utils.APIRateProfile{
|
||||
RateProfile: &utils.RateProfile{
|
||||
Tenant: utils.CGRateSorg,
|
||||
ID: "RT_CGR202",
|
||||
//FilterIDs: []string{"*lte:~*opts.*usage:2m"},
|
||||
Rates: map[string]*utils.Rate{
|
||||
"RT_ALWAYS": {
|
||||
ID: "RT_ALWAYS",
|
||||
FilterIDs: []string{"*prefix:~*req.Destination:2023", "*string:~*opts.*usage:1m"},
|
||||
ActivationTimes: "* * * * *",
|
||||
IntervalRates: []*utils.IntervalRate{
|
||||
{
|
||||
IntervalStart: utils.NewDecimal(0, 0),
|
||||
FixedFee: utils.NewDecimal(22, 2),
|
||||
Increment: utils.NewDecimal(int64(5*time.Second), 0),
|
||||
RecurrentFee: utils.NewDecimal(int64(5*time.Second), 0),
|
||||
Unit: utils.NewDecimal(int64(time.Minute), 0),
|
||||
},
|
||||
},
|
||||
},
|
||||
"RT_WEEKEND": {
|
||||
ID: "RT_WEEKEND",
|
||||
ActivationTimes: "* * * * 5-6",
|
||||
FilterIDs: []string{"*prefix:~*req.Destination:2023"},
|
||||
IntervalRates: []*utils.IntervalRate{
|
||||
{
|
||||
IntervalStart: utils.NewDecimal(0, 0),
|
||||
Increment: utils.NewDecimal(int64(time.Second), 0),
|
||||
RecurrentFee: utils.NewDecimal(int64(time.Second), 0),
|
||||
Unit: utils.NewDecimal(int64(time.Minute), 0),
|
||||
},
|
||||
},
|
||||
},
|
||||
"RT_SPECIAL": {
|
||||
ID: "RT_SPECIAL",
|
||||
ActivationTimes: "* 12 * * *",
|
||||
FilterIDs: []string{"*string:~*req.Account:2021",
|
||||
"*string:~*req.Destination:2023"},
|
||||
IntervalRates: []*utils.IntervalRate{
|
||||
{
|
||||
IntervalStart: utils.NewDecimal(int64(50*time.Second), 0),
|
||||
Increment: utils.NewDecimal(int64(2*time.Second), 0),
|
||||
RecurrentFee: utils.NewDecimal(int64(2*time.Second), 0),
|
||||
Unit: utils.NewDecimal(int64(time.Minute), 0),
|
||||
},
|
||||
},
|
||||
},
|
||||
"RT_DIFFERENT": {
|
||||
ID: "RT_DIFFERENT",
|
||||
ActivationTimes: "10 12 * * *",
|
||||
//FilterIDs: []string{"*lte:~*opts.*usage:2m"},
|
||||
IntervalRates: []*utils.IntervalRate{
|
||||
{
|
||||
IntervalStart: utils.NewDecimal(int64(50*time.Second), 0),
|
||||
Increment: utils.NewDecimal(int64(2*time.Second), 0),
|
||||
RecurrentFee: utils.NewDecimal(int64(2*time.Second), 0),
|
||||
Unit: utils.NewDecimal(int64(time.Minute), 0),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
var reply string
|
||||
if err := rateSRPC.Call(context.Background(), utils.AdminSv1SetRateProfile,
|
||||
ratePrf1, &reply); err != nil {
|
||||
t.Error(err)
|
||||
} else if reply != utils.OK {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
expected := []string{"RT_DIFFERENT"}
|
||||
var rateIDs []string
|
||||
if err := rateSRPC.Call(context.Background(), utils.RateSv1RateProfileRatesForEvent,
|
||||
&utils.CGREvent{
|
||||
Tenant: "cgrates.org",
|
||||
Event: map[string]interface{}{
|
||||
"Account": "2021",
|
||||
},
|
||||
APIOpts: map[string]interface{}{
|
||||
utils.MetaRateProfileID: "RT_CGR202",
|
||||
utils.MetaUsage: "1m",
|
||||
},
|
||||
}, &rateIDs); err != nil {
|
||||
t.Error(err)
|
||||
} else {
|
||||
sort.Slice(expected, func(i, j int) bool {
|
||||
return expected[i] < expected[j]
|
||||
})
|
||||
sort.Slice(rateIDs, func(i, j int) bool {
|
||||
return rateIDs[i] < rateIDs[j]
|
||||
})
|
||||
if !reflect.DeepEqual(expected, rateIDs) {
|
||||
t.Errorf("Expected %+v, received %+v", expected, rateIDs)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
expected := []string{"RT_DIFFERENT"}
|
||||
var rateIDs []string
|
||||
if err := rateSRPC.Call(context.Background(), utils.RateSv1RateProfileRatesForEvent,
|
||||
&utils.CGREvent{
|
||||
Tenant: "cgrates.org",
|
||||
Event: map[string]interface{}{
|
||||
"Account": "2021",
|
||||
utils.Destination: "2023",
|
||||
},
|
||||
APIOpts: map[string]interface{}{
|
||||
utils.MetaRateProfileID: "RT_CGR202",
|
||||
utils.MetaUsage: "1m",
|
||||
},
|
||||
}, &rateIDs); err != nil {
|
||||
t.Error(err)
|
||||
} else {
|
||||
sort.Slice(expected, func(i, j int) bool {
|
||||
return expected[i] < expected[j]
|
||||
})
|
||||
sort.Slice(rateIDs, func(i, j int) bool {
|
||||
return rateIDs[i] < rateIDs[j]
|
||||
})
|
||||
if !reflect.DeepEqual(expected, rateIDs) {
|
||||
t.Errorf("Expected %+v, received %+v", expected, rateIDs)
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
//Kill the engine when it is about to be finished
|
||||
func testRateSKillEngine(t *testing.T) {
|
||||
if err := engine.KillEngine(100); err != nil {
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
{"tag": "Tenant", "path": "Tenant", "type": "*variable", "value": "~*req.0", "mandatory": true},
|
||||
{"tag": "ID", "path": "ID", "type": "*variable", "value": "~*req.1", "mandatory": true},
|
||||
{"tag": "FilterIDs", "path": "FilterIDs", "type": "*variable", "value": "~*req.2"},
|
||||
{"tag": "Weight", "path": "Weight", "type": "*variable", "value": "~*req.3"},
|
||||
{"tag": "Weights", "path": "Weights", "type": "*variable", "value": "~*req.3"},
|
||||
{"tag": "Schedule", "path": "Schedule", "type": "*variable", "value": "~*req.4"},
|
||||
// {"tag": "TargetType", "path": "TargetType", "type": "*variable", "value": "~*req.5"},
|
||||
{"tag": "TargetIDs", "path": "Targets[<~*req.5>]", "type": "*variable", "value": "~*req.6"},
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
|
||||
"rates": {
|
||||
"enabled": true,
|
||||
"prefix_indexed_fields": ["*req.Destination"],
|
||||
"exists_indexed_fields": ["*req.Destination"],
|
||||
},
|
||||
|
||||
"admins": {
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
"rates": {
|
||||
"enabled": true,
|
||||
"prefix_indexed_fields": ["*req.Destination"],
|
||||
"exists_indexed_fields": ["*req.Destination"],
|
||||
},
|
||||
|
||||
"admins": {
|
||||
|
||||
@@ -267,6 +267,61 @@ func (rS *RateS) V1RateProfilesForEvent(ctx *context.Context, args *utils.CGREve
|
||||
return
|
||||
}
|
||||
|
||||
// RateProfilesForEvent returns the list of rates that are matching the event from a specific profile
|
||||
func (rS *RateS) V1RateProfileRatesForEvent(ctx *context.Context, args *utils.CGREvent, rtIDs *[]string) (err error) {
|
||||
if args == nil {
|
||||
return utils.NewErrMandatoryIeMissing(utils.CGREventString)
|
||||
}
|
||||
if _, has := args.APIOpts[utils.MetaRateProfileID]; !has {
|
||||
return utils.NewErrMandatoryIeMissing(utils.MetaRateProfileID)
|
||||
}
|
||||
rpID := utils.IfaceAsString(args.APIOpts[utils.MetaRateProfileID])
|
||||
tnt := args.Tenant
|
||||
if tnt == utils.EmptyString {
|
||||
tnt = rS.cfg.GeneralCfg().DefaultTenant
|
||||
}
|
||||
evNM := args.AsDataProvider()
|
||||
var rateIDs utils.StringSet
|
||||
if rateIDs, err = engine.MatchingItemIDsForEvent(ctx,
|
||||
evNM,
|
||||
rS.cfg.RateSCfg().RateStringIndexedFields,
|
||||
rS.cfg.RateSCfg().RatePrefixIndexedFields,
|
||||
rS.cfg.RateSCfg().RateSuffixIndexedFields,
|
||||
rS.cfg.RateSCfg().RateExistsIndexedFields,
|
||||
rS.cfg.RateSCfg().RateNotExistsIndexedFields,
|
||||
rS.dm,
|
||||
utils.CacheRateFilterIndexes,
|
||||
utils.ConcatenatedKey(tnt, rpID),
|
||||
rS.cfg.RateSCfg().RateIndexedSelects,
|
||||
rS.cfg.RateSCfg().RateNestedFields,
|
||||
); err != nil {
|
||||
return
|
||||
}
|
||||
if len(rateIDs) == 0 {
|
||||
return utils.ErrNotFound
|
||||
}
|
||||
var ratesMtched []string
|
||||
for _, rateID := range rateIDs.AsSlice() {
|
||||
var rp *utils.RateProfile
|
||||
if rp, err = rS.dm.GetRateProfile(ctx, tnt, rpID, true, true, utils.NonTransactional); err != nil {
|
||||
return
|
||||
}
|
||||
rate := rp.Rates[rateID]
|
||||
var pass bool
|
||||
if pass, err = rS.fltrS.Pass(ctx, tnt, rate.FilterIDs, evNM); err != nil {
|
||||
return
|
||||
} else if !pass {
|
||||
continue
|
||||
}
|
||||
ratesMtched = append(ratesMtched, rateID)
|
||||
}
|
||||
if len(ratesMtched) == 0 {
|
||||
return utils.ErrNotFound
|
||||
}
|
||||
*rtIDs = ratesMtched
|
||||
return
|
||||
}
|
||||
|
||||
// V1CostForEvent will be called to calculate the cost for an event
|
||||
func (rS *RateS) V1CostForEvent(ctx *context.Context, args *utils.CGREvent, rpCost *utils.RateProfileCost) (err error) {
|
||||
var rPfIDs []string
|
||||
|
||||
@@ -381,6 +381,7 @@ const (
|
||||
MetaEEs = "*ees"
|
||||
MetaRateS = "*rates"
|
||||
MetaRateSOverwrite = "*rateSOverwrite"
|
||||
MetaRateProfileID = "*rateProfileID"
|
||||
MetaContinue = "*continue"
|
||||
MetaUp = "*up"
|
||||
Migrator = "migrator"
|
||||
@@ -1297,10 +1298,11 @@ const (
|
||||
)
|
||||
|
||||
const (
|
||||
RateSv1 = "RateSv1"
|
||||
RateSv1CostForEvent = "RateSv1.CostForEvent"
|
||||
RateSv1RateProfilesForEvent = "RateSv1.RateProfilesForEvent"
|
||||
RateSv1Ping = "RateSv1.Ping"
|
||||
RateSv1 = "RateSv1"
|
||||
RateSv1CostForEvent = "RateSv1.CostForEvent"
|
||||
RateSv1RateProfilesForEvent = "RateSv1.RateProfilesForEvent"
|
||||
RateSv1RateProfileRatesForEvent = "RateSv1.RateProfileRatesForEvent"
|
||||
RateSv1Ping = "RateSv1.Ping"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
Reference in New Issue
Block a user