mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-12 02:26:26 +05:00
Adding *resources type for FilterS
This commit is contained in:
committed by
Dan Christian Bogos
parent
a37cd65587
commit
2360aee3d1
@@ -57,7 +57,21 @@ func (rsv1 *ResourceSv1) ReleaseResources(args utils.ArgRSv1ResourceUsage, reply
|
||||
return rsv1.rls.V1ReleaseResource(args, reply)
|
||||
}
|
||||
|
||||
//func for getResource
|
||||
// GetResource returns a resource configuration
|
||||
func (apierV1 *ApierV1) GetResource(arg utils.TenantID, reply *engine.Resource) error {
|
||||
if missing := utils.MissingStructFields(&arg, []string{"Tenant", "ID"}); len(missing) != 0 { //Params missing
|
||||
return utils.NewErrMandatoryIeMissing(missing...)
|
||||
}
|
||||
if res, err := apierV1.DataManager.GetResource(arg.Tenant, arg.ID, true, true, utils.NonTransactional); err != nil {
|
||||
if err.Error() != utils.ErrNotFound.Error() {
|
||||
err = utils.NewErrServerError(err)
|
||||
}
|
||||
return err
|
||||
} else {
|
||||
*reply = *res
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetResourceProfile returns a resource configuration
|
||||
func (apierV1 *ApierV1) GetResourceProfile(arg utils.TenantID, reply *engine.ResourceProfile) error {
|
||||
|
||||
@@ -481,7 +481,7 @@ func (fltr *FilterRule) passStatS(dP config.DataProvider,
|
||||
for key, val := range statValues {
|
||||
ifaceStatValues[key] = val
|
||||
}
|
||||
//convert convert into a NavigableMap so we can send it to passGreaterThan
|
||||
//convert ifaceStatValues into a NavigableMap so we can send it to passGreaterThan
|
||||
nM := config.NewNavigableMap(ifaceStatValues)
|
||||
//split the type in exact 2 parts
|
||||
//special cases like *gt#sum#Usage
|
||||
@@ -538,17 +538,30 @@ func (fltr *FilterRule) passResourceS(dP config.DataProvider,
|
||||
if resourceS == nil || reflect.ValueOf(resourceS).IsNil() {
|
||||
return false, errors.New("Missing ResourceS information")
|
||||
}
|
||||
// for _, resItem := range fltr.resourceItems {
|
||||
// //take total usage for resource
|
||||
|
||||
// //compose the newFilter
|
||||
|
||||
// //send it to passGreaterThan
|
||||
// // if val, err := fltr.passGreaterThan(nM); err != nil || !val {
|
||||
// // //in case of error return false and error
|
||||
// // //and in case of not pass return false and nil
|
||||
// // return false, err
|
||||
// // }
|
||||
// }
|
||||
for _, resItem := range fltr.resourceItems {
|
||||
//take total usage for resource
|
||||
var reply *Resource
|
||||
if err := resourceS.Call(utils.ApierV1GetResource,
|
||||
&utils.TenantID{Tenant: tenant, ID: resItem.ItemID}, &reply); err != nil {
|
||||
return false, err
|
||||
}
|
||||
data := map[string]interface{}{
|
||||
utils.Usage: reply.totalUsage(),
|
||||
}
|
||||
//convert data into a NavigableMap so we can send it to passGreaterThan
|
||||
nM := config.NewNavigableMap(data)
|
||||
//compose the newFilter
|
||||
fltr, err := NewFilterRule(resItem.FilterType,
|
||||
utils.Usage, []string{resItem.FilterValue})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
// send it to passGreaterThan
|
||||
if val, err := fltr.passGreaterThan(nM); err != nil || !val {
|
||||
//in case of error return false and error
|
||||
//and in case of not pass return false and nil
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ var sTestsFltr = []func(t *testing.T){
|
||||
testV1FltrPupulateThreshold,
|
||||
testV1FltrGetThresholdForEvent,
|
||||
testV1FltrGetThresholdForEvent2,
|
||||
testV1FltrPopulateResources,
|
||||
testV1FltrStopEngine,
|
||||
}
|
||||
|
||||
@@ -276,7 +277,6 @@ func testV1FltrPupulateThreshold(t *testing.T) {
|
||||
},
|
||||
MaxHits: -1,
|
||||
MinSleep: time.Duration(1 * time.Millisecond),
|
||||
Blocker: false,
|
||||
Weight: 10.0,
|
||||
ActionIDs: []string{"LOG"},
|
||||
Async: true,
|
||||
@@ -344,10 +344,8 @@ func testV1FltrGetThresholdForEvent2(t *testing.T) {
|
||||
},
|
||||
MaxHits: -1,
|
||||
MinSleep: time.Duration(1 * time.Millisecond),
|
||||
Blocker: false,
|
||||
Weight: 10.0,
|
||||
ActionIDs: []string{"LOG"},
|
||||
Async: true,
|
||||
}
|
||||
if err := fltrRpc.Call("ApierV1.SetThresholdProfile", tPrfl, &result); err != nil {
|
||||
t.Error(err)
|
||||
@@ -368,6 +366,149 @@ func testV1FltrGetThresholdForEvent2(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func testV1FltrPopulateResources(t *testing.T) {
|
||||
//create a resourceProfile
|
||||
rlsConfig := &engine.ResourceProfile{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "ResTest",
|
||||
ActivationInterval: &utils.ActivationInterval{
|
||||
ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),
|
||||
ExpiryTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),
|
||||
},
|
||||
UsageTTL: time.Duration(1) * time.Minute,
|
||||
Limit: 10,
|
||||
AllocationMessage: "MessageAllocation",
|
||||
Stored: true,
|
||||
Weight: 20,
|
||||
ThresholdIDs: []string{utils.META_NONE},
|
||||
}
|
||||
|
||||
var result string
|
||||
if err := fltrRpc.Call("ApierV1.SetResourceProfile", rlsConfig, &result); err != nil {
|
||||
t.Error(err)
|
||||
} else if result != utils.OK {
|
||||
t.Error("Unexpected reply returned", result)
|
||||
}
|
||||
|
||||
var reply *engine.ResourceProfile
|
||||
if err := fltrRpc.Call("ApierV1.GetResourceProfile",
|
||||
&utils.TenantID{Tenant: "cgrates.org", ID: rlsConfig.ID}, &reply); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(reply, rlsConfig) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(rlsConfig), utils.ToJSON(reply))
|
||||
}
|
||||
|
||||
// Allocate 3 units for resource ResTest
|
||||
argsRU := utils.ArgRSv1ResourceUsage{
|
||||
CGREvent: utils.CGREvent{
|
||||
Tenant: "cgrates.org",
|
||||
Event: map[string]interface{}{
|
||||
"Account": "3001",
|
||||
"Destination": "3002"},
|
||||
},
|
||||
UsageID: "651a8db2-4f67-4cf8-b622-169e8a482e21",
|
||||
Units: 3,
|
||||
}
|
||||
if err := fltrRpc.Call(utils.ResourceSv1AllocateResources,
|
||||
argsRU, &result); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
//we allocate 3 units to resource and add a filter for Usages > 2
|
||||
//should match (3>2)
|
||||
filter := &engine.Filter{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "FLTR_TH_Resource",
|
||||
Rules: []*engine.FilterRule{
|
||||
{
|
||||
Type: "*resources",
|
||||
Values: []string{"*gt:ResTest:2.0"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if err := fltrRpc.Call("ApierV1.SetFilter", filter, &result); err != nil {
|
||||
t.Error(err)
|
||||
} else if result != utils.OK {
|
||||
t.Error("Unexpected reply returned", result)
|
||||
}
|
||||
|
||||
tPrfl := &engine.ThresholdProfile{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "TH_ResTest",
|
||||
FilterIDs: []string{"FLTR_TH_Resource", "*string:Account:2020"},
|
||||
ActivationInterval: &utils.ActivationInterval{
|
||||
ActivationTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC),
|
||||
ExpiryTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC),
|
||||
},
|
||||
MaxHits: -1,
|
||||
MinSleep: time.Duration(1 * time.Millisecond),
|
||||
Weight: 10.0,
|
||||
ActionIDs: []string{"LOG"},
|
||||
Async: true,
|
||||
}
|
||||
if err := fltrRpc.Call("ApierV1.SetThresholdProfile", tPrfl, &result); err != nil {
|
||||
t.Error(err)
|
||||
} else if result != utils.OK {
|
||||
t.Error("Unexpected reply returned", result)
|
||||
}
|
||||
var rcvTh *engine.ThresholdProfile
|
||||
if err := fltrRpc.Call("ApierV1.GetThresholdProfile",
|
||||
&utils.TenantID{Tenant: tPrfl.Tenant, ID: tPrfl.ID}, &rcvTh); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(tPrfl, rcvTh) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", tPrfl, rcvTh)
|
||||
}
|
||||
|
||||
// check the event
|
||||
tEv := utils.CGREvent{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "event1",
|
||||
Event: map[string]interface{}{
|
||||
utils.Account: "2020"},
|
||||
}
|
||||
var ids []string
|
||||
eIDs := []string{"TH_ResTest"}
|
||||
if err := fltrRpc.Call(utils.ThresholdSv1ProcessEvent, tEv, &ids); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(ids, eIDs) {
|
||||
t.Errorf("Expecting ids: %s, received: %s", eIDs, ids)
|
||||
}
|
||||
|
||||
//change the filter
|
||||
//we allocate 3 units to resource and add a filter for Usages < 2
|
||||
//should fail (3<2)
|
||||
filter = &engine.Filter{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "FLTR_TH_Resource",
|
||||
Rules: []*engine.FilterRule{
|
||||
{
|
||||
Type: "*resources",
|
||||
Values: []string{"*lt:ResTest:2.0"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if err := fltrRpc.Call("ApierV1.SetFilter", filter, &result); err != nil {
|
||||
t.Error(err)
|
||||
} else if result != utils.OK {
|
||||
t.Error("Unexpected reply returned", result)
|
||||
}
|
||||
|
||||
//Overwrite the threshold
|
||||
if err := fltrRpc.Call("ApierV1.SetThresholdProfile", tPrfl, &result); err != nil {
|
||||
t.Error(err)
|
||||
} else if result != utils.OK {
|
||||
t.Error("Unexpected reply returned", result)
|
||||
}
|
||||
|
||||
//expect NotFound error because filter doesn't match
|
||||
if err := fltrRpc.Call(utils.ThresholdSv1ProcessEvent, tEv, &ids); err == nil ||
|
||||
err.Error() != utils.ErrNotFound.Error() {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func testV1FltrStopEngine(t *testing.T) {
|
||||
if err := engine.KillEngine(accDelay); err != nil {
|
||||
t.Error(err)
|
||||
|
||||
@@ -695,6 +695,7 @@ const (
|
||||
ApierV1SetDispatcherProfile = "ApierV1.SetDispatcherProfile"
|
||||
ApierV1GetDispatcherProfile = "ApierV1.GetDispatcherProfile"
|
||||
ApierV1RemoveDispatcherProfile = "ApierV1.RemoveDispatcherProfile"
|
||||
ApierV1GetResource = "ApierV1.GetResource"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
Reference in New Issue
Block a user