Added GetSuppliersForEvent

This commit is contained in:
Tripon Alexandru-Ionut
2019-04-18 13:41:28 +03:00
parent 45c843a3a4
commit 0a7529f114
10 changed files with 259 additions and 8 deletions

View File

@@ -337,6 +337,12 @@ func (dSup *DispatcherSupplierSv1) GetSuppliers(args *engine.ArgsGetSuppliers,
return dSup.dSup.SupplierSv1GetSuppliers(args, reply)
}
// GetSuppliersProfiles returns a list of suppliers profiles that match for Event
func (dSup *DispatcherSupplierSv1) GetSupplierForEvent(args *utils.CGREventWithArgDispatcher,
reply *engine.SupplierProfile) error {
return dSup.dSup.SupplierSv1GetSupplierForEvent(args, reply)
}
func NewDispatcherAttributeSv1(dps *dispatchers.DispatcherService) *DispatcherAttributeSv1 {
return &DispatcherAttributeSv1{dA: dps}
}

View File

@@ -55,6 +55,7 @@ type ResourceSv1Interface interface {
type SupplierSv1Interface interface {
GetSuppliers(args *engine.ArgsGetSuppliers, reply *engine.SortedSuppliers) error
GetSupplierForEvent(args *utils.CGREventWithArgDispatcher, reply *engine.SupplierProfile) error
Ping(ign *utils.CGREventWithArgDispatcher, reply *string) error
}

View File

@@ -133,6 +133,12 @@ func (splv1 *SupplierSv1) GetSuppliers(args *engine.ArgsGetSuppliers,
return splv1.splS.V1GetSuppliers(args, reply)
}
// GetSuppliersProfiles returns a list of suppliers profiles that match for Event
func (splv1 *SupplierSv1) GetSupplierForEvent(args *utils.CGREventWithArgDispatcher,
reply *engine.SupplierProfile) error {
return splv1.splS.V1GetSupplierForEvent(args, reply)
}
func (splv1 *SupplierSv1) Ping(ign *utils.CGREventWithArgDispatcher, reply *string) error {
*reply = utils.Pong
return nil

View File

@@ -24,6 +24,7 @@ import (
"net/rpc/jsonrpc"
"path"
"reflect"
"sort"
"testing"
"time"
@@ -65,6 +66,7 @@ var sTestsSupplierSV1 = []func(t *testing.T){
testV1SplSGetSupplierProfileIDs,
testV1SplSUpdateSupplierProfiles,
testV1SplSRemSupplierProfiles,
testV1SplSGetSupplierForEvent,
testV1SplSupplierPing,
testV1SplSStopEngine,
}
@@ -878,6 +880,70 @@ func testV1SplSupplierPing(t *testing.T) {
}
}
func testV1SplSGetSupplierForEvent(t *testing.T) {
ev := &utils.CGREventWithArgDispatcher{
CGREvent: &utils.CGREvent{
Tenant: "cgrates.org",
ID: "testV1SplSGetHighestCostSuppliers",
Event: map[string]interface{}{
utils.Account: "1000",
utils.Destination: "1001",
utils.SetupTime: "*now",
"Subject": "TEST",
},
},
}
expected := engine.SupplierProfile{
Tenant: "cgrates.org",
ID: "SPL_LCR",
FilterIDs: []string{"FLTR_TEST"},
ActivationInterval: &utils.ActivationInterval{
ActivationTime: time.Date(2017, 11, 27, 00, 00, 00, 00, time.UTC),
},
Sorting: "*least_cost",
SortingParameters: []string{},
Suppliers: []*engine.Supplier{
&engine.Supplier{
ID: "supplier_1",
FilterIDs: nil,
AccountIDs: nil,
RatingPlanIDs: []string{"RP_TEST_1"},
ResourceIDs: nil,
StatIDs: nil,
Weight: 10,
Blocker: false,
SupplierParameters: "",
},
&engine.Supplier{
ID: "supplier_2",
FilterIDs: nil,
AccountIDs: nil,
RatingPlanIDs: []string{"RP_TEST_2"},
ResourceIDs: nil,
StatIDs: nil,
Weight: 0,
Blocker: false,
SupplierParameters: "",
},
},
Weight: 50,
}
var supProf engine.SupplierProfile
if err := splSv1Rpc.Call(utils.SupplierSv1GetSupplierForEvent,
ev, &supProf); err != nil {
t.Fatal(err)
}
sort.Slice(expected.Suppliers, func(i, j int) bool {
return supProf.Suppliers[i].Weight < supProf.Suppliers[j].Weight
})
sort.Slice(supProf.Suppliers, func(i, j int) bool {
return supProf.Suppliers[i].Weight < supProf.Suppliers[j].Weight
})
if !reflect.DeepEqual(expected, supProf) {
t.Errorf("Expected: %s ,received: %s", utils.ToJSON(expected), utils.ToJSON(supProf))
}
}
func testV1SplSStopEngine(t *testing.T) {
if err := engine.KillEngine(100); err != nil {
t.Error(err)

View File

@@ -0,0 +1,65 @@
/*
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 console
import (
"github.com/cgrates/cgrates/engine"
"github.com/cgrates/cgrates/utils"
)
func init() {
c := &CmdGetSupplierForEvent{
name: "supplier_for_event",
rpcMethod: utils.SupplierSv1GetSupplierForEvent,
rpcParams: &utils.CGREventWithArgDispatcher{},
}
commands[c.Name()] = c
c.CommandExecuter = &CommandExecuter{c}
}
type CmdGetSupplierForEvent struct {
name string
rpcMethod string
rpcParams *utils.CGREventWithArgDispatcher
*CommandExecuter
}
func (self *CmdGetSupplierForEvent) Name() string {
return self.name
}
func (self *CmdGetSupplierForEvent) RpcMethod() string {
return self.rpcMethod
}
func (self *CmdGetSupplierForEvent) RpcParams(reset bool) interface{} {
if reset || self.rpcParams == nil {
self.rpcParams = &utils.CGREventWithArgDispatcher{}
}
return self.rpcParams
}
func (self *CmdGetSupplierForEvent) PostprocessRpcParams() error {
return nil
}
func (self *CmdGetSupplierForEvent) RpcResult() interface{} {
atr := engine.SupplierProfile{}
return &atr
}

View File

@@ -6,7 +6,7 @@ cgrates.org,ATTR_API_ATTR_FAKE_AUTH,*auth,*string:~APIKey:12345,,,APIMethods,*co
cgrates.org,ATTR_API_ATTR_AUTH,*auth,*string:~APIKey:attr12345,,,APIMethods,*constant,AttributeSv1.Ping&AttributeSv1.GetAttributeForEvent&AttributeSv1.ProcessEvent,false,20
cgrates.org,ATTR_API_CHRG_AUTH,*auth,*string:~APIKey:chrg12345,,,APIMethods,*constant,ChargerSv1.Ping&ChargerSv1.GetChargersForEvent&ChargerSv1.ProcessEvent,false,20
cgrates.org,ATTR_API_THR_AUTH,*auth,*string:~APIKey:thr12345,,,APIMethods,*constant,ThresholdSv1.Ping&ThresholdSv1.GetThresholdsForEvent&ThresholdSv1.ProcessEvent&ThresholdSv1.GetThreshold&ThresholdSv1.GetThresholdIDs,false,20
cgrates.org,ATTR_API_SUP_AUTH,*auth,*string:~APIKey:sup12345,,,APIMethods,*constant,SupplierSv1.Ping&SupplierSv1.GetSuppliers,false,20
cgrates.org,ATTR_API_SUP_AUTH,*auth,*string:~APIKey:sup12345,,,APIMethods,*constant,SupplierSv1.Ping&SupplierSv1.GetSuppliers&SupplierSv1.GetSupplierForEvent,false,20
cgrates.org,ATTR_API_STAT_AUTH,*auth,*string:~APIKey:stat12345,,,APIMethods,*constant,StatSv1.Ping&StatSv1.GetStatQueuesForEvent&StatSv1.GetQueueStringMetrics&StatSv1.ProcessEvent&StatSv1.GetQueueIDs&StatSv1.GetQueueFloatMetrics,false,20
cgrates.org,ATTR_API_RES_AUTH,*auth,*string:~APIKey:res12345,,,APIMethods,*constant,ResourceSv1.Ping&ResourceSv1.GetResourcesForEvent&ResourceSv1.AuthorizeResources&ResourceSv1.AllocateResources&ResourceSv1.ReleaseResources,false,20
cgrates.org,ATTR_API_SES_AUTH,*auth,*string:~APIKey:ses12345,,,APIMethods,*constant,SessionSv1.Ping&SessionSv1.AuthorizeEvent&SessionSv1.AuthorizeEventWithDigest&SessionSv1.InitiateSession&SessionSv1.InitiateSessionWithDigest&SessionSv1.UpdateSession&SessionSv1.SyncSessions&SessionSv1.TerminateSession&SessionSv1.ProcessCDR&SessionSv1.ProcessEvent&SessionSv1.GetActiveSessions&SessionSv1.GetActiveSessionsCount&SessionSv1.ForceDisconnect&SessionSv1.GetPassiveSessions&SessionSv1.GetPassiveSessionsCount&SessionSv1.ReplicateSessions&SessionSv1.SetPassiveSession,false,20
1 #Tenant ID Contexts FilterIDs ActivationInterval AttributeFilterIDs FieldName Type Value Blocker Weight
6 cgrates.org ATTR_API_ATTR_AUTH *auth *string:~APIKey:attr12345 APIMethods *constant AttributeSv1.Ping&AttributeSv1.GetAttributeForEvent&AttributeSv1.ProcessEvent false 20
7 cgrates.org ATTR_API_CHRG_AUTH *auth *string:~APIKey:chrg12345 APIMethods *constant ChargerSv1.Ping&ChargerSv1.GetChargersForEvent&ChargerSv1.ProcessEvent false 20
8 cgrates.org ATTR_API_THR_AUTH *auth *string:~APIKey:thr12345 APIMethods *constant ThresholdSv1.Ping&ThresholdSv1.GetThresholdsForEvent&ThresholdSv1.ProcessEvent&ThresholdSv1.GetThreshold&ThresholdSv1.GetThresholdIDs false 20
9 cgrates.org ATTR_API_SUP_AUTH *auth *string:~APIKey:sup12345 APIMethods *constant SupplierSv1.Ping&SupplierSv1.GetSuppliers SupplierSv1.Ping&SupplierSv1.GetSuppliers&SupplierSv1.GetSupplierForEvent false 20
10 cgrates.org ATTR_API_STAT_AUTH *auth *string:~APIKey:stat12345 APIMethods *constant StatSv1.Ping&StatSv1.GetStatQueuesForEvent&StatSv1.GetQueueStringMetrics&StatSv1.ProcessEvent&StatSv1.GetQueueIDs&StatSv1.GetQueueFloatMetrics false 20
11 cgrates.org ATTR_API_RES_AUTH *auth *string:~APIKey:res12345 APIMethods *constant ResourceSv1.Ping&ResourceSv1.GetResourcesForEvent&ResourceSv1.AuthorizeResources&ResourceSv1.AllocateResources&ResourceSv1.ReleaseResources false 20
12 cgrates.org ATTR_API_SES_AUTH *auth *string:~APIKey:ses12345 APIMethods *constant SessionSv1.Ping&SessionSv1.AuthorizeEvent&SessionSv1.AuthorizeEventWithDigest&SessionSv1.InitiateSession&SessionSv1.InitiateSessionWithDigest&SessionSv1.UpdateSession&SessionSv1.SyncSessions&SessionSv1.TerminateSession&SessionSv1.ProcessCDR&SessionSv1.ProcessEvent&SessionSv1.GetActiveSessions&SessionSv1.GetActiveSessionsCount&SessionSv1.ForceDisconnect&SessionSv1.GetPassiveSessions&SessionSv1.GetPassiveSessionsCount&SessionSv1.ReplicateSessions&SessionSv1.SetPassiveSession false 20

View File

@@ -53,3 +53,19 @@ func (dS *DispatcherService) SupplierSv1GetSuppliers(args *engine.ArgsGetSupplie
return dS.Dispatch(&args.CGREvent, utils.MetaSuppliers, args.RouteID,
utils.SupplierSv1GetSuppliers, args, reply)
}
func (dS *DispatcherService) SupplierSv1GetSupplierForEvent(args *utils.CGREventWithArgDispatcher,
reply *engine.SupplierProfile) (err error) {
if args.ArgDispatcher == nil {
return utils.NewErrMandatoryIeMissing("ArgDispatcher")
}
if dS.attrS != nil {
if err = dS.authorize(utils.SupplierSv1GetSupplierForEvent,
args.CGREvent.Tenant,
args.APIKey, args.CGREvent.Time); err != nil {
return
}
}
return dS.Dispatch(args.CGREvent, utils.MetaSuppliers, args.RouteID,
utils.SupplierSv1GetSupplierForEvent, args, reply)
}

View File

@@ -22,6 +22,7 @@ package dispatchers
import (
"reflect"
"sort"
"testing"
"time"
@@ -37,6 +38,7 @@ var sTestsDspSup = []func(t *testing.T){
testDspSupPing,
testDspSupTestAuthKey,
testDspSupTestAuthKey2,
testDspSupGetSupplierForEvent,
}
//Test start here
@@ -322,3 +324,71 @@ func testDspSupGetSupRoundRobin(t *testing.T) {
t.Errorf("Expecting : %+v, received: %+v", utils.ToJSON(eRpl), utils.ToJSON(rpl))
}
}
func testDspSupGetSupplierForEvent(t *testing.T) {
ev := &utils.CGREventWithArgDispatcher{
CGREvent: &utils.CGREvent{
Tenant: "cgrates.org",
ID: "testV1SplSGetHighestCostSuppliers",
Event: map[string]interface{}{
utils.Account: "1002",
utils.Subject: "1002",
utils.Destination: "1001",
utils.SetupTime: time.Date(2017, 12, 1, 14, 25, 0, 0, time.UTC),
utils.Usage: "1m20s",
},
},
ArgDispatcher: &utils.ArgDispatcher{
APIKey: utils.StringPointer("sup12345"),
},
}
expected := engine.SupplierProfile{
Tenant: "cgrates.org",
ID: "SPL_ACNT_1002",
FilterIDs: []string{"FLTR_ACNT_1002"},
ActivationInterval: &utils.ActivationInterval{
ActivationTime: time.Date(2017, 11, 27, 00, 00, 00, 00, time.UTC),
},
Sorting: "*least_cost",
SortingParameters: []string{},
Suppliers: []*engine.Supplier{
&engine.Supplier{
ID: "supplier1",
FilterIDs: nil,
AccountIDs: nil,
RatingPlanIDs: []string{"RP_1002_LOW"},
ResourceIDs: nil,
StatIDs: nil,
Weight: 10,
Blocker: false,
SupplierParameters: "",
},
&engine.Supplier{
ID: "supplier2",
FilterIDs: nil,
AccountIDs: nil,
RatingPlanIDs: []string{"RP_1002"},
ResourceIDs: nil,
StatIDs: nil,
Weight: 20,
Blocker: false,
SupplierParameters: "",
},
},
Weight: 10,
}
var supProf engine.SupplierProfile
if err := dispEngine.RCP.Call(utils.SupplierSv1GetSupplierForEvent,
ev, &supProf); err != nil {
t.Fatal(err)
}
sort.Slice(expected.Suppliers, func(i, j int) bool {
return supProf.Suppliers[i].Weight < supProf.Suppliers[j].Weight
})
sort.Slice(supProf.Suppliers, func(i, j int) bool {
return supProf.Suppliers[i].Weight < supProf.Suppliers[j].Weight
})
if !reflect.DeepEqual(expected, supProf) {
t.Errorf("Expected: %s ,received: %s", utils.ToJSON(expected), utils.ToJSON(supProf))
}
}

View File

@@ -469,7 +469,7 @@ type optsGetSuppliers struct {
sortingParameters []string //used for QOS strategy
}
// V1GetSuppliersForEvent returns the list of valid supplier IDs
// V1GetSupplierForEvent returns the list of valid supplier IDs
func (spS *SupplierService) V1GetSuppliers(args *ArgsGetSuppliers, reply *SortedSuppliers) (err error) {
if missing := utils.MissingStructFields(&args.CGREvent, []string{"Tenant", "ID"}); len(missing) != 0 {
return utils.NewErrMandatoryIeMissing(missing...)
@@ -500,3 +500,23 @@ func (spS *SupplierService) V1GetSuppliers(args *ArgsGetSuppliers, reply *Sorted
*reply = *sSps
return
}
// V1GetSupplierProfiles returns the list of valid supplier profiles
func (spS *SupplierService) V1GetSupplierForEvent(args *utils.CGREventWithArgDispatcher, reply *SupplierProfile) (err error) {
if missing := utils.MissingStructFields(args.CGREvent, []string{"Tenant", "ID"}); len(missing) != 0 {
return utils.NewErrMandatoryIeMissing(missing...)
} else if args.CGREvent.Event == nil {
return utils.NewErrMandatoryIeMissing("Event")
}
sPs, err := spS.matchingSupplierProfilesForEvent(args.CGREvent)
if err != nil {
if err != utils.ErrNotFound {
err = utils.NewErrServerError(err)
}
return err
}
if sPs != nil {
*reply = *sPs
}
return
}

View File

@@ -754,12 +754,13 @@ const (
// SupplierS APIs
const (
SupplierSv1GetSuppliers = "SupplierSv1.GetSuppliers"
SupplierSv1Ping = "SupplierSv1.Ping"
ApierV1GetSupplierProfile = "ApierV1.GetSupplierProfile"
ApierV1GetSupplierProfileIDs = "ApierV1.GetSupplierProfileIDs"
ApierV1RemoveSupplierProfile = "ApierV1.RemoveSupplierProfile"
ApierV1SetSupplierProfile = "ApierV1.SetSupplierProfile"
SupplierSv1GetSuppliers = "SupplierSv1.GetSuppliers"
SupplierSv1GetSupplierForEvent = "SupplierSv1.GetSupplierForEvent"
SupplierSv1Ping = "SupplierSv1.Ping"
ApierV1GetSupplierProfile = "ApierV1.GetSupplierProfile"
ApierV1GetSupplierProfileIDs = "ApierV1.GetSupplierProfileIDs"
ApierV1RemoveSupplierProfile = "ApierV1.RemoveSupplierProfile"
ApierV1SetSupplierProfile = "ApierV1.SetSupplierProfile"
)
// AttributeS APIs