Added *routes_maxcost flag. Fixes #2563

This commit is contained in:
Trial97
2021-02-09 11:23:46 +02:00
committed by Dan Christian Bogos
parent 61e190f38d
commit a7accbd6b5
13 changed files with 738 additions and 27 deletions

View File

@@ -297,6 +297,7 @@ func (da *DiameterAgent) processRequest(reqProcessor *config.RequestProcessor,
reqProcessor.Flags.HasKey(utils.MetaSuppliersEventCost),
cgrEv, cgrArgs.ArgDispatcher, *cgrArgs.SupplierPaginator,
reqProcessor.Flags.HasKey(utils.MetaFD),
reqProcessor.Flags.ParamValue(utils.MetaSuppliersMaxCost),
)
rply := new(sessions.V1AuthorizeReply)
err = da.connMgr.Call(da.cgrCfg.DiameterAgentCfg().SessionSConns, da, utils.SessionSv1AuthorizeEvent,
@@ -368,7 +369,9 @@ func (da *DiameterAgent) processRequest(reqProcessor *config.RequestProcessor,
reqProcessor.Flags.HasKey(utils.MetaSuppliersIgnoreErrors),
reqProcessor.Flags.HasKey(utils.MetaSuppliersEventCost),
cgrEv, cgrArgs.ArgDispatcher, *cgrArgs.SupplierPaginator,
reqProcessor.Flags.HasKey(utils.MetaFD))
reqProcessor.Flags.HasKey(utils.MetaFD),
reqProcessor.Flags.ParamValue(utils.MetaSuppliersMaxCost),
)
rply := new(sessions.V1ProcessMessageReply)
err = da.connMgr.Call(da.cgrCfg.DiameterAgentCfg().SessionSConns, da, utils.SessionSv1ProcessMessage,
msgArgs, rply)

View File

