From e27b72268f99b811e1dddb663e0609d02daecb75 Mon Sep 17 00:00:00 2001 From: DanB Date: Mon, 8 Jan 2018 16:12:57 +0100 Subject: [PATCH] SessionSv1.AuthorizeEvent with integration tests --- agents/fsagent.go | 18 +- agents/fsevent.go | 2 +- apier/v1/sessions.go | 20 +- apier/v1/sessionsv1_it_test.go | 196 +++++++++++++++++++ data/conf/samples/sessions/cgrates.json | 75 +++++++ data/tariffplans/testit/AccountActions.csv | 2 + data/tariffplans/testit/ActionPlans.csv | 2 + data/tariffplans/testit/Actions.csv | 2 + data/tariffplans/testit/Attributes.csv | 2 + data/tariffplans/testit/DestinationRates.csv | 2 + data/tariffplans/testit/Filters.csv | 3 + data/tariffplans/testit/Rates.csv | 2 + data/tariffplans/testit/RatingPlans.csv | 2 + data/tariffplans/testit/RatingProfiles.csv | 2 + data/tariffplans/testit/Resources.csv | 2 + data/tariffplans/testit/Stats.csv | 2 + data/tariffplans/testit/Suppliers.csv | 4 + data/tariffplans/testit/Thresholds.csv | 2 + engine/ratingprofile.go | 1 - sessionmanager/smgbirpc_it_test.go | 6 +- sessionmanager/smgeneric.go | 37 ++-- utils/consts.go | 4 + utils/errors.go | 16 ++ 23 files changed, 365 insertions(+), 39 deletions(-) create mode 100644 apier/v1/sessionsv1_it_test.go create mode 100644 data/conf/samples/sessions/cgrates.json create mode 100644 data/tariffplans/testit/AccountActions.csv create mode 100644 data/tariffplans/testit/ActionPlans.csv create mode 100644 data/tariffplans/testit/Actions.csv create mode 100644 data/tariffplans/testit/Attributes.csv create mode 100644 data/tariffplans/testit/DestinationRates.csv create mode 100644 data/tariffplans/testit/Filters.csv create mode 100644 data/tariffplans/testit/Rates.csv create mode 100644 data/tariffplans/testit/RatingPlans.csv create mode 100644 data/tariffplans/testit/RatingProfiles.csv create mode 100644 data/tariffplans/testit/Resources.csv create mode 100644 data/tariffplans/testit/Stats.csv create mode 100644 data/tariffplans/testit/Suppliers.csv create mode 100644 data/tariffplans/testit/Thresholds.csv diff --git a/agents/fsagent.go b/agents/fsagent.go index dca965ebd..b2af39015 100644 --- a/agents/fsagent.go +++ b/agents/fsagent.go @@ -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(" 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(" 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(" 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(" Failed processing CDR, cgrid: %s, accid: %s, error: <%s>", cdr.CGRID, cdr.OriginID, err.Error())) } diff --git a/agents/fsevent.go b/agents/fsevent.go index 1adffb5fd..8fccf387d 100644 --- a/agents/fsevent.go +++ b/agents/fsevent.go @@ -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 diff --git a/apier/v1/sessions.go b/apier/v1/sessions.go index cc43c6c55..242312c06 100644 --- a/apier/v1/sessions.go +++ b/apier/v1/sessions.go @@ -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) } diff --git a/apier/v1/sessionsv1_it_test.go b/apier/v1/sessionsv1_it_test.go new file mode 100644 index 000000000..3a2f73dea --- /dev/null +++ b/apier/v1/sessionsv1_it_test.go @@ -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 +*/ + +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) + } +} diff --git a/data/conf/samples/sessions/cgrates.json b/data/conf/samples/sessions/cgrates.json new file mode 100644 index 000000000..02393bbe7 --- /dev/null +++ b/data/conf/samples/sessions/cgrates.json @@ -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"} + ], +}, + + +} diff --git a/data/tariffplans/testit/AccountActions.csv b/data/tariffplans/testit/AccountActions.csv new file mode 100644 index 000000000..48442717c --- /dev/null +++ b/data/tariffplans/testit/AccountActions.csv @@ -0,0 +1,2 @@ +#Tenant,Account,ActionPlanId,ActionTriggersId,AllowNegative,Disabled +cgrates.org,1001,PACKAGE_1001,,, diff --git a/data/tariffplans/testit/ActionPlans.csv b/data/tariffplans/testit/ActionPlans.csv new file mode 100644 index 000000000..b8bda093e --- /dev/null +++ b/data/tariffplans/testit/ActionPlans.csv @@ -0,0 +1,2 @@ +#Id,ActionsId,TimingId,Weight +PACKAGE_1001,TOPUP_RST_MONETARY_10,*asap,10 diff --git a/data/tariffplans/testit/Actions.csv b/data/tariffplans/testit/Actions.csv new file mode 100644 index 000000000..b7d93f795 --- /dev/null +++ b/data/tariffplans/testit/Actions.csv @@ -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 diff --git a/data/tariffplans/testit/Attributes.csv b/data/tariffplans/testit/Attributes.csv new file mode 100644 index 000000000..26c6383cb --- /dev/null +++ b/data/tariffplans/testit/Attributes.csv @@ -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 diff --git a/data/tariffplans/testit/DestinationRates.csv b/data/tariffplans/testit/DestinationRates.csv new file mode 100644 index 000000000..afd7edf81 --- /dev/null +++ b/data/tariffplans/testit/DestinationRates.csv @@ -0,0 +1,2 @@ +#Id,DestinationId,RatesTag,RoundingMethod,RoundingDecimals,MaxCost,MaxCostStrategy +DR_ANY_1CNT,*any,RT_1CNT,*up,5,0, diff --git a/data/tariffplans/testit/Filters.csv b/data/tariffplans/testit/Filters.csv new file mode 100644 index 000000000..3f07fa934 --- /dev/null +++ b/data/tariffplans/testit/Filters.csv @@ -0,0 +1,3 @@ +#Tenant[0],ID[1],FilterType[2],FilterFieldName[3],FilterFieldValues[4],ActivationInterval[5] +cgrates.org,FLTR_ACCOUNT_1001,*string,Account,1001, + diff --git a/data/tariffplans/testit/Rates.csv b/data/tariffplans/testit/Rates.csv new file mode 100644 index 000000000..d04653135 --- /dev/null +++ b/data/tariffplans/testit/Rates.csv @@ -0,0 +1,2 @@ +#Id,ConnectFee,Rate,RateUnit,RateIncrement,GroupIntervalStart +RT_1CNT,0,0.01,60s,1s,0s diff --git a/data/tariffplans/testit/RatingPlans.csv b/data/tariffplans/testit/RatingPlans.csv new file mode 100644 index 000000000..d84767576 --- /dev/null +++ b/data/tariffplans/testit/RatingPlans.csv @@ -0,0 +1,2 @@ +#Id,DestinationRatesId,TimingTag,Weight +RP_TESTIT1,DR_ANY_1CNT,*any,10 \ No newline at end of file diff --git a/data/tariffplans/testit/RatingProfiles.csv b/data/tariffplans/testit/RatingProfiles.csv new file mode 100644 index 000000000..6c0ad1d04 --- /dev/null +++ b/data/tariffplans/testit/RatingProfiles.csv @@ -0,0 +1,2 @@ +#Direction,Tenant,Category,Subject,ActivationTime,RatingPlanId,RatesFallbackSubject,CdrStatQueueIds +*out,cgrates.org,call,*any,2018-01-01T00:00:00Z,RP_TESTIT1,, diff --git a/data/tariffplans/testit/Resources.csv b/data/tariffplans/testit/Resources.csv new file mode 100644 index 000000000..a5c997a6f --- /dev/null +++ b/data/tariffplans/testit/Resources.csv @@ -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, diff --git a/data/tariffplans/testit/Stats.csv b/data/tariffplans/testit/Stats.csv new file mode 100644 index 000000000..d6200cacf --- /dev/null +++ b/data/tariffplans/testit/Stats.csv @@ -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] + diff --git a/data/tariffplans/testit/Suppliers.csv b/data/tariffplans/testit/Suppliers.csv new file mode 100644 index 000000000..27e5a8c4c --- /dev/null +++ b/data/tariffplans/testit/Suppliers.csv @@ -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,, + diff --git a/data/tariffplans/testit/Thresholds.csv b/data/tariffplans/testit/Thresholds.csv new file mode 100644 index 000000000..f85aa2ada --- /dev/null +++ b/data/tariffplans/testit/Thresholds.csv @@ -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] + diff --git a/engine/ratingprofile.go b/engine/ratingprofile.go index 58f9bff3d..79f7abb7d 100644 --- a/engine/ratingprofile.go +++ b/engine/ratingprofile.go @@ -235,7 +235,6 @@ func (rpf *RatingProfile) GetRatingPlansForPrefix(cd *CallDescriptor) (err error cd.addRatingInfos(ris) return } - return utils.ErrNotFound } diff --git a/sessionmanager/smgbirpc_it_test.go b/sessionmanager/smgbirpc_it_test.go index c91ec4875..72ae1bfff 100644 --- a/sessionmanager/smgbirpc_it_test.go +++ b/sessionmanager/smgbirpc_it_test.go @@ -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 diff --git a/sessionmanager/smgeneric.go b/sessionmanager/smgeneric.go index f9d98bb3e..a89db1607 100644 --- a/sessionmanager/smgeneric.go +++ b/sessionmanager/smgeneric.go @@ -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, diff --git a/utils/consts.go b/utils/consts.go index 95719e542..fc2f78d20 100755 --- a/utils/consts.go +++ b/utils/consts.go @@ -554,6 +554,10 @@ const ( ApierV1ComputeFilterIndexes = "ApierV1.ComputeFilterIndexes" ) +const ( + ApierV2LoadTariffPlanFromFolder = "ApierV2.LoadTariffPlanFromFolder" +) + // MetaSupplierAPIs const ( SupplierSv1GetSuppliers = "SupplierSv1.GetSuppliers" diff --git a/utils/errors.go b/utils/errors.go index aac5f4b48..32117829a 100644 --- a/utils/errors.go +++ b/utils/errors.go @@ -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)