mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
SessionSv1.AuthorizeEvent with integration tests
This commit is contained in:
@@ -137,7 +137,7 @@ func (sm *FSSessionManager) onChannelPark(fsev FSEvent, connId string) {
|
||||
}
|
||||
authArgs := fsev.V1AuthorizeArgs()
|
||||
var authReply sessionmanager.V1AuthorizeReply
|
||||
if err := sm.smg.Call(utils.SMGv1AuthorizeEvent, authArgs, &authReply); err != nil {
|
||||
if err := sm.smg.Call(utils.SessionSv1AuthorizeEvent, authArgs, &authReply); err != nil {
|
||||
utils.Logger.Err(
|
||||
fmt.Sprintf("<SM-FreeSWITCH> Could not authorize event %s, error: %s",
|
||||
fsev.GetUUID(), err.Error()))
|
||||
@@ -146,19 +146,19 @@ func (sm *FSSessionManager) onChannelPark(fsev FSEvent, connId string) {
|
||||
return
|
||||
}
|
||||
if authArgs.GetMaxUsage {
|
||||
if authReply.MaxUsage != -1 { // For calls different than unlimited, set limits
|
||||
if authReply.MaxUsage == 0 {
|
||||
if *authReply.MaxUsage != -1 { // For calls different than unlimited, set limits
|
||||
if *authReply.MaxUsage == 0 {
|
||||
sm.unparkCall(fsev.GetUUID(), connId,
|
||||
fsev.GetCallDestNr(utils.META_DEFAULT), utils.ErrInsufficientCredit.Error())
|
||||
return
|
||||
}
|
||||
sm.setMaxCallDuration(fsev.GetUUID(), connId,
|
||||
authReply.MaxUsage, fsev.GetCallDestNr(utils.META_DEFAULT))
|
||||
*authReply.MaxUsage, fsev.GetCallDestNr(utils.META_DEFAULT))
|
||||
}
|
||||
}
|
||||
if authArgs.CheckResources {
|
||||
if authArgs.AuthorizeResources {
|
||||
if _, err := sm.conns[connId].SendApiCmd(fmt.Sprintf("uuid_setvar %s %s %b\n\n",
|
||||
fsev.GetUUID(), CGRResourcesAllowed, authReply.ResourcesAllowed)); err != nil {
|
||||
fsev.GetUUID(), CGRResourcesAllowed, authReply.ResourcesAuthorized)); err != nil {
|
||||
utils.Logger.Info(
|
||||
fmt.Sprintf("<%s> error %s setting channel variabile: %s",
|
||||
utils.SMFreeSWITCH, err.Error(), CGRResourcesAllowed))
|
||||
@@ -206,7 +206,7 @@ func (sm *FSSessionManager) onChannelAnswer(fsev FSEvent, connId string) {
|
||||
}
|
||||
initSessionArgs := fsev.V1InitSessionArgs()
|
||||
var initReply sessionmanager.V1InitSessionReply
|
||||
if err := sm.smg.Call(utils.SMGv1InitiateSession,
|
||||
if err := sm.smg.Call(utils.SessionSv1InitiateSession,
|
||||
initSessionArgs, &initReply); err != nil {
|
||||
utils.Logger.Err(
|
||||
fmt.Sprintf("<SM-FreeSWITCH> Could not answer session with event %s, error: %s",
|
||||
@@ -227,7 +227,7 @@ func (sm *FSSessionManager) onChannelHangupComplete(fsev FSEvent, connId string)
|
||||
return
|
||||
}
|
||||
var reply string
|
||||
if err := sm.smg.Call(utils.SMGv1TerminateSession,
|
||||
if err := sm.smg.Call(utils.SessionSv1TerminateSession,
|
||||
fsev.V1TerminateSessionArgs(), &reply); err != nil {
|
||||
utils.Logger.Err(
|
||||
fmt.Sprintf("<SM-FreeSWITCH> Could not terminate session with event %s, error: %s",
|
||||
@@ -236,7 +236,7 @@ func (sm *FSSessionManager) onChannelHangupComplete(fsev FSEvent, connId string)
|
||||
}
|
||||
if sm.cfg.CreateCdr {
|
||||
cdr := fsev.AsCDR(sm.timezone)
|
||||
if err := sm.smg.Call(utils.SMGv1ProcessCDR, cdr, &reply); err != nil {
|
||||
if err := sm.smg.Call(utils.SessionSv1ProcessCDR, cdr, &reply); err != nil {
|
||||
utils.Logger.Err(fmt.Sprintf("<SM-FreeSWITCH> Failed processing CDR, cgrid: %s, accid: %s, error: <%s>",
|
||||
cdr.CGRID, cdr.OriginID, err.Error()))
|
||||
}
|
||||
|
||||
@@ -445,7 +445,7 @@ func (fsev FSEvent) V1AuthorizeArgs() (args *sessionmanager.V1AuthorizeArgs) {
|
||||
args.GetMaxUsage = false
|
||||
}
|
||||
if strings.Index(subsystems, SubSResourceS) != -1 {
|
||||
args.CheckResources = true
|
||||
args.AuthorizeResources = true
|
||||
}
|
||||
if strings.Index(subsystems, SubSSupplierS) != -1 {
|
||||
args.GetSuppliers = true
|
||||
|
||||
@@ -27,7 +27,7 @@ func NewSessionSv1(sm *sessionmanager.SMGeneric) *SessionSv1 {
|
||||
return &SessionSv1{SMG: sm}
|
||||
}
|
||||
|
||||
// Exports RPC from SessionSv1
|
||||
// SessionSv1 exports RPC from SessionSv1
|
||||
type SessionSv1 struct {
|
||||
SMG *sessionmanager.SMGeneric
|
||||
}
|
||||
@@ -35,32 +35,34 @@ type SessionSv1 struct {
|
||||
// Publishes BiJSONRPC methods exported by SessionSv1
|
||||
func (ssv1 *SessionSv1) Handlers() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"SessionSv1.InitiateSession": ssv1.SMG.BiRPCv1InitiateSession,
|
||||
"SessionSv1.UpdateSession": ssv1.SMG.BiRPCv1UpdateSession,
|
||||
"SessionSv1.TerminateSession": ssv1.SMG.BiRPCv1TerminateSession,
|
||||
"SessionSv1.ProcessCDR": ssv1.SMG.BiRPCv1ProcessCDR,
|
||||
utils.SessionSv1AuthorizeEvent: ssv1.SMG.BiRPCv1AuthorizeEvent,
|
||||
utils.SessionSv1InitiateSession: ssv1.SMG.BiRPCv1InitiateSession,
|
||||
utils.SessionSv1UpdateSession: ssv1.SMG.BiRPCv1UpdateSession,
|
||||
utils.SessionSv1TerminateSession: ssv1.SMG.BiRPCv1TerminateSession,
|
||||
utils.SessionSv1ProcessCDR: ssv1.SMG.BiRPCv1ProcessCDR,
|
||||
}
|
||||
}
|
||||
|
||||
// Called on session start, returns the maximum number of seconds the session can last
|
||||
func (ssv1 *SessionSv1) AuthorizeEvent(args *sessionmanager.V1AuthorizeArgs,
|
||||
rply *sessionmanager.V1AuthorizeReply) error {
|
||||
return ssv1.SMG.BiRPCv1AuthorizeEvent(nil, args, rply)
|
||||
}
|
||||
|
||||
func (ssv1 *SessionSv1) InitiateSession(args *sessionmanager.V1InitSessionArgs,
|
||||
rply *sessionmanager.V1InitSessionReply) error {
|
||||
return ssv1.SMG.BiRPCv1InitiateSession(nil, args, rply)
|
||||
}
|
||||
|
||||
// Interim updates, returns remaining duration from the rater
|
||||
func (ssv1 *SessionSv1) UpdateSession(args *sessionmanager.V1UpdateSessionArgs,
|
||||
rply *sessionmanager.V1UpdateSessionReply) error {
|
||||
return ssv1.SMG.BiRPCv1UpdateSession(nil, args, rply)
|
||||
}
|
||||
|
||||
// Called on session end, should stop debit loop
|
||||
func (ssv1 *SessionSv1) TerminateSession(args *sessionmanager.V1TerminateSessionArgs,
|
||||
rply *string) error {
|
||||
return ssv1.SMG.BiRPCv1TerminateSession(nil, args, rply)
|
||||
}
|
||||
|
||||
// Called on session end, should stop debit loop
|
||||
func (ssv1 *SessionSv1) ProcessCDR(cgrEv utils.CGREvent, rply *string) error {
|
||||
return ssv1.SMG.BiRPCv1ProcessCDR(nil, cgrEv, rply)
|
||||
}
|
||||
|
||||
196
apier/v1/sessionsv1_it_test.go
Normal file
196
apier/v1/sessionsv1_it_test.go
Normal file
@@ -0,0 +1,196 @@
|
||||
// +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 v1
|
||||
|
||||
import (
|
||||
"net/rpc"
|
||||
"net/rpc/jsonrpc"
|
||||
"path"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cenk/rpc2"
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/sessionmanager"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
var (
|
||||
sSv1CfgPath string
|
||||
sSv1Cfg *config.CGRConfig
|
||||
sSv1BiRpc *rpc2.Client
|
||||
sSApierRpc *rpc.Client
|
||||
disconnectEvChan = make(chan *utils.AttrDisconnectSession)
|
||||
)
|
||||
|
||||
func handleDisconnectSession(clnt *rpc2.Client,
|
||||
args *utils.AttrDisconnectSession, reply *string) error {
|
||||
disconnectEvChan <- args
|
||||
*reply = utils.OK
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestSSv1ItInitCfg(t *testing.T) {
|
||||
sSv1CfgPath = path.Join(*dataDir, "conf", "samples", "sessions")
|
||||
// Init config first
|
||||
sSv1Cfg, err = config.NewCGRConfigFromFolder(sSv1CfgPath)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
sSv1Cfg.DataFolderPath = *dataDir // Share DataFolderPath through config towards StoreDb for Flush()
|
||||
config.SetCgrConfig(sSv1Cfg)
|
||||
}
|
||||
|
||||
func TestSSv1ItResetDataDb(t *testing.T) {
|
||||
if err := engine.InitDataDb(sSv1Cfg); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSSv1ItResetStorDb(t *testing.T) {
|
||||
if err := engine.InitStorDb(sSv1Cfg); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSSv1ItStartEngine(t *testing.T) {
|
||||
if _, err := engine.StopStartEngine(sSv1CfgPath, 100); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
|
||||
func TestSSv1ItRpcConn(t *testing.T) {
|
||||
dummyClnt, err := utils.NewBiJSONrpcClient(sSv1Cfg.SessionSCfg().ListenBijson,
|
||||
nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
clntHandlers := map[string]interface{}{
|
||||
utils.SessionSv1DisconnectSession: handleDisconnectSession,
|
||||
}
|
||||
if sSv1BiRpc, err = utils.NewBiJSONrpcClient(sSv1Cfg.SessionSCfg().ListenBijson,
|
||||
clntHandlers); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if sSApierRpc, err = jsonrpc.Dial("tcp", sSv1Cfg.RPCJSONListen); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
dummyClnt.Close() // close so we don't get EOF error when disconnecting server
|
||||
}
|
||||
|
||||
// Load the tariff plan, creating accounts and their balances
|
||||
func TestSSv1ItTPFromFolder(t *testing.T) {
|
||||
attrs := &utils.AttrLoadTpFromFolder{
|
||||
FolderPath: path.Join(*dataDir, "tariffplans", "testit")}
|
||||
var loadInst utils.LoadInstance
|
||||
if err := sSApierRpc.Call(utils.ApierV2LoadTariffPlanFromFolder,
|
||||
attrs, &loadInst); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
time.Sleep(time.Millisecond) // Give time for scheduler to execute topups
|
||||
}
|
||||
|
||||
func TestSSv1ItAuth(t *testing.T) {
|
||||
authUsage := 5 * time.Minute
|
||||
args := &sessionmanager.V1AuthorizeArgs{
|
||||
GetMaxUsage: true,
|
||||
AuthorizeResources: false,
|
||||
GetSuppliers: false,
|
||||
GetAttributes: true,
|
||||
CGREvent: utils.CGREvent{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "TestSSv1ItAuth",
|
||||
Event: map[string]interface{}{
|
||||
utils.ACCID: "TestSSv1ItAuth",
|
||||
utils.RequestType: utils.META_PREPAID,
|
||||
utils.Account: "1001",
|
||||
utils.Destination: "1002",
|
||||
utils.SetupTime: time.Date(2018, time.January, 7, 16, 60, 0, 0, time.UTC),
|
||||
utils.Usage: authUsage,
|
||||
},
|
||||
},
|
||||
}
|
||||
var rply sessionmanager.V1AuthorizeReply
|
||||
if err := sSv1BiRpc.Call(utils.SessionSv1AuthorizeEvent, args, &rply); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if *rply.MaxUsage != authUsage {
|
||||
t.Errorf("Unexpected MaxUsage: %v", rply.MaxUsage)
|
||||
}
|
||||
/*if !*rply.ResourcesAuthorized {
|
||||
t.Errorf("Unexpected ResourceAuthorized: %v", rply.ResourcesAuthorized)
|
||||
}
|
||||
|
||||
eSplrs := &engine.SortedSuppliers{
|
||||
ProfileID: "SPL_ACNT_1001",
|
||||
Sorting: utils.MetaWeight,
|
||||
SortedSuppliers: []*engine.SortedSupplier{
|
||||
&engine.SortedSupplier{
|
||||
SupplierID: "supplier1",
|
||||
SortingData: map[string]interface{}{
|
||||
"Weight": 20.0,
|
||||
},
|
||||
},
|
||||
&engine.SortedSupplier{
|
||||
SupplierID: "supplier2",
|
||||
SortingData: map[string]interface{}{
|
||||
"Weight": 10.0,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
if !reflect.DeepEqual(eSplrs, rply.Suppliers) {
|
||||
t.Errorf("expecting: %+v, received: %+v", utils.ToJSON(eSplrs), utils.ToJSON(rply.Suppliers))
|
||||
}
|
||||
*/
|
||||
eAttrs := &engine.AttrSProcessEventReply{
|
||||
MatchedProfile: "ATTR_ACNT_1001",
|
||||
AlteredFields: []string{"OfficeGroup"},
|
||||
CGREvent: &utils.CGREvent{Tenant: "cgrates.org",
|
||||
ID: "TestSSv1ItAuth",
|
||||
Context: utils.StringPointer(utils.MetaSessionS),
|
||||
Event: map[string]interface{}{
|
||||
"Account": "1001", "Destination": "1002",
|
||||
"EventName": "CgrAuthorization",
|
||||
"OfficeGroup": "Marketing",
|
||||
"OriginID": "TestSSv1ItAuth",
|
||||
"RequestType": "*prepaid",
|
||||
"SetupTime": "2018-01-07T17:00:00Z",
|
||||
"Usage": 300000000000.0,
|
||||
},
|
||||
},
|
||||
}
|
||||
if !reflect.DeepEqual(eAttrs, rply.Attributes) {
|
||||
t.Errorf("expecting: %+v, received: %+v", utils.ToJSON(eAttrs), utils.ToJSON(rply.Attributes))
|
||||
}
|
||||
}
|
||||
|
||||
func TestSSv1ItStopCgrEngine(t *testing.T) {
|
||||
if err := sSv1BiRpc.Close(); err != nil { // Close the connection so we don't get EOF warnings from client
|
||||
t.Error(err)
|
||||
}
|
||||
if err := engine.KillEngine(100); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
75
data/conf/samples/sessions/cgrates.json
Normal file
75
data/conf/samples/sessions/cgrates.json
Normal file
@@ -0,0 +1,75 @@
|
||||
{
|
||||
// CGRateS Configuration file
|
||||
//
|
||||
// Used for SessionSv1 integration tests
|
||||
|
||||
|
||||
"general": {
|
||||
"log_level": 7,
|
||||
},
|
||||
|
||||
|
||||
"listen": {
|
||||
"rpc_json": ":2012",
|
||||
"rpc_gob": ":2013",
|
||||
"http": ":2080",
|
||||
},
|
||||
|
||||
|
||||
"stor_db": {
|
||||
"db_password": "CGRateS.org",
|
||||
},
|
||||
|
||||
|
||||
"rals": {
|
||||
"enabled": true,
|
||||
},
|
||||
|
||||
|
||||
"scheduler": {
|
||||
"enabled": true,
|
||||
},
|
||||
|
||||
|
||||
"cdrs": {
|
||||
"enabled": true,
|
||||
},
|
||||
|
||||
|
||||
"resources": {
|
||||
"enabled": true,
|
||||
},
|
||||
|
||||
|
||||
"attributes": {
|
||||
"enabled": true,
|
||||
},
|
||||
|
||||
|
||||
"suppliers": {
|
||||
"enabled": true,
|
||||
},
|
||||
|
||||
|
||||
"sessions": {
|
||||
"enabled": true,
|
||||
"session_ttl": "50ms",
|
||||
"rals_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"}
|
||||
],
|
||||
"cdrs_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"}
|
||||
],
|
||||
"resources_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"}
|
||||
],
|
||||
"suppliers_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"}
|
||||
],
|
||||
"attributes_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"}
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
}
|
||||
2
data/tariffplans/testit/AccountActions.csv
Normal file
2
data/tariffplans/testit/AccountActions.csv
Normal file
@@ -0,0 +1,2 @@
|
||||
#Tenant,Account,ActionPlanId,ActionTriggersId,AllowNegative,Disabled
|
||||
cgrates.org,1001,PACKAGE_1001,,,
|
||||
|
2
data/tariffplans/testit/ActionPlans.csv
Normal file
2
data/tariffplans/testit/ActionPlans.csv
Normal file
@@ -0,0 +1,2 @@
|
||||
#Id,ActionsId,TimingId,Weight
|
||||
PACKAGE_1001,TOPUP_RST_MONETARY_10,*asap,10
|
||||
|
2
data/tariffplans/testit/Actions.csv
Normal file
2
data/tariffplans/testit/Actions.csv
Normal file
@@ -0,0 +1,2 @@
|
||||
#ActionsId[0],Action[1],ExtraParameters[2],Filter[3],BalanceId[4],BalanceType[5],Directions[6],Categories[7],DestinationIds[8],RatingSubject[9],SharedGroup[10],ExpiryTime[11],TimingIds[12],Units[13],BalanceWeight[14],BalanceBlocker[15],BalanceDisabled[16],Weight[17]
|
||||
TOPUP_RST_MONETARY_10,*topup_reset,,,,*monetary,*out,,*any,,,*unlimited,,10,10,false,false,10
|
||||
|
2
data/tariffplans/testit/Attributes.csv
Normal file
2
data/tariffplans/testit/Attributes.csv
Normal file
@@ -0,0 +1,2 @@
|
||||
#Tenant,ID,Context,FilterIDs,ActivationInterval,FieldName,Initial,Substitute,Append,Weight
|
||||
cgrates.org,ATTR_ACNT_1001,*sessions,FLTR_ACCOUNT_1001,,OfficeGroup,*any,Marketing,true,10
|
||||
|
2
data/tariffplans/testit/DestinationRates.csv
Normal file
2
data/tariffplans/testit/DestinationRates.csv
Normal file
@@ -0,0 +1,2 @@
|
||||
#Id,DestinationId,RatesTag,RoundingMethod,RoundingDecimals,MaxCost,MaxCostStrategy
|
||||
DR_ANY_1CNT,*any,RT_1CNT,*up,5,0,
|
||||
|
3
data/tariffplans/testit/Filters.csv
Normal file
3
data/tariffplans/testit/Filters.csv
Normal file
@@ -0,0 +1,3 @@
|
||||
#Tenant[0],ID[1],FilterType[2],FilterFieldName[3],FilterFieldValues[4],ActivationInterval[5]
|
||||
cgrates.org,FLTR_ACCOUNT_1001,*string,Account,1001,
|
||||
|
||||
|
2
data/tariffplans/testit/Rates.csv
Normal file
2
data/tariffplans/testit/Rates.csv
Normal file
@@ -0,0 +1,2 @@
|
||||
#Id,ConnectFee,Rate,RateUnit,RateIncrement,GroupIntervalStart
|
||||
RT_1CNT,0,0.01,60s,1s,0s
|
||||
|
2
data/tariffplans/testit/RatingPlans.csv
Normal file
2
data/tariffplans/testit/RatingPlans.csv
Normal file
@@ -0,0 +1,2 @@
|
||||
#Id,DestinationRatesId,TimingTag,Weight
|
||||
RP_TESTIT1,DR_ANY_1CNT,*any,10
|
||||
|
2
data/tariffplans/testit/RatingProfiles.csv
Normal file
2
data/tariffplans/testit/RatingProfiles.csv
Normal file
@@ -0,0 +1,2 @@
|
||||
#Direction,Tenant,Category,Subject,ActivationTime,RatingPlanId,RatesFallbackSubject,CdrStatQueueIds
|
||||
*out,cgrates.org,call,*any,2018-01-01T00:00:00Z,RP_TESTIT1,,
|
||||
|
2
data/tariffplans/testit/Resources.csv
Normal file
2
data/tariffplans/testit/Resources.csv
Normal file
@@ -0,0 +1,2 @@
|
||||
#Tenant[0],Id[1],FilterIDs[2],ActivationInterval[3],TTL[4],Limit[5],AllocationMessage[6],Blocker[7],Stored[8],Weight[9],Thresholds[10]
|
||||
cgrates.org,RES_ACNT_1001,FLTR_ACCOUNT_1001,,1h,1,,false,false,10,
|
||||
|
2
data/tariffplans/testit/Stats.csv
Normal file
2
data/tariffplans/testit/Stats.csv
Normal file
@@ -0,0 +1,2 @@
|
||||
#Tenant[0],Id[1],FilterIDs[2],ActivationInterval[3],QueueLength[4],TTL[5],Metrics[6],MetricParams[7],Blocker[8],Stored[9],Weight[10],MinItems[11],Thresholds[12]
|
||||
|
||||
|
4
data/tariffplans/testit/Suppliers.csv
Normal file
4
data/tariffplans/testit/Suppliers.csv
Normal file
@@ -0,0 +1,4 @@
|
||||
#Tenant,ID,FilterIDs,ActivationInterval,Sorting,SortingParams,SupplierID,SupplierFilterIDs,SupplierAccountIDs,SupplierRatingPlanIDs,SupplierResourceIDs,SupplierStatIDs,SupplierWeight,Blocker,Weight
|
||||
cgrates.org,SPL_ACNT_1001,FLTR_ACCOUNT_1001,,*weight,,supplier1,,,,,,20,,10
|
||||
cgrates.org,SPL_ACNT_1001,,,,,supplier2,,,,,,10,,
|
||||
|
||||
|
2
data/tariffplans/testit/Thresholds.csv
Normal file
2
data/tariffplans/testit/Thresholds.csv
Normal file
@@ -0,0 +1,2 @@
|
||||
#Tenant[0],Id[1],FilterIDs[2],ActivationInterval[3],Recurrent[4],MinHits[5],MinSleep[6],Blocker[7],Weight[8],ActionIDs[9],Async[10]
|
||||
|
||||
|
@@ -235,7 +235,6 @@ func (rpf *RatingProfile) GetRatingPlansForPrefix(cd *CallDescriptor) (err error
|
||||
cd.addRatingInfos(ris)
|
||||
return
|
||||
}
|
||||
|
||||
return utils.ErrNotFound
|
||||
}
|
||||
|
||||
|
||||
@@ -82,8 +82,9 @@ func TestSMGBiRPCStartEngine(t *testing.T) {
|
||||
func TestSMGBiRPCApierRpcConn(t *testing.T) {
|
||||
time.Sleep(time.Duration(1 * time.Second))
|
||||
clntHandlers := map[string]interface{}{"SMGClientV1.DisconnectSession": handleDisconnectSession}
|
||||
if _, err = utils.NewBiJSONrpcClient(smgBiRPCCfg.SessionSCfg().ListenBijson,
|
||||
clntHandlers); err != nil { // First attempt is to make sure multiple clients are supported
|
||||
dummyClnt, err := utils.NewBiJSONrpcClient(smgBiRPCCfg.SessionSCfg().ListenBijson,
|
||||
clntHandlers)
|
||||
if err != nil { // First attempt is to make sure multiple clients are supported
|
||||
t.Fatal(err)
|
||||
}
|
||||
if smgBiRPC, err = utils.NewBiJSONrpcClient(smgBiRPCCfg.SessionSCfg().ListenBijson,
|
||||
@@ -93,6 +94,7 @@ func TestSMGBiRPCApierRpcConn(t *testing.T) {
|
||||
if smgRPC, err = jsonrpc.Dial("tcp", smgBiRPCCfg.RPCJSONListen); err != nil { // Connect also simple RPC so we can check accounts and such
|
||||
t.Fatal(err)
|
||||
}
|
||||
dummyClnt.Close() // close so we don't get EOF error when disconnecting server
|
||||
}
|
||||
|
||||
// Load the tariff plan, creating accounts and their balances
|
||||
|
||||
@@ -87,6 +87,7 @@ func NewSMGeneric(cgrCfg *config.CGRConfig, rals, resS,
|
||||
return &SMGeneric{cgrCfg: cgrCfg,
|
||||
rals: rals,
|
||||
resS: resS,
|
||||
splS: splS,
|
||||
attrS: attrS,
|
||||
cdrsrv: cdrsrv,
|
||||
smgReplConns: smgReplConns,
|
||||
@@ -1316,19 +1317,19 @@ func (smg *SMGeneric) BiRPCV1ReplicatePassiveSessions(clnt rpcclient.RpcClientCo
|
||||
}
|
||||
|
||||
type V1AuthorizeArgs struct {
|
||||
GetMaxUsage bool
|
||||
CheckResources bool
|
||||
GetSuppliers bool
|
||||
GetAttributes bool
|
||||
GetMaxUsage bool
|
||||
AuthorizeResources bool
|
||||
GetSuppliers bool
|
||||
GetAttributes bool
|
||||
utils.CGREvent
|
||||
utils.Paginator
|
||||
}
|
||||
|
||||
type V1AuthorizeReply struct {
|
||||
MaxUsage time.Duration
|
||||
ResourcesAllowed bool
|
||||
Suppliers engine.SortedSuppliers
|
||||
Attributes *engine.AttrSProcessEventReply
|
||||
MaxUsage *time.Duration
|
||||
ResourcesAuthorized *bool
|
||||
Suppliers *engine.SortedSuppliers
|
||||
Attributes *engine.AttrSProcessEventReply
|
||||
}
|
||||
|
||||
// BiRPCV1Authorize performs authorization for CGREvent based on specific components
|
||||
@@ -1340,17 +1341,17 @@ func (smg *SMGeneric) BiRPCv1AuthorizeEvent(clnt *rpc2.Client,
|
||||
}
|
||||
maxUsage, err := smg.GetMaxUsage(args.CGREvent.Event)
|
||||
if err != nil {
|
||||
return utils.NewErrServerError(err)
|
||||
return utils.NewErrRALs(err)
|
||||
}
|
||||
authReply.MaxUsage = maxUsage
|
||||
authReply.MaxUsage = &maxUsage
|
||||
}
|
||||
if args.CheckResources {
|
||||
if args.AuthorizeResources {
|
||||
if smg.resS == nil {
|
||||
return utils.NewErrNotConnected(utils.ResourceS)
|
||||
}
|
||||
originID, err := args.CGREvent.FieldAsString(utils.ACCID)
|
||||
if err != nil {
|
||||
return utils.NewErrServerError(err)
|
||||
return utils.NewErrMandatoryIeMissing(utils.ACCID)
|
||||
}
|
||||
var allowed bool
|
||||
attrRU := utils.ArgRSv1ResourceUsage{
|
||||
@@ -1360,9 +1361,9 @@ func (smg *SMGeneric) BiRPCv1AuthorizeEvent(clnt *rpc2.Client,
|
||||
}
|
||||
if err = smg.resS.Call(utils.ResourceSv1AllowUsage,
|
||||
attrRU, &allowed); err != nil {
|
||||
return err
|
||||
return utils.NewErrResourceS(err)
|
||||
}
|
||||
authReply.ResourcesAllowed = allowed
|
||||
authReply.ResourcesAuthorized = &allowed
|
||||
}
|
||||
if args.GetSuppliers {
|
||||
if smg.splS == nil {
|
||||
@@ -1371,16 +1372,18 @@ func (smg *SMGeneric) BiRPCv1AuthorizeEvent(clnt *rpc2.Client,
|
||||
var splsReply engine.SortedSuppliers
|
||||
if err = smg.splS.Call(utils.SupplierSv1GetSuppliers,
|
||||
args.CGREvent, &splsReply); err != nil {
|
||||
return err
|
||||
return utils.NewErrSupplierS(err)
|
||||
}
|
||||
if splsReply.SortedSuppliers != nil {
|
||||
authReply.Suppliers = &splsReply
|
||||
}
|
||||
authReply.Suppliers = splsReply
|
||||
}
|
||||
if args.GetAttributes {
|
||||
if smg.attrS == nil {
|
||||
return utils.NewErrNotConnected(utils.AttributeS)
|
||||
}
|
||||
if args.CGREvent.Context == nil { // populate if not already in
|
||||
args.CGREvent.Context = utils.StringPointer(utils.MetaSMG)
|
||||
args.CGREvent.Context = utils.StringPointer(utils.MetaSessionS)
|
||||
}
|
||||
var rplyEv engine.AttrSProcessEventReply
|
||||
if err = smg.attrS.Call(utils.AttributeSv1ProcessEvent,
|
||||
|
||||
@@ -554,6 +554,10 @@ const (
|
||||
ApierV1ComputeFilterIndexes = "ApierV1.ComputeFilterIndexes"
|
||||
)
|
||||
|
||||
const (
|
||||
ApierV2LoadTariffPlanFromFolder = "ApierV2.LoadTariffPlanFromFolder"
|
||||
)
|
||||
|
||||
// MetaSupplierAPIs
|
||||
const (
|
||||
SupplierSv1GetSuppliers = "SupplierSv1.GetSuppliers"
|
||||
|
||||
@@ -103,6 +103,22 @@ func NewErrNotConnected(serv string) error {
|
||||
return fmt.Errorf("NOT_CONNECTED: %s", serv)
|
||||
}
|
||||
|
||||
func NewErrRALs(err error) error {
|
||||
return fmt.Errorf("RALS_ERROR: %s", err)
|
||||
}
|
||||
|
||||
func NewErrResourceS(err error) error {
|
||||
return fmt.Errorf("RESOURCES_ERROR: %s", err)
|
||||
}
|
||||
|
||||
func NewErrSupplierS(err error) error {
|
||||
return fmt.Errorf("SUPPLIERS_ERROR: %s", err)
|
||||
}
|
||||
|
||||
func NewErrAttributeS(err error) error {
|
||||
return fmt.Errorf("SUPPLIERS_ERROR: %s", err)
|
||||
}
|
||||
|
||||
// Centralized returns for APIs
|
||||
func APIErrorHandler(errIn error) (err error) {
|
||||
cgrErr, ok := errIn.(*CGRError)
|
||||
|
||||
Reference in New Issue
Block a user