@@ -218,6 +218,7 @@ func (da *DNSAgent) processRequest(reqProcessor *config.RequestProcessor,
reqProcessor.Flags.HasKey(utils.MetaSuppliersEventCost),
cgrEv, cgrArgs.ArgDispatcher, *cgrArgs.SupplierPaginator,
reqProcessor.Flags.HasKey(utils.MetaFD),
reqProcessor.Flags.ParamValue(utils.MetaSuppliersMaxCost),
)
rply := new(sessions.V1AuthorizeReply)
err = da.connMgr.Call(da.cgrCfg.DNSAgentCfg().SessionSConns, nil,
@@ -293,7 +294,9 @@ func (da *DNSAgent) processRequest(reqProcessor *config.RequestProcessor,
reqProcessor.Flags.HasKey(utils.MetaSuppliersIgnoreErrors),
reqProcessor.Flags.HasKey(utils.MetaSuppliersEventCost),
cgrEv, cgrArgs.ArgDispatcher, *cgrArgs.SupplierPaginator,
reqProcessor.Flags.HasKey(utils.MetaFD))
reqProcessor.Flags.HasKey(utils.MetaFD),
reqProcessor.Flags.ParamValue(utils.MetaSuppliersMaxCost),
)
rply := new(sessions.V1ProcessMessageReply) // need it so rpcclient can clone
err = da.connMgr.Call(da.cgrCfg.DNSAgentCfg().SessionSConns, nil,
utils.SessionSv1ProcessMessage,

View File

@@ -153,6 +153,7 @@ func (ha *HTTPAgent) processRequest(reqProcessor *config.RequestProcessor,
reqProcessor.Flags.HasKey(utils.MetaSuppliersEventCost),
cgrEv, cgrArgs.ArgDispatcher, *cgrArgs.SupplierPaginator,
reqProcessor.Flags.HasKey(utils.MetaFD),
reqProcessor.Flags.ParamValue(utils.MetaSuppliersMaxCost),
)
rply := new(sessions.V1AuthorizeReply)
err = ha.connMgr.Call(ha.sessionConns, nil, utils.SessionSv1AuthorizeEvent,
@@ -224,7 +225,9 @@ func (ha *HTTPAgent) processRequest(reqProcessor *config.RequestProcessor,
reqProcessor.Flags.HasKey(utils.MetaSuppliersIgnoreErrors),
reqProcessor.Flags.HasKey(utils.MetaSuppliersEventCost),
cgrEv, cgrArgs.ArgDispatcher, *cgrArgs.SupplierPaginator,
reqProcessor.Flags.HasKey(utils.MetaFD))
reqProcessor.Flags.HasKey(utils.MetaFD),
reqProcessor.Flags.ParamValue(utils.MetaSuppliersMaxCost),
)
rply := new(sessions.V1ProcessMessageReply)
err = ha.connMgr.Call(ha.sessionConns, nil, utils.SessionSv1ProcessMessage,
evArgs, rply)

View File

@@ -191,6 +191,56 @@ func TestKamEvV1AuthorizeArgs(t *testing.T) {
}
}
func TestKamEvV1AuthorizeArgs2(t *testing.T) {
timezone := config.CgrConfig().GeneralCfg().DefaultTimezone
kamEv := KamEvent{"event": "CGR_CALL_END",
"callid": "46c01a5c249b469e76333fc6bfa87f6a@0:0:0:0:0:0:0:0",
"from_tag": "bf71ad59", "to_tag": "7351fecf",
"cgr_reqtype": utils.META_POSTPAID, "cgr_account": "1001",
"cgr_destination": "1002", "cgr_answertime": "1419839310",
"cgr_duration": "3", "cgr_pdd": "4",
utils.CGR_SUPPLIER: "supplier2",
utils.CGR_DISCONNECT_CAUSE: "200",
utils.CGRFlags: "*accounts,*suppliers,*suppliers_maxcost:100,*suppliers_ignore_errors"}
sTime, err := utils.ParseTimeDetectLayout(kamEv[utils.AnswerTime], timezone)
if err != nil {
return
}
expected := &sessions.V1AuthorizeArgs{
GetMaxUsage: true,
CGREvent: &utils.CGREvent{
Tenant: utils.FirstNonEmpty(kamEv[utils.Tenant],
config.CgrConfig().GeneralCfg().DefaultTenant),
ID: utils.UUIDSha1Prefix(),
Time: &sTime,
Event: kamEv.AsMapStringInterface(),
},
GetSuppliers: true,
SuppliersIgnoreErrors: true,
SuppliersMaxCost: "100",
}
rcv := kamEv.V1AuthorizeArgs()
if !reflect.DeepEqual(expected.CGREvent.Tenant, rcv.CGREvent.Tenant) {
t.Errorf("Expecting: %+v, received: %+v", expected.CGREvent.Tenant, rcv.CGREvent.Tenant)
} else if !reflect.DeepEqual(expected.CGREvent.Time, rcv.CGREvent.Time) {
t.Errorf("Expecting: %+v, received: %+v", expected.CGREvent.Time, rcv.CGREvent.Time)
} else if !reflect.DeepEqual(expected.CGREvent.Event, rcv.CGREvent.Event) {
t.Errorf("Expecting: %+v, received: %+v", expected.CGREvent.Event, rcv.CGREvent.Event)
} else if !reflect.DeepEqual(expected.CGREvent.Event, rcv.CGREvent.Event) {
t.Errorf("Expecting: %+v, received: %+v", expected.CGREvent.Event, rcv.CGREvent.Event)
} else if !reflect.DeepEqual(expected.GetMaxUsage, rcv.GetMaxUsage) {
t.Errorf("Expecting: %+v, received: %+v", expected.GetMaxUsage, rcv.GetMaxUsage)
} else if !reflect.DeepEqual(expected.GetSuppliers, rcv.GetSuppliers) {
t.Errorf("Expecting: %+v, received: %+v", expected.GetSuppliers, rcv.GetSuppliers)
} else if !reflect.DeepEqual(expected.GetAttributes, rcv.GetAttributes) {
t.Errorf("Expecting: %+v, received: %+v", expected.GetAttributes, rcv.GetAttributes)
} else if !reflect.DeepEqual(expected.SuppliersMaxCost, rcv.SuppliersMaxCost) {
t.Errorf("Expecting: %+v, received: %+v", expected.SuppliersMaxCost, rcv.SuppliersMaxCost)
} else if !reflect.DeepEqual(expected.SuppliersIgnoreErrors, rcv.SuppliersIgnoreErrors) {
t.Errorf("Expecting: %+v, received: %+v", expected.SuppliersIgnoreErrors, rcv.SuppliersIgnoreErrors)
}
}
func TestKamEvAsKamAuthReply(t *testing.T) {
timezone := config.CgrConfig().GeneralCfg().DefaultTimezone
kamEv := KamEvent{"event": "CGR_CALL_END",

View File

@@ -194,6 +194,7 @@ func (ra *RadiusAgent) processRequest(reqProcessor *config.RequestProcessor,
reqProcessor.Flags.HasKey(utils.MetaSuppliersEventCost),
cgrEv, cgrArgs.ArgDispatcher, *cgrArgs.SupplierPaginator,
reqProcessor.Flags.HasKey(utils.MetaFD),
reqProcessor.Flags.ParamValue(utils.MetaSuppliersMaxCost),
)
rply := new(sessions.V1AuthorizeReply)
err = ra.connMgr.Call(ra.cgrCfg.RadiusAgentCfg().SessionSConns, nil, utils.SessionSv1AuthorizeEvent,
@@ -265,7 +266,9 @@ func (ra *RadiusAgent) processRequest(reqProcessor *config.RequestProcessor,
reqProcessor.Flags.HasKey(utils.MetaSuppliersIgnoreErrors),
reqProcessor.Flags.HasKey(utils.MetaSuppliersEventCost),
cgrEv, cgrArgs.ArgDispatcher, *cgrArgs.SupplierPaginator,
reqProcessor.Flags.HasKey(utils.MetaFD))
reqProcessor.Flags.HasKey(utils.MetaFD),
reqProcessor.Flags.ParamValue(utils.MetaSuppliersMaxCost),
)
rply := new(sessions.V1ProcessMessageReply)
err = ra.connMgr.Call(ra.cgrCfg.RadiusAgentCfg().SessionSConns, nil, utils.SessionSv1ProcessMessage, evArgs, rply)
if utils.ErrHasPrefix(err, utils.RalsErrorPrfx) {

View File

@@ -198,6 +198,7 @@ func (erS *ERService) processEvent(cgrEv *utils.CGREvent, rdrCfg *config.EventRe
rdrCfg.Flags.HasKey(utils.MetaSuppliersEventCost),
cgrEv, cgrArgs.ArgDispatcher, *cgrArgs.SupplierPaginator,
rdrCfg.Flags.HasKey(utils.MetaFD),
rdrCfg.Flags.ParamValue(utils.MetaSuppliersMaxCost),
)
rply := new(sessions.V1AuthorizeReply)
err = erS.connMgr.Call(erS.cfg.ERsCfg().SessionSConns, nil, utils.SessionSv1AuthorizeEvent,
@@ -254,7 +255,8 @@ func (erS *ERService) processEvent(cgrEv *utils.CGREvent, rdrCfg *config.EventRe
rdrCfg.Flags.HasKey(utils.MetaSuppliersIgnoreErrors),
rdrCfg.Flags.HasKey(utils.MetaSuppliersEventCost),
cgrEv, cgrArgs.ArgDispatcher, *cgrArgs.SupplierPaginator,
rdrCfg.Flags.HasKey(utils.MetaFD))
rdrCfg.Flags.HasKey(utils.MetaFD),
rdrCfg.Flags.ParamValue(utils.MetaSuppliersMaxCost))
rply := new(sessions.V1ProcessMessageReply) // need it so rpcclient can clone
err = erS.connMgr.Call(erS.cfg.ERsCfg().SessionSConns, nil, utils.SessionSv1ProcessMessage,
evArgs, rply)

View File

@@ -0,0 +1,528 @@
// +build integration
/*
Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments
Copyright (C) ITsysCOM GmbH
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package general_tests
import (
"net/rpc"
"path"
"reflect"
"testing"
"time"
"github.com/cgrates/cgrates/config"
"github.com/cgrates/cgrates/engine"
"github.com/cgrates/cgrates/sessions"
"github.com/cgrates/cgrates/utils"
)
var (
sesSupplierSCfgDir string
sesSupplierSCfgPath string
sesSupplierSCfg *config.CGRConfig
sesSupplierSRPC *rpc.Client
sesSupplierSTests = []func(t *testing.T){
testSesSupplierSItLoadConfig,
testSesSupplierSItResetDataDB,
testSesSupplierSItResetStorDb,
testSesSupplierSItStartEngine,
testSesSupplierSItRPCConn,
testSesSupplierSItLoadFromFolder,
testSesSupplierSAuthorizeEvent,
testSesSupplierSProcessMessage,
testSesSupplierSProcessEvent,
testSesSupplierSItStopCgrEngine,
}
)
func TestSesSupplierSItSessions(t *testing.T) {
switch *dbType {
case utils.MetaInternal:
sesSupplierSCfgDir = "tutinternal"
case utils.MetaMySQL:
sesSupplierSCfgDir = "tutmysql"
case utils.MetaMongo:
sesSupplierSCfgDir = "tutmongo"
case utils.MetaPostgres:
t.SkipNow()
default:
t.Fatal("Unknown Database type")
}
for _, stest := range sesSupplierSTests {
t.Run(sesSupplierSCfgDir, stest)
}
}
func testSesSupplierSItLoadConfig(t *testing.T) {
sesSupplierSCfgPath = path.Join(*dataDir, "conf", "samples", sesSupplierSCfgDir)
if sesSupplierSCfg, err = config.NewCGRConfigFromPath(sesSupplierSCfgPath); err != nil {
t.Error(err)
}
}
func testSesSupplierSItResetDataDB(t *testing.T) {
if err := engine.InitDataDb(sesSupplierSCfg); err != nil {
t.Fatal(err)
}
}
func testSesSupplierSItResetStorDb(t *testing.T) {
if err := engine.InitStorDb(sesSupplierSCfg); err != nil {
t.Fatal(err)
}
}
func testSesSupplierSItStartEngine(t *testing.T) {
if _, err := engine.StopStartEngine(sesSupplierSCfgPath, *waitRater); err != nil {
t.Fatal(err)
}
}
func testSesSupplierSItRPCConn(t *testing.T) {
var err error
sesSupplierSRPC, err = newRPCClient(sesSupplierSCfg.ListenCfg())
if err != nil {
t.Fatal(err)
}
}
func testSesSupplierSItLoadFromFolder(t *testing.T) {
var reply string
attrs := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "testit")}
if err := sesSupplierSRPC.Call(utils.APIerSv1LoadTariffPlanFromFolder, attrs, &reply); err != nil {
t.Error(err)
}
time.Sleep(100 * time.Millisecond)
}
func testSesSupplierSAuthorizeEvent(t *testing.T) {
cgrEv := &utils.CGREvent{
Tenant: "cgrates.org",
Event: map[string]interface{}{
utils.Source: "testV4CDRsProcessCDR",
utils.OriginID: "testV4CDRsProcessCDR",
utils.OriginHost: "192.168.1.1",
utils.RequestType: utils.META_POSTPAID,
utils.Category: utils.CALL,
utils.Account: "1003",
utils.Subject: "1003",
utils.Destination: "1002",
utils.AnswerTime: time.Date(2018, 8, 24, 16, 00, 26, 0, time.UTC),
utils.SetupTime: time.Date(2018, 8, 24, 16, 00, 00, 0, time.UTC),
utils.Usage: time.Minute,
},
}
args := sessions.NewV1AuthorizeArgs(false, []string{},
false, []string{}, false, []string{}, false, false,
true, false, false, cgrEv, &utils.ArgDispatcher{}, utils.Paginator{}, false, "")
var rply sessions.V1AuthorizeReply
if err := sesSupplierSRPC.Call(utils.SessionSv1AuthorizeEvent, args, &rply); err != nil {
t.Fatal(err)
}
expected := sessions.V1AuthorizeReply{
Suppliers: &engine.SortedSuppliers{
ProfileID: "SPL_LEASTCOST_1",
Sorting: "*lc",
Count: 3,
SortedSuppliers: []*engine.SortedSupplier{
{
SupplierID: "supplier3",
SupplierParameters: "",
SortingData: map[string]interface{}{
"Cost": 0.0102,
"RatingPlanID": "RP_SPECIAL_1002",
"Weight": 15.,
},
}, {
SupplierID: "supplier1",
SupplierParameters: "",
SortingData: map[string]interface{}{
"Cost": 0.0102,
"RatingPlanID": "RP_SPECIAL_1002",
"Weight": 10.,
},
}, {
SupplierID: "supplier2",
SupplierParameters: "",
SortingData: map[string]interface{}{
"Cost": 1.2,
"RatingPlanID": "RP_RETAIL1",
"Weight": 20.,
},
},
},
},
}
if !reflect.DeepEqual(rply, expected) {
t.Errorf("Expected: %s, received: %s", utils.ToJSON(expected), utils.ToJSON(rply))
}
args = sessions.NewV1AuthorizeArgs(false, []string{},
false, []string{}, false, []string{}, false, false,
true, false, false, cgrEv, &utils.ArgDispatcher{}, utils.Paginator{}, false, "2")
rply = sessions.V1AuthorizeReply{}
if err := sesSupplierSRPC.Call(utils.SessionSv1ProcessMessage,
args, &rply); err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(rply, expected) {
t.Errorf("Expected: %s, received: %s", utils.ToJSON(expected), utils.ToJSON(rply))
}
expected = sessions.V1AuthorizeReply{
Suppliers: &engine.SortedSuppliers{
ProfileID: "SPL_LEASTCOST_1",
Sorting: "*lc",
Count: 2,
SortedSuppliers: []*engine.SortedSupplier{
{
SupplierID: "supplier3",
SupplierParameters: "",
SortingData: map[string]interface{}{
"Cost": 0.0102,
"RatingPlanID": "RP_SPECIAL_1002",
"Weight": 15.,
},
}, {
SupplierID: "supplier1",
SupplierParameters: "",
SortingData: map[string]interface{}{
"Cost": 0.0102,
"RatingPlanID": "RP_SPECIAL_1002",
"Weight": 10.,
},
},
},
},
}
args = sessions.NewV1AuthorizeArgs(false, []string{},
false, []string{}, false, []string{}, false, false,
true, false, false, cgrEv, &utils.ArgDispatcher{}, utils.Paginator{}, false, "1")
rply = sessions.V1AuthorizeReply{}
if err := sesSupplierSRPC.Call(utils.SessionSv1ProcessMessage,
args, &rply); err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(rply, expected) {
t.Errorf("Expected: %s, received: %s", utils.ToJSON(expected), utils.ToJSON(rply))
}
args = sessions.NewV1AuthorizeArgs(false, []string{},
false, []string{}, false, []string{}, false, false,
true, false, true, cgrEv, &utils.ArgDispatcher{}, utils.Paginator{}, false, "")
rply = sessions.V1AuthorizeReply{}
if err := sesSupplierSRPC.Call(utils.SessionSv1ProcessMessage,
args, &rply); err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(rply, expected) {
t.Errorf("Expected: %s, received: %s", utils.ToJSON(expected), utils.ToJSON(rply))
}
}
func testSesSupplierSProcessMessage(t *testing.T) {
cgrEv := &utils.CGREvent{
Tenant: "cgrates.org",
Event: map[string]interface{}{
utils.Source: "testV4CDRsProcessCDR",
utils.OriginID: "testV4CDRsProcessCDR",
utils.OriginHost: "192.168.1.1",
utils.RequestType: utils.META_POSTPAID,
utils.Category: utils.CALL,
utils.Account: "1003",
utils.Subject: "1003",
utils.Destination: "1002",
utils.AnswerTime: time.Date(2018, 8, 24, 16, 00, 26, 0, time.UTC),
utils.SetupTime: time.Date(2018, 8, 24, 16, 00, 00, 0, time.UTC),
utils.Usage: time.Minute,
},
}
args := sessions.NewV1ProcessMessageArgs(false, []string{},
false, []string{}, false, []string{}, false, false,
true, false, false, cgrEv, &utils.ArgDispatcher{}, utils.Paginator{}, false, "")
var rply sessions.V1ProcessMessageReply
if err := sesSupplierSRPC.Call(utils.SessionSv1ProcessMessage,
args, &rply); err != nil {
t.Fatal(err)
}
expected := sessions.V1ProcessMessageReply{
Suppliers: &engine.SortedSuppliers{
ProfileID: "SPL_LEASTCOST_1",
Sorting: "*lc",
Count: 3,
SortedSuppliers: []*engine.SortedSupplier{
{
SupplierID: "supplier3",
SupplierParameters: "",
SortingData: map[string]interface{}{
"Cost": 0.0102,
"RatingPlanID": "RP_SPECIAL_1002",
"Weight": 15.,
},
}, {
SupplierID: "supplier1",
SupplierParameters: "",
SortingData: map[string]interface{}{
"Cost": 0.0102,
"RatingPlanID": "RP_SPECIAL_1002",
"Weight": 10.,
},
}, {
SupplierID: "supplier2",
SupplierParameters: "",
SortingData: map[string]interface{}{
"Cost": 1.2,
"RatingPlanID": "RP_RETAIL1",
"Weight": 20.,
},
},
},
},
}
if !reflect.DeepEqual(rply, expected) {
t.Errorf("Expected: %s, received: %s", utils.ToJSON(expected), utils.ToJSON(rply))
}
args = sessions.NewV1ProcessMessageArgs(false, []string{},
false, []string{}, false, []string{}, false, false,
true, false, false, cgrEv, &utils.ArgDispatcher{}, utils.Paginator{}, false, "2")
rply = sessions.V1ProcessMessageReply{}
if err := sesSupplierSRPC.Call(utils.SessionSv1ProcessMessage,
args, &rply); err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(rply, expected) {
t.Errorf("Expected: %s, received: %s", utils.ToJSON(expected), utils.ToJSON(rply))
}
expected = sessions.V1ProcessMessageReply{
Suppliers: &engine.SortedSuppliers{
ProfileID: "SPL_LEASTCOST_1",
Sorting: "*lc",
Count: 2,
SortedSuppliers: []*engine.SortedSupplier{
{
SupplierID: "supplier3",
SupplierParameters: "",
SortingData: map[string]interface{}{
"Cost": 0.0102,
"RatingPlanID": "RP_SPECIAL_1002",
"Weight": 15.,
},
}, {
SupplierID: "supplier1",
SupplierParameters: "",
SortingData: map[string]interface{}{
"Cost": 0.0102,
"RatingPlanID": "RP_SPECIAL_1002",
"Weight": 10.,
},
},
},
},
}
args = sessions.NewV1ProcessMessageArgs(false, []string{},
false, []string{}, false, []string{}, false, false,
true, false, false, cgrEv, &utils.ArgDispatcher{}, utils.Paginator{}, false, "1")
rply = sessions.V1ProcessMessageReply{}
if err := sesSupplierSRPC.Call(utils.SessionSv1ProcessMessage,
args, &rply); err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(rply, expected) {
t.Errorf("Expected: %s, received: %s", utils.ToJSON(expected), utils.ToJSON(rply))
}
args = sessions.NewV1ProcessMessageArgs(false, []string{},
false, []string{}, false, []string{}, false, false,
true, false, true, cgrEv, &utils.ArgDispatcher{}, utils.Paginator{}, false, "")
rply = sessions.V1ProcessMessageReply{}
if err := sesSupplierSRPC.Call(utils.SessionSv1ProcessMessage,
args, &rply); err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(rply, expected) {
t.Errorf("Expected: %s, received: %s", utils.ToJSON(expected), utils.ToJSON(rply))
}
}
func testSesSupplierSProcessEvent(t *testing.T) {
cgrEv := &utils.CGREvent{
Tenant: "cgrates.org",
Event: map[string]interface{}{
utils.Source: "testV4CDRsProcessCDR",
utils.OriginID: "testV4CDRsProcessCDR",
utils.OriginHost: "192.168.1.1",
utils.RequestType: utils.META_POSTPAID,
utils.Category: utils.CALL,
utils.Account: "1003",
utils.Subject: "1003",
utils.Destination: "1002",
utils.AnswerTime: time.Date(2018, 8, 24, 16, 00, 26, 0, time.UTC),
utils.SetupTime: time.Date(2018, 8, 24, 16, 00, 00, 0, time.UTC),
utils.Usage: time.Minute,
},
}
args := sessions.V1ProcessEventArgs{
Flags: []string{"*suppliers"},
CGREvent: cgrEv,
Paginator: utils.Paginator{},
}
var rply sessions.V1ProcessEventReply
if err := sesSupplierSRPC.Call(utils.SessionSv1ProcessEvent, args, &rply); err != nil {
t.Fatal(err)
}
expected := sessions.V1ProcessEventReply{
Suppliers: &engine.SortedSuppliers{
ProfileID: "SPL_LEASTCOST_1",
Sorting: "*lc",
Count: 3,
SortedSuppliers: []*engine.SortedSupplier{
{
SupplierID: "supplier3",
SupplierParameters: "",
SortingData: map[string]interface{}{
"Cost": 0.0102,
"RatingPlanID": "RP_SPECIAL_1002",
"Weight": 15.,
},
}, {
SupplierID: "supplier1",
SupplierParameters: "",
SortingData: map[string]interface{}{
"Cost": 0.0102,
"RatingPlanID": "RP_SPECIAL_1002",
"Weight": 10.,
},
}, {
SupplierID: "supplier2",
SupplierParameters: "",
SortingData: map[string]interface{}{
"Cost": 1.2,
"RatingPlanID": "RP_RETAIL1",
"Weight": 20.,
},
},
},
},
}
if !reflect.DeepEqual(rply, expected) {
t.Errorf("Expected: %s, received: %s", utils.ToJSON(expected), utils.ToJSON(rply))
}
args = sessions.V1ProcessEventArgs{
Flags: []string{"*suppliers", "*suppliers_maxcost:2"},
CGREvent: cgrEv,
Paginator: utils.Paginator{},
}
rply = sessions.V1ProcessEventReply{}
if err := sesSupplierSRPC.Call(utils.SessionSv1ProcessEvent,
args, &rply); err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(rply, expected) {
t.Errorf("Expected: %s, received: %s", utils.ToJSON(expected), utils.ToJSON(rply))
}
expected = sessions.V1ProcessEventReply{
Suppliers: &engine.SortedSuppliers{
ProfileID: "SPL_LEASTCOST_1",
Sorting: "*lc",
Count: 2,
SortedSuppliers: []*engine.SortedSupplier{
{
SupplierID: "supplier3",
SupplierParameters: "",
SortingData: map[string]interface{}{
"Cost": 0.0102,
"RatingPlanID": "RP_SPECIAL_1002",
"Weight": 15.,
},
}, {
SupplierID: "supplier1",
SupplierParameters: "",
SortingData: map[string]interface{}{
"Cost": 0.0102,
"RatingPlanID": "RP_SPECIAL_1002",
"Weight": 10.,
},
},
},
},
}
args = sessions.V1ProcessEventArgs{
Flags: []string{"*suppliers", "*suppliers_maxcost:1"},
CGREvent: cgrEv,
Paginator: utils.Paginator{},
}
rply = sessions.V1ProcessEventReply{}
if err := sesSupplierSRPC.Call(utils.SessionSv1ProcessEvent,
args, &rply); err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(rply, expected) {
t.Errorf("Expected: %s, received: %s", utils.ToJSON(expected), utils.ToJSON(rply))
}
args = sessions.V1ProcessEventArgs{
Flags: []string{"*suppliers:*event_cost"},
CGREvent: cgrEv,
Paginator: utils.Paginator{},
}
rply = sessions.V1ProcessEventReply{}
if err := sesSupplierSRPC.Call(utils.SessionSv1ProcessEvent,
args, &rply); err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(rply, expected) {
t.Errorf("Expected: %s, received: %s", utils.ToJSON(expected), utils.ToJSON(rply))
}
}
func testSesSupplierSItStopCgrEngine(t *testing.T) {
if err := engine.KillEngine(100); err != nil {
t.Error(err)
}
}

View File

@@ -9,6 +9,7 @@ cgrates (0.10.3~dev) UNRELEASED; urgency=medium
* [SessionS] Added extra condition to determine if the increment is considered the roundIncrement
* [SessionS] Cloned the charging interval added on EventCost merge
* [FilterS] Optimized the automated index fields matching
* [AgentS] Added *routes_maxcost flag
-- DanB <danb@cgrates.org> Thu, 08 Oct 2020 16:23:58 +0300

View File

@@ -1703,7 +1703,7 @@ func NewV1AuthorizeArgs(attrs bool, attributeIDs []string,
thrslds bool, thresholdIDs []string, statQueues bool, statIDs []string,
res, maxUsage, suppls, supplsIgnoreErrs, supplsEventCost bool,
cgrEv *utils.CGREvent, argDisp *utils.ArgDispatcher,
supplierPaginator utils.Paginator, forceDuration bool) (args *V1AuthorizeArgs) {
supplierPaginator utils.Paginator, forceDuration bool, supMaxCost string) (args *V1AuthorizeArgs) {
args = &V1AuthorizeArgs{
GetAttributes: attrs,
AuthorizeResources: res,
@@ -1716,7 +1716,9 @@ func NewV1AuthorizeArgs(attrs bool, attributeIDs []string,
ForceDuration: forceDuration,
}
if supplsEventCost {
args.SuppliersMaxCost = utils.MetaSuppliersEventCost
args.SuppliersMaxCost = utils.MetaEventCost
} else {
args.SuppliersMaxCost = supMaxCost
}
args.ArgDispatcher = argDisp
args.Paginator = supplierPaginator
@@ -1769,6 +1771,8 @@ func (args *V1AuthorizeArgs) ParseFlags(flags string) {
args.SuppliersIgnoreErrors = true
case subsystem == utils.MetaSuppliersEventCost:
args.SuppliersMaxCost = utils.MetaEventCost
case strings.HasPrefix(subsystem, utils.MetaSuppliersMaxCost):
args.SuppliersMaxCost = strings.TrimPrefix(subsystem, utils.MetaSuppliersMaxCost+utils.InInFieldSep)
case strings.HasPrefix(subsystem, utils.MetaAttributes):
args.GetAttributes = true
args.AttributeIDs = getFlagIDs(subsystem)
@@ -2709,7 +2713,7 @@ func NewV1ProcessMessageArgs(attrs bool, attributeIDs []string,
thds bool, thresholdIDs []string, stats bool, statIDs []string, resrc, acnts,
suppls, supplsIgnoreErrs, supplsEventCost bool,
cgrEv *utils.CGREvent, argDisp *utils.ArgDispatcher,
supplierPaginator utils.Paginator, forceDuration bool) (args *V1ProcessMessageArgs) {
supplierPaginator utils.Paginator, forceDuration bool, supMaxCost string) (args *V1ProcessMessageArgs) {
args = &V1ProcessMessageArgs{
AllocateResources: resrc,
Debit: acnts,
@@ -2723,7 +2727,9 @@ func NewV1ProcessMessageArgs(attrs bool, attributeIDs []string,
ForceDuration: forceDuration,
}
if supplsEventCost {
args.SuppliersMaxCost = utils.MetaSuppliersEventCost
args.SuppliersMaxCost = utils.MetaEventCost
} else {
args.SuppliersMaxCost = supMaxCost
}
args.Paginator = supplierPaginator
if len(attributeIDs) != 0 {
@@ -2774,6 +2780,8 @@ func (args *V1ProcessMessageArgs) ParseFlags(flags string) {
args.SuppliersIgnoreErrors = true
case subsystem == utils.MetaSuppliersEventCost:
args.SuppliersMaxCost = utils.MetaEventCost
case strings.HasPrefix(subsystem, utils.MetaSuppliersMaxCost):
args.SuppliersMaxCost = strings.TrimPrefix(subsystem, utils.MetaSuppliersMaxCost+utils.InInFieldSep)
case strings.Index(subsystem, utils.MetaAttributes) != -1:
args.GetAttributes = true
args.AttributeIDs = getFlagIDs(subsystem)
@@ -3228,8 +3236,8 @@ func (sS *SessionS) BiRPCv1ProcessEvent(clnt rpcclient.ClientConnector,
// get suppliers if required
if argsFlagsWithParams.HasKey(utils.MetaSuppliers) {
var ignoreErrors bool
var maxCost string
// check in case we have options for suppliers
maxCost := argsFlagsWithParams.ParamValue(utils.MetaSuppliersMaxCost)
if splOpts := argsFlagsWithParams.ParamsSlice(utils.MetaSuppliers); len(splOpts) != 0 {
//check for subflags and convert them into utils.FlagsWithParams
splsFlagsWithParams, err := utils.FlagsWithParamsFromSlice(splOpts)
@@ -3240,7 +3248,7 @@ func (sS *SessionS) BiRPCv1ProcessEvent(clnt rpcclient.ClientConnector,
ignoreErrors = true
}
if splsFlagsWithParams.HasKey(utils.MetaEventCost) {
maxCost = utils.MetaSuppliersEventCost
maxCost = utils.MetaEventCost
}
}
splsReply, err := sS.getSuppliers(args.CGREvent.Clone(), args.ArgDispatcher,

View File

@@ -827,7 +827,7 @@ func TestSessionSNewV1AuthorizeArgs(t *testing.T) {
GetAttributes: true,
CGREvent: cgrEv,
}
rply := NewV1AuthorizeArgs(true, nil, false, nil, false, nil, true, false, false, false, false, cgrEv, nil, utils.Paginator{}, false)
rply := NewV1AuthorizeArgs(true, nil, false, nil, false, nil, true, false, false, false, false, cgrEv, nil, utils.Paginator{}, false, "")
if !reflect.DeepEqual(expected, rply) {
t.Errorf("Expecting %+v, received: %+v", expected, rply)
}
@@ -839,11 +839,11 @@ func TestSessionSNewV1AuthorizeArgs(t *testing.T) {
ProcessStats: true,
GetSuppliers: false,
SuppliersIgnoreErrors: true,
SuppliersMaxCost: utils.MetaSuppliersEventCost,
SuppliersMaxCost: utils.MetaEventCost,
CGREvent: cgrEv,
ForceDuration: true,
}
rply = NewV1AuthorizeArgs(true, nil, false, nil, true, nil, false, true, false, true, true, cgrEv, nil, utils.Paginator{}, true)
rply = NewV1AuthorizeArgs(true, nil, false, nil, true, nil, false, true, false, true, true, cgrEv, nil, utils.Paginator{}, true, "")
if !reflect.DeepEqual(expected, rply) {
t.Errorf("Expecting %+v,\n received: %+v", expected, rply)
}
@@ -859,14 +859,34 @@ func TestSessionSNewV1AuthorizeArgs(t *testing.T) {
ProcessStats: true,
GetSuppliers: false,
SuppliersIgnoreErrors: true,
SuppliersMaxCost: utils.MetaSuppliersEventCost,
SuppliersMaxCost: utils.MetaEventCost,
CGREvent: cgrEv,
AttributeIDs: []string{"ATTR1", "ATTR2"},
ThresholdIDs: []string{"ID1", "ID2"},
StatIDs: []string{"test3", "test4"},
}
rply = NewV1AuthorizeArgs(true, attributeIDs, false, thresholdIDs, true, statIDs,
false, true, false, true, true, cgrEv, nil, utils.Paginator{}, false)
false, true, false, true, true, cgrEv, nil, utils.Paginator{}, false, "")
if !reflect.DeepEqual(expected, rply) {
t.Errorf("Expecting %+v,\n received: %+v", expected, rply)
}
expected = &V1AuthorizeArgs{
GetAttributes: true,
AuthorizeResources: false,
GetMaxUsage: true,
ProcessThresholds: false,
ProcessStats: true,
GetSuppliers: true,
SuppliersIgnoreErrors: true,
SuppliersMaxCost: "100",
CGREvent: cgrEv,
AttributeIDs: []string{"ATTR1", "ATTR2"},
ThresholdIDs: []string{"ID1", "ID2"},
StatIDs: []string{"test3", "test4"},
}
rply = NewV1AuthorizeArgs(true, attributeIDs, false, thresholdIDs, true, statIDs,
false, true, true, true, false, cgrEv, nil, utils.Paginator{}, false, "100")
if !reflect.DeepEqual(expected, rply) {
t.Errorf("Expecting %+v,\n received: %+v", expected, rply)
}
@@ -928,6 +948,30 @@ func TestV1AuthorizeArgsParseFlags(t *testing.T) {
if !reflect.DeepEqual(eOut, v1authArgs) {
t.Errorf("Expecting %+v,\n received: %+v\n", utils.ToJSON(eOut), utils.ToJSON(v1authArgs))
}
cgrArgs = v1authArgs.CGREvent.ExtractArgs(true, true)
eOut = &V1AuthorizeArgs{
GetMaxUsage: true,
AuthorizeResources: true,
GetSuppliers: true,
SuppliersIgnoreErrors: true,
SuppliersMaxCost: "100",
GetAttributes: true,
AttributeIDs: []string{"Attr1", "Attr2"},
ProcessThresholds: true,
ThresholdIDs: []string{"tr1", "tr2", "tr3"},
ProcessStats: true,
StatIDs: []string{"st1", "st2", "st3"},
ArgDispatcher: cgrArgs.ArgDispatcher,
Paginator: *cgrArgs.SupplierPaginator,
ForceDuration: true,
}
strArg = "*accounts,*fd,*resources,,*dispatchers,*suppliers,*suppliers_ignore_errors,*suppliers_maxcost:100,*attributes:Attr1;Attr2,*thresholds:tr1;tr2;tr3,*stats:st1;st2;st3"
v1authArgs.ParseFlags(strArg)
if !reflect.DeepEqual(eOut, v1authArgs) {
t.Errorf("Expecting %+v,\n received: %+v\n", utils.ToJSON(eOut), utils.ToJSON(v1authArgs))
}
}
func TestSessionSNewV1UpdateSessionArgs(t *testing.T) {
@@ -1026,7 +1070,7 @@ func TestSessionSNewV1ProcessMessageArgs(t *testing.T) {
GetSuppliers: true,
}
rply := NewV1ProcessMessageArgs(true, nil, false, nil, false, nil,
true, true, true, false, false, cgrEv, nil, utils.Paginator{}, false)
true, true, true, false, false, cgrEv, nil, utils.Paginator{}, false, "")
if !reflect.DeepEqual(expected, rply) {
t.Errorf("Expecting %+v, received: %+v", expected, rply)
}
@@ -1035,11 +1079,11 @@ func TestSessionSNewV1ProcessMessageArgs(t *testing.T) {
GetAttributes: true,
CGREvent: cgrEv,
GetSuppliers: true,
SuppliersMaxCost: utils.MetaSuppliersEventCost,
SuppliersMaxCost: utils.MetaEventCost,
SuppliersIgnoreErrors: true,
}
rply = NewV1ProcessMessageArgs(true, nil, false, nil, false, nil, true,
false, true, true, true, cgrEv, nil, utils.Paginator{}, false)
false, true, true, true, cgrEv, nil, utils.Paginator{}, false, "")
if !reflect.DeepEqual(expected, rply) {
t.Errorf("Expecting %+v, received: %+v", expected, rply)
}
@@ -1053,18 +1097,34 @@ func TestSessionSNewV1ProcessMessageArgs(t *testing.T) {
GetAttributes: true,
CGREvent: cgrEv,
GetSuppliers: true,
SuppliersMaxCost: utils.MetaSuppliersEventCost,
SuppliersMaxCost: utils.MetaEventCost,
SuppliersIgnoreErrors: true,
AttributeIDs: []string{"ATTR1", "ATTR2"},
ThresholdIDs: []string{"ID1", "ID2"},
StatIDs: []string{"test3", "test4"},
}
rply = NewV1ProcessMessageArgs(true, attributeIDs, false, thresholdIDs, false, statIDs, true,
false, true, true, true, cgrEv, nil, utils.Paginator{}, false)
false, true, true, true, cgrEv, nil, utils.Paginator{}, false, "")
if !reflect.DeepEqual(expected, rply) {
t.Errorf("Expecting %+v, received: %+v", expected, rply)
}
expected = &V1ProcessMessageArgs{
AllocateResources: true,
GetAttributes: true,
CGREvent: cgrEv,
GetSuppliers: true,
SuppliersMaxCost: "100",
SuppliersIgnoreErrors: true,
AttributeIDs: []string{"ATTR1", "ATTR2"},
ThresholdIDs: []string{"ID1", "ID2"},
StatIDs: []string{"test3", "test4"},
}
rply = NewV1ProcessMessageArgs(true, attributeIDs, false, thresholdIDs, false, statIDs, true,
false, true, true, false, cgrEv, nil, utils.Paginator{}, false, "100")
if !reflect.DeepEqual(expected, rply) {
t.Errorf("Expecting %+v, received: %+v", expected, rply)
}
}
func TestSessionSNewV1InitSessionArgs(t *testing.T) {
@@ -1493,7 +1553,7 @@ func TestSessionSNewV1AuthorizeArgsWithArgDispatcher(t *testing.T) {
}
cgrArgs := cgrEv.ExtractArgs(true, true)
rply := NewV1AuthorizeArgs(true, nil, false, nil, false, nil, true, false, false, false,
false, cgrEv, cgrArgs.ArgDispatcher, *cgrArgs.SupplierPaginator, false)
false, cgrEv, cgrArgs.ArgDispatcher, *cgrArgs.SupplierPaginator, false, "")
if !reflect.DeepEqual(expected, rply) {
t.Errorf("Expecting %+v, received: %+v", utils.ToJSON(expected), utils.ToJSON(rply))
}
@@ -1505,7 +1565,7 @@ func TestSessionSNewV1AuthorizeArgsWithArgDispatcher(t *testing.T) {
ProcessStats: true,
GetSuppliers: false,
SuppliersIgnoreErrors: true,
SuppliersMaxCost: utils.MetaSuppliersEventCost,
SuppliersMaxCost: utils.MetaEventCost,
CGREvent: cgrEv,
ArgDispatcher: &utils.ArgDispatcher{
APIKey: utils.StringPointer("testkey"),
@@ -1513,7 +1573,7 @@ func TestSessionSNewV1AuthorizeArgsWithArgDispatcher(t *testing.T) {
},
}
rply = NewV1AuthorizeArgs(true, nil, false, nil, true, nil, false,
true, false, true, true, cgrEv, cgrArgs.ArgDispatcher, *cgrArgs.SupplierPaginator, false)
true, false, true, true, cgrEv, cgrArgs.ArgDispatcher, *cgrArgs.SupplierPaginator, false, "")
if !reflect.DeepEqual(expected, rply) {
t.Errorf("Expecting %+v, received: %+v", utils.ToJSON(expected), utils.ToJSON(rply))
}
@@ -1539,7 +1599,7 @@ func TestSessionSNewV1AuthorizeArgsWithArgDispatcher2(t *testing.T) {
}
cgrArgs := cgrEv.ExtractArgs(true, true)
rply := NewV1AuthorizeArgs(true, nil, false, nil, false, nil, true, false,
false, false, false, cgrEv, cgrArgs.ArgDispatcher, *cgrArgs.SupplierPaginator, false)
false, false, false, cgrEv, cgrArgs.ArgDispatcher, *cgrArgs.SupplierPaginator, false, "")
if !reflect.DeepEqual(expected, rply) {
t.Errorf("Expecting %+v, received: %+v", utils.ToJSON(expected), utils.ToJSON(rply))
}
@@ -1551,14 +1611,14 @@ func TestSessionSNewV1AuthorizeArgsWithArgDispatcher2(t *testing.T) {
ProcessStats: true,
GetSuppliers: false,
SuppliersIgnoreErrors: true,
SuppliersMaxCost: utils.MetaSuppliersEventCost,
SuppliersMaxCost: utils.MetaEventCost,
CGREvent: cgrEv,
ArgDispatcher: &utils.ArgDispatcher{
RouteID: utils.StringPointer("testrouteid"),
},
}
rply = NewV1AuthorizeArgs(true, nil, false, nil, true, nil, false,
true, false, true, true, cgrEv, cgrArgs.ArgDispatcher, *cgrArgs.SupplierPaginator, false)
true, false, true, true, cgrEv, cgrArgs.ArgDispatcher, *cgrArgs.SupplierPaginator, false, "")
if !reflect.DeepEqual(expected, rply) {
t.Errorf("Expecting %+v, received: %+v", utils.ToJSON(expected), utils.ToJSON(rply))
}
@@ -1899,6 +1959,28 @@ func TestV1ProcessMessageArgsParseFlags(t *testing.T) {
t.Errorf("Expecting %+v,\n received: %+v\n", utils.ToJSON(eOut), utils.ToJSON(v1ProcessMsgArgs))
}
cgrArgs = v1ProcessMsgArgs.CGREvent.ExtractArgs(true, true)
eOut = &V1ProcessMessageArgs{
Debit: true,
AllocateResources: true,
GetSuppliers: true,
SuppliersIgnoreErrors: true,
SuppliersMaxCost: "100",
GetAttributes: true,
AttributeIDs: []string{"Attr1", "Attr2"},
ProcessThresholds: true,
ThresholdIDs: []string{"tr1", "tr2", "tr3"},
ProcessStats: true,
StatIDs: []string{"st1", "st2", "st3"},
ArgDispatcher: cgrArgs.ArgDispatcher,
}
strArg = "*accounts,*resources,*dispatchers,*suppliers,*suppliers_ignore_errors,*suppliers_maxcost:100,*attributes:Attr1;Attr2,*thresholds:tr1;tr2;tr3,*stats:st1;st2;st3"
v1ProcessMsgArgs.ParseFlags(strArg)
if !reflect.DeepEqual(eOut, v1ProcessMsgArgs) {
t.Errorf("Expecting %+v,\n received: %+v\n", utils.ToJSON(eOut), utils.ToJSON(v1ProcessMsgArgs))
}
}
func TestSessionSgetSession(t *testing.T) {

View File

@@ -534,6 +534,8 @@ const (
MetaRound = "*round"
Pong = "Pong"
MetaEventCost = "*event_cost"
MetaSuppliersMaxCost = "*suppliers_maxcost"
MetaMaxCost = "*maxcost"
MetaSuppliersEventCost = "*suppliers_event_cost"
MetaSuppliersIgnoreErrors = "*suppliers_ignore_errors"
Freeswitch = "freeswitch"

View File

@@ -263,6 +263,14 @@ func (fWp FlagsWithParams) ParamsSlice(subs string) (ps []string) {
return
}
// ParamValue returns the value of the flag
func (fWp FlagsWithParams) ParamValue(subs string) (ps string) {
for _, ps = range fWp[subs] {
return
}
return
}
// SliceFlags converts from FlagsWithParams back to []string
func (fWp FlagsWithParams) SliceFlags() (sls []string) {
for key := range fWp {

View File

@@ -313,3 +313,21 @@ func TestFlagsWithParamsGetBool(t *testing.T) {
t.Errorf("Expecting: true, received: %+v", ToJSON(rcv))
}
}
func TestFlagsWithParamsValue(t *testing.T) {
flagsWithParams := &FlagsWithParams{
"test": []string{"string2"},
"empty": []string{},
}
key := "notpresent"
if rcv := flagsWithParams.ParamValue(key); rcv != EmptyString {
t.Errorf("Expecting: %q, received: %+v", EmptyString, rcv)
}
key = "empty"
if rcv := flagsWithParams.ParamValue(key); rcv != EmptyString {
t.Errorf("Expecting: %q, received: %+v", EmptyString, rcv)
}
key = "test"
if rcv := flagsWithParams.ParamValue(key); rcv != "string2" {
t.Errorf("Expecting: string2, received: %+v", rcv)
}
}