From 7b5091c7d82339aa4c344c0c87ee1337aca36df1 Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Sat, 2 Apr 2016 15:45:17 +0300 Subject: [PATCH] added SetActionTrigger, GetActionTriggers also added console commands an tests fixes #415 --- apier/v1/apier.go | 2 +- apier/v1/triggers.go | 77 ++++++++++++++----- ...{trigger_add.go => account_trigger_add.go} | 16 ++-- ...er_remove.go => account_trigger_remove.go} | 16 ++-- ...gger_reset.go => account_trigger_reset.go} | 16 ++-- console/account_trigger_set.go | 63 +++++++++++++++ console/trigger_set.go | 8 +- console/triggers.go | 66 ++++++++++++++++ engine/storage_mongo_datadb.go | 6 ++ general_tests/tp_it_test.go | 39 ++++++++++ 10 files changed, 259 insertions(+), 50 deletions(-) rename console/{trigger_add.go => account_trigger_add.go} (76%) rename console/{trigger_remove.go => account_trigger_remove.go} (75%) rename console/{trigger_reset.go => account_trigger_reset.go} (75%) create mode 100644 console/account_trigger_set.go create mode 100644 console/triggers.go diff --git a/apier/v1/apier.go b/apier/v1/apier.go index 9afe5cf63..b6abf47f0 100644 --- a/apier/v1/apier.go +++ b/apier/v1/apier.go @@ -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 diff --git a/apier/v1/triggers.go b/apier/v1/triggers.go index 23b22bd06..b6c6a3f5f 100644 --- a/apier/v1/triggers.go +++ b/apier/v1/triggers.go @@ -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 +} diff --git a/console/trigger_add.go b/console/account_trigger_add.go similarity index 76% rename from console/trigger_add.go rename to console/account_trigger_add.go index bef41f910..3577aee9f 100644 --- a/console/trigger_add.go +++ b/console/account_trigger_add.go @@ -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 } diff --git a/console/trigger_remove.go b/console/account_trigger_remove.go similarity index 75% rename from console/trigger_remove.go rename to console/account_trigger_remove.go index a460d8528..5d2739692 100644 --- a/console/trigger_remove.go +++ b/console/account_trigger_remove.go @@ -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 } diff --git a/console/trigger_reset.go b/console/account_trigger_reset.go similarity index 75% rename from console/trigger_reset.go rename to console/account_trigger_reset.go index 0d5be9f24..d545361db 100644 --- a/console/trigger_reset.go +++ b/console/account_trigger_reset.go @@ -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 } diff --git a/console/account_trigger_set.go b/console/account_trigger_set.go new file mode 100644 index 000000000..84ed47079 --- /dev/null +++ b/console/account_trigger_set.go @@ -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 +*/ + +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 +} diff --git a/console/trigger_set.go b/console/trigger_set.go index 2e9095d95..e1a72dd67 100644 --- a/console/trigger_set.go +++ b/console/trigger_set.go @@ -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 } diff --git a/console/triggers.go b/console/triggers.go new file mode 100644 index 000000000..454d4994c --- /dev/null +++ b/console/triggers.go @@ -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 +*/ + +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 +} diff --git a/engine/storage_mongo_datadb.go b/engine/storage_mongo_datadb.go index 84503d7a1..51abc1989 100644 --- a/engine/storage_mongo_datadb.go +++ b/engine/storage_mongo_datadb.go @@ -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) { diff --git a/general_tests/tp_it_test.go b/general_tests/tp_it_test.go index 3eef405e1..237015a7b 100644 --- a/general_tests/tp_it_test.go +++ b/general_tests/tp_it_test.go @@ -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])) + } +}