added SetActionTrigger, GetActionTriggers

also added console commands an tests
fixes #415
This commit is contained in:
Radu Ioan Fericean
2016-04-02 15:45:17 +03:00
parent a2fd5116be
commit 7b5091c7d8
10 changed files with 259 additions and 50 deletions

View File

@@ -824,7 +824,7 @@ func (self *ApierV1) GetCacheStats(attrs utils.AttrCacheStats, reply *utils.Cach
}
if loadHistInsts, err := self.AccountDb.GetLoadHistory(1, false); err != nil || len(loadHistInsts) == 0 {
if err != nil { // Not really an error here since we only count in cache
utils.Logger.Err(fmt.Sprintf("ApierV1.GetCacheStats, error on GetLoadHistory: %s", err.Error()))
utils.Logger.Warning(fmt.Sprintf("ApierV1.GetCacheStats, error on GetLoadHistory: %s", err.Error()))
}
cs.LastLoadId = utils.NOT_AVAILABLE
cs.LastLoadTime = utils.NOT_AVAILABLE

View File

@@ -175,7 +175,7 @@ type AttrSetAccountActionTriggers struct {
MinSleep *string
ExpirationDate *string
ActivationDate *string
BalanceId *string
BalanceID *string
BalanceType *string
BalanceDirections *[]string
BalanceDestinationIds *[]string
@@ -188,7 +188,7 @@ type AttrSetAccountActionTriggers struct {
BalanceBlocker *bool
BalanceDisabled *bool
MinQueuedItems *int
ActionsId *string
ActionsID *string
}
func (self *ApierV1) SetAccountActionTriggers(attr AttrSetAccountActionTriggers, reply *string) error {
@@ -238,8 +238,9 @@ func (self *ApierV1) SetAccountActionTriggers(attr AttrSetAccountActionTriggers,
}
at.ActivationDate = actTime
}
if attr.BalanceId != nil {
at.Balance.ID = attr.BalanceId
at.Balance = &engine.BalanceFilter{}
if attr.BalanceID != nil {
at.Balance.ID = attr.BalanceID
}
if attr.BalanceType != nil {
at.Balance.Type = attr.BalanceType
@@ -281,8 +282,8 @@ func (self *ApierV1) SetAccountActionTriggers(attr AttrSetAccountActionTriggers,
if attr.MinQueuedItems != nil {
at.MinQueuedItems = *attr.MinQueuedItems
}
if attr.ActionsId != nil {
at.ActionsID = *attr.ActionsId
if attr.ActionsID != nil {
at.ActionsID = *attr.ActionsID
}
}
@@ -301,7 +302,7 @@ func (self *ApierV1) SetAccountActionTriggers(attr AttrSetAccountActionTriggers,
return nil
}
type AttrSetActionTriggers struct {
type AttrSetActionTrigger struct {
GroupID string
UniqueID string
ThresholdType *string
@@ -310,7 +311,7 @@ type AttrSetActionTriggers struct {
MinSleep *string
ExpirationDate *string
ActivationDate *string
BalanceId *string
BalanceID *string
BalanceType *string
BalanceDirections *[]string
BalanceDestinationIds *[]string
@@ -323,20 +324,16 @@ type AttrSetActionTriggers struct {
BalanceBlocker *bool
BalanceDisabled *bool
MinQueuedItems *int
ActionsId *string
ActionsID *string
}
func (self *ApierV1) SetActionTriggers(attr AttrSetAccountActionTriggers, reply *string) error {
func (self *ApierV1) SetActionTrigger(attr AttrSetActionTrigger, reply *string) error {
if missing := utils.MissingStructFields(&attr, []string{"GroupID"}); len(missing) != 0 {
return utils.NewErrMandatoryIeMissing(missing...)
}
atrs, err := self.RatingDb.GetActionTriggers(attr.GroupID)
if err != nil && err != utils.ErrNotFound {
*reply = err.Error()
return err
}
atrs, _ := self.RatingDb.GetActionTriggers(attr.GroupID)
var newAtr *engine.ActionTrigger
if attr.UniqueID != "" {
//search for exiting one
@@ -352,6 +349,12 @@ func (self *ApierV1) SetActionTriggers(attr AttrSetAccountActionTriggers, reply
newAtr = &engine.ActionTrigger{}
atrs = append(atrs, newAtr)
}
newAtr.ID = attr.GroupID
if attr.UniqueID != "" {
newAtr.UniqueID = attr.UniqueID
} else {
newAtr.UniqueID = utils.GenUUID()
}
if attr.ThresholdType != nil {
newAtr.ThresholdType = *attr.ThresholdType
@@ -386,8 +389,9 @@ func (self *ApierV1) SetActionTriggers(attr AttrSetAccountActionTriggers, reply
}
newAtr.ActivationDate = actTime
}
if attr.BalanceId != nil {
newAtr.Balance.ID = attr.BalanceId
newAtr.Balance = &engine.BalanceFilter{}
if attr.BalanceID != nil {
newAtr.Balance.ID = attr.BalanceID
}
if attr.BalanceType != nil {
newAtr.Balance.Type = attr.BalanceType
@@ -430,16 +434,47 @@ func (self *ApierV1) SetActionTriggers(attr AttrSetAccountActionTriggers, reply
if attr.MinQueuedItems != nil {
newAtr.MinQueuedItems = *attr.MinQueuedItems
}
if attr.ActionsId != nil {
newAtr.ActionsID = *attr.ActionsId
if attr.ActionsID != nil {
newAtr.ActionsID = *attr.ActionsID
}
if err := self.RatingDb.SetActionTriggers(attr.GroupID, atrs); err != nil {
*reply = err.Error()
return err
}
//cache action triggers
self.RatingDb.CacheRatingPrefixValues(map[string][]string{utils.ACTION_TRIGGER_PREFIX: []string{utils.ACTION_TRIGGER_PREFIX + attr.GroupID}})
//no cache for action triggers
*reply = utils.OK
return nil
}
type AttrGetActionTriggers struct {
GroupIDs []string
}
func (self *ApierV1) GetActionTriggers(attr AttrGetActionTriggers, atrs *engine.ActionTriggers) error {
var allAttrs engine.ActionTriggers
if len(attr.GroupIDs) > 0 {
for _, key := range attr.GroupIDs {
getAttrs, err := self.RatingDb.GetActionTriggers(key)
if err != nil {
return err
}
allAttrs = append(allAttrs, getAttrs...)
}
} else {
keys, err := self.RatingDb.GetKeysForPrefix(utils.ACTION_TRIGGER_PREFIX, true)
if err != nil {
return err
}
for _, key := range keys {
getAttrs, err := self.RatingDb.GetActionTriggers(key[len(utils.ACTION_TRIGGER_PREFIX):])
if err != nil {
return err
}
allAttrs = append(allAttrs, getAttrs...)
}
}
*atrs = allAttrs
return nil
}

View File

@@ -21,8 +21,8 @@ package console
import "github.com/cgrates/cgrates/apier/v1"
func init() {
c := &CmdAddTriggers{
name: "triggers_add",
c := &CmdAccountAddTriggers{
name: "account_triggers_add",
rpcMethod: "ApierV1.AddAccountActionTriggers",
rpcParams: &v1.AttrAddAccountActionTriggers{},
}
@@ -31,33 +31,33 @@ func init() {
}
// Commander implementation
type CmdAddTriggers struct {
type CmdAccountAddTriggers struct {
name string
rpcMethod string
rpcParams *v1.AttrAddAccountActionTriggers
*CommandExecuter
}
func (self *CmdAddTriggers) Name() string {
func (self *CmdAccountAddTriggers) Name() string {
return self.name
}
func (self *CmdAddTriggers) RpcMethod() string {
func (self *CmdAccountAddTriggers) RpcMethod() string {
return self.rpcMethod
}
func (self *CmdAddTriggers) RpcParams(reset bool) interface{} {
func (self *CmdAccountAddTriggers) RpcParams(reset bool) interface{} {
if reset || self.rpcParams == nil {
self.rpcParams = &v1.AttrAddAccountActionTriggers{}
}
return self.rpcParams
}
func (self *CmdAddTriggers) PostprocessRpcParams() error {
func (self *CmdAccountAddTriggers) PostprocessRpcParams() error {
return nil
}
func (self *CmdAddTriggers) RpcResult() interface{} {
func (self *CmdAccountAddTriggers) RpcResult() interface{} {
var s string
return &s
}

View File

@@ -21,8 +21,8 @@ package console
import "github.com/cgrates/cgrates/apier/v1"
func init() {
c := &CmdRemoveTriggers{
name: "triggers_remove",
c := &CmdAccountRemoveTriggers{
name: "account_triggers_remove",
rpcMethod: "ApierV1.RemoveAccountActionTriggers",
rpcParams: &v1.AttrRemoveAccountActionTriggers{},
}
@@ -31,33 +31,33 @@ func init() {
}
// Commander implementation
type CmdRemoveTriggers struct {
type CmdAccountRemoveTriggers struct {
name string
rpcMethod string
rpcParams *v1.AttrRemoveAccountActionTriggers
*CommandExecuter
}
func (self *CmdRemoveTriggers) Name() string {
func (self *CmdAccountRemoveTriggers) Name() string {
return self.name
}
func (self *CmdRemoveTriggers) RpcMethod() string {
func (self *CmdAccountRemoveTriggers) RpcMethod() string {
return self.rpcMethod
}
func (self *CmdRemoveTriggers) RpcParams(reset bool) interface{} {
func (self *CmdAccountRemoveTriggers) RpcParams(reset bool) interface{} {
if reset || self.rpcParams == nil {
self.rpcParams = &v1.AttrRemoveAccountActionTriggers{}
}
return self.rpcParams
}
func (self *CmdRemoveTriggers) PostprocessRpcParams() error {
func (self *CmdAccountRemoveTriggers) PostprocessRpcParams() error {
return nil
}
func (self *CmdRemoveTriggers) RpcResult() interface{} {
func (self *CmdAccountRemoveTriggers) RpcResult() interface{} {
var s string
return &s
}

View File

@@ -21,8 +21,8 @@ package console
import "github.com/cgrates/cgrates/apier/v1"
func init() {
c := &CmdResetTriggers{
name: "triggers_reset",
c := &CmdAccountResetTriggers{
name: "account_triggers_reset",
rpcMethod: "ApierV1.ResetAccountActionTriggers",
rpcParams: &v1.AttrRemoveAccountActionTriggers{},
}
@@ -31,33 +31,33 @@ func init() {
}
// Commander implementation
type CmdResetTriggers struct {
type CmdAccountResetTriggers struct {
name string
rpcMethod string
rpcParams *v1.AttrRemoveAccountActionTriggers
*CommandExecuter
}
func (self *CmdResetTriggers) Name() string {
func (self *CmdAccountResetTriggers) Name() string {
return self.name
}
func (self *CmdResetTriggers) RpcMethod() string {
func (self *CmdAccountResetTriggers) RpcMethod() string {
return self.rpcMethod
}
func (self *CmdResetTriggers) RpcParams(reset bool) interface{} {
func (self *CmdAccountResetTriggers) RpcParams(reset bool) interface{} {
if reset || self.rpcParams == nil {
self.rpcParams = &v1.AttrRemoveAccountActionTriggers{}
}
return self.rpcParams
}
func (self *CmdResetTriggers) PostprocessRpcParams() error {
func (self *CmdAccountResetTriggers) PostprocessRpcParams() error {
return nil
}
func (self *CmdResetTriggers) RpcResult() interface{} {
func (self *CmdAccountResetTriggers) RpcResult() interface{} {
var s string
return &s
}

View File

@@ -0,0 +1,63 @@
/*
Rating system designed to be used in VoIP Carriers World
Copyright (C) 2012-2015 ITsysCOM
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/apier/v1"
func init() {
c := &CmdAccountSetTriggers{
name: "account_triggers_set",
rpcMethod: "ApierV1.SetAccountActionTriggers",
rpcParams: &v1.AttrSetAccountActionTriggers{},
}
commands[c.Name()] = c
c.CommandExecuter = &CommandExecuter{c}
}
// Commander implementation
type CmdAccountSetTriggers struct {
name string
rpcMethod string
rpcParams *v1.AttrSetAccountActionTriggers
*CommandExecuter
}
func (self *CmdAccountSetTriggers) Name() string {
return self.name
}
func (self *CmdAccountSetTriggers) RpcMethod() string {
return self.rpcMethod
}
func (self *CmdAccountSetTriggers) RpcParams(reset bool) interface{} {
if reset || self.rpcParams == nil {
self.rpcParams = &v1.AttrSetAccountActionTriggers{}
}
return self.rpcParams
}
func (self *CmdAccountSetTriggers) PostprocessRpcParams() error {
return nil
}
func (self *CmdAccountSetTriggers) RpcResult() interface{} {
var s string
return &s
}

View File

@@ -23,8 +23,8 @@ import "github.com/cgrates/cgrates/apier/v1"
func init() {
c := &CmdSetTriggers{
name: "triggers_set",
rpcMethod: "ApierV1.SetAccountActionTriggers",
rpcParams: &v1.AttrSetAccountActionTriggers{},
rpcMethod: "ApierV1.SetActionTrigger",
rpcParams: &v1.AttrSetActionTrigger{},
}
commands[c.Name()] = c
c.CommandExecuter = &CommandExecuter{c}
@@ -34,7 +34,7 @@ func init() {
type CmdSetTriggers struct {
name string
rpcMethod string
rpcParams *v1.AttrSetAccountActionTriggers
rpcParams *v1.AttrSetActionTrigger
*CommandExecuter
}
@@ -48,7 +48,7 @@ func (self *CmdSetTriggers) RpcMethod() string {
func (self *CmdSetTriggers) RpcParams(reset bool) interface{} {
if reset || self.rpcParams == nil {
self.rpcParams = &v1.AttrSetAccountActionTriggers{}
self.rpcParams = &v1.AttrSetActionTrigger{}
}
return self.rpcParams
}

66
console/triggers.go Normal file
View File

@@ -0,0 +1,66 @@
/*
Rating system designed to be used in VoIP Carriers World
Copyright (C) 2012-2015 ITsysCOM
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/apier/v1"
"github.com/cgrates/cgrates/engine"
)
func init() {
c := &CmdGetTriggers{
name: "triggers",
rpcMethod: "ApierV1.GetActionTriggers",
rpcParams: &v1.AttrGetActionTriggers{},
}
commands[c.Name()] = c
c.CommandExecuter = &CommandExecuter{c}
}
// Commander implementation
type CmdGetTriggers struct {
name string
rpcMethod string
rpcParams *v1.AttrGetActionTriggers
*CommandExecuter
}
func (self *CmdGetTriggers) Name() string {
return self.name
}
func (self *CmdGetTriggers) RpcMethod() string {
return self.rpcMethod
}
func (self *CmdGetTriggers) RpcParams(reset bool) interface{} {
if reset || self.rpcParams == nil {
self.rpcParams = &v1.AttrGetActionTriggers{}
}
return self.rpcParams
}
func (self *CmdGetTriggers) PostprocessRpcParams() error {
return nil
}
func (self *CmdGetTriggers) RpcResult() interface{} {
atr := engine.ActionTriggers{}
return &atr
}

View File

@@ -310,6 +310,12 @@ func (ms *MongoStorage) GetKeysForPrefix(prefix string, skipCache bool) ([]strin
result = append(result, utils.ACTION_PLAN_PREFIX+keyResult.Key)
}
return result, nil
case utils.ACTION_TRIGGER_PREFIX:
iter := ms.db.C(colAtr).Find(bson.M{"key": bson.M{"$regex": bson.RegEx{Pattern: subject}}}).Select(bson.M{"key": 1}).Iter()
for iter.Next(&keyResult) {
result = append(result, utils.ACTION_TRIGGER_PREFIX+keyResult.Key)
}
return result, nil
case utils.ACCOUNT_PREFIX:
iter := ms.db.C(colAcc).Find(bson.M{"id": bson.M{"$regex": bson.RegEx{Pattern: subject}}}).Select(bson.M{"id": 1}).Iter()
for iter.Next(&idResult) {

View File

@@ -7,6 +7,7 @@ import (
"testing"
"time"
"github.com/cgrates/cgrates/apier/v1"
"github.com/cgrates/cgrates/config"
"github.com/cgrates/cgrates/engine"
"github.com/cgrates/cgrates/utils"
@@ -117,3 +118,41 @@ func TestTpBalanceCounter(t *testing.T) {
t.Errorf("Calling ApierV2.GetBalance received: %s", utils.ToIJSON(acnt))
}
}
func TestTpActionTriggers(t *testing.T) {
if !*testIntegration {
return
}
var atrs engine.ActionTriggers
if err := tpRPC.Call("ApierV1.GetActionTriggers", v1.AttrGetActionTriggers{GroupIDs: []string{}}, &atrs); err != nil {
t.Error("Got error on ApierV1.GetActionTriggers: ", err.Error())
} else if len(atrs) != 9 {
t.Errorf("Calling v1.GetActionTriggers got: %v", atrs)
}
var reply string
if err := tpRPC.Call("ApierV1.SetActionTrigger", v1.AttrSetActionTrigger{
GroupID: "TestATR",
UniqueID: "Unique atr id",
BalanceID: utils.StringPointer("BID1"),
}, &reply); err != nil {
t.Error("Got error on ApierV1.SetActionTrigger: ", err.Error())
} else if reply != utils.OK {
t.Errorf("Calling v1.SetActionTrigger got: %v", reply)
}
if err := tpRPC.Call("ApierV1.GetActionTriggers", v1.AttrGetActionTriggers{GroupIDs: []string{}}, &atrs); err != nil {
t.Error("Got error on ApierV1.GetActionTriggers: ", err.Error())
} else if len(atrs) != 10 {
t.Errorf("Calling v1.GetActionTriggers got: %v", atrs)
}
if err := tpRPC.Call("ApierV1.GetActionTriggers", v1.AttrGetActionTriggers{GroupIDs: []string{"TestATR"}}, &atrs); err != nil {
t.Error("Got error on ApierV1.GetActionTriggers: ", err.Error())
} else if len(atrs) != 1 {
t.Errorf("Calling v1.GetActionTriggers got: %v", atrs)
}
if atrs[0].ID != "TestATR" ||
atrs[0].UniqueID != "Unique atr id" ||
*atrs[0].Balance.ID != "BID1" {
t.Error("Wrong action trigger set: ", utils.ToIJSON(atrs[0]))
}
}