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/apier_local_test.go b/apier/v1/apier_local_test.go index cfa76e271..002d95e43 100644 --- a/apier/v1/apier_local_test.go +++ b/apier/v1/apier_local_test.go @@ -1295,8 +1295,8 @@ func TestApierResetDataAfterLoadFromFolder(t *testing.T) { t.Error("Got error on ApierV1.GetCacheStats: ", err.Error()) } else { if rcvStats.Destinations != 5 || - rcvStats.RatingPlans != 4 || - rcvStats.RatingProfiles != 4 || + rcvStats.RatingPlans != 5 || + rcvStats.RatingProfiles != 5 || rcvStats.Actions != 8 || rcvStats.DerivedChargers != 3 { t.Errorf("Calling ApierV1.GetCacheStats received: %+v", rcvStats) diff --git a/apier/v1/triggers.go b/apier/v1/triggers.go index 642c137c7..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 } } @@ -300,3 +301,180 @@ func (self *ApierV1) SetAccountActionTriggers(attr AttrSetAccountActionTriggers, *reply = utils.OK return nil } + +type AttrSetActionTrigger struct { + GroupID string + UniqueID string + ThresholdType *string + ThresholdValue *float64 + Recurrent *bool + MinSleep *string + ExpirationDate *string + ActivationDate *string + BalanceID *string + BalanceType *string + BalanceDirections *[]string + BalanceDestinationIds *[]string + BalanceWeight *float64 + BalanceExpirationDate *string + BalanceTimingTags *[]string + BalanceRatingSubject *string + BalanceCategories *[]string + BalanceSharedGroups *[]string + BalanceBlocker *bool + BalanceDisabled *bool + MinQueuedItems *int + ActionsID *string +} + +func (self *ApierV1) SetActionTrigger(attr AttrSetActionTrigger, reply *string) error { + + if missing := utils.MissingStructFields(&attr, []string{"GroupID"}); len(missing) != 0 { + return utils.NewErrMandatoryIeMissing(missing...) + } + + atrs, _ := self.RatingDb.GetActionTriggers(attr.GroupID) + var newAtr *engine.ActionTrigger + if attr.UniqueID != "" { + //search for exiting one + for _, atr := range atrs { + if atr.UniqueID == attr.UniqueID { + newAtr = atr + break + } + } + } + + if newAtr == nil { + 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 + } + if attr.ThresholdValue != nil { + newAtr.ThresholdValue = *attr.ThresholdValue + } + if attr.Recurrent != nil { + newAtr.Recurrent = *attr.Recurrent + } + if attr.MinSleep != nil { + minSleep, err := utils.ParseDurationWithSecs(*attr.MinSleep) + if err != nil { + *reply = err.Error() + return err + } + newAtr.MinSleep = minSleep + } + if attr.ExpirationDate != nil { + expTime, err := utils.ParseTimeDetectLayout(*attr.ExpirationDate, self.Config.DefaultTimezone) + if err != nil { + *reply = err.Error() + return err + } + newAtr.ExpirationDate = expTime + } + if attr.ActivationDate != nil { + actTime, err := utils.ParseTimeDetectLayout(*attr.ActivationDate, self.Config.DefaultTimezone) + if err != nil { + *reply = err.Error() + return err + } + newAtr.ActivationDate = actTime + } + newAtr.Balance = &engine.BalanceFilter{} + if attr.BalanceID != nil { + newAtr.Balance.ID = attr.BalanceID + } + if attr.BalanceType != nil { + newAtr.Balance.Type = attr.BalanceType + } + if attr.BalanceDirections != nil { + newAtr.Balance.Directions = utils.StringMapPointer(utils.NewStringMap(*attr.BalanceDirections...)) + } + if attr.BalanceDestinationIds != nil { + newAtr.Balance.DestinationIDs = utils.StringMapPointer(utils.NewStringMap(*attr.BalanceDestinationIds...)) + } + if attr.BalanceWeight != nil { + newAtr.Balance.Weight = attr.BalanceWeight + } + if attr.BalanceExpirationDate != nil { + balanceExpTime, err := utils.ParseDate(*attr.BalanceExpirationDate) + if err != nil { + *reply = err.Error() + return err + } + newAtr.Balance.ExpirationDate = &balanceExpTime + } + if attr.BalanceTimingTags != nil { + newAtr.Balance.TimingIDs = utils.StringMapPointer(utils.NewStringMap(*attr.BalanceTimingTags...)) + } + if attr.BalanceRatingSubject != nil { + newAtr.Balance.RatingSubject = attr.BalanceRatingSubject + } + if attr.BalanceCategories != nil { + newAtr.Balance.Categories = utils.StringMapPointer(utils.NewStringMap(*attr.BalanceCategories...)) + } + if attr.BalanceSharedGroups != nil { + newAtr.Balance.SharedGroups = utils.StringMapPointer(utils.NewStringMap(*attr.BalanceSharedGroups...)) + } + if attr.BalanceBlocker != nil { + newAtr.Balance.Blocker = attr.BalanceBlocker + } + if attr.BalanceDisabled != nil { + newAtr.Balance.Disabled = attr.BalanceDisabled + } + if attr.MinQueuedItems != nil { + newAtr.MinQueuedItems = *attr.MinQueuedItems + } + if attr.ActionsID != nil { + newAtr.ActionsID = *attr.ActionsID + } + + if err := self.RatingDb.SetActionTriggers(attr.GroupID, atrs); err != nil { + *reply = err.Error() + return err + } + //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/data/docker/devel/Dockerfile b/data/docker/devel/Dockerfile index 47e251317..ea0a8b803 100644 --- a/data/docker/devel/Dockerfile +++ b/data/docker/devel/Dockerfile @@ -17,7 +17,7 @@ RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv EA312927 RUN echo 'deb http://repo.mongodb.org/apt/debian wheezy/mongodb-org/3.2 main' | tee '/etc/apt/sources.list.d/mongodb-org-3.2.list' # install dependencies -RUN apt-get -y update && apt-get -y install git bzr mercurial redis-server mysql-server python-pycurl python-mysqldb postgresql postgresql-client sudo wget freeswitch-meta-vanilla vim zsh mongodb-org +RUN apt-get -y update && apt-get -y install git bzr mercurial redis-server mysql-server python-pycurl python-mysqldb postgresql postgresql-client sudo wget freeswitch-meta-vanilla vim zsh mongodb-org tmux rsyslog # add mongo conf COPY mongod.conf /etc/mongod.conf @@ -34,6 +34,9 @@ RUN GOROOT=/root/go GOPATH=/root/code /root/go/bin/go get github.com/Masterminds #install oh-my-zsh RUN TERM=xterm sh -c "$(wget https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O -)"; exit 0 +# change shell for tmux +RUN chsh -s /usr/bin/zsh + # cleanup RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* diff --git a/data/docker/devel/start.sh b/data/docker/devel/start.sh index ac7992663..0a4a75591 100755 --- a/data/docker/devel/start.sh +++ b/data/docker/devel/start.sh @@ -2,6 +2,7 @@ sed -i 's/127.0.0.1/0.0.0.0/g' /etc/redis/redis.conf /etc/mysql/my.cnf echo 'host all all 0.0.0.0/32 md5'>>/etc/postgresql/9.4/main/pg_hba.conf +/etc/init.d/rsyslog start /etc/init.d/mysql start /etc/init.d/postgresql start /etc/init.d/redis-server start diff --git a/data/tariffplans/testtp/AccountActions.csv b/data/tariffplans/testtp/AccountActions.csv index d04a5bde4..fc5722aa3 100644 --- a/data/tariffplans/testtp/AccountActions.csv +++ b/data/tariffplans/testtp/AccountActions.csv @@ -7,3 +7,4 @@ cgrates.org,1005,PREPAID_10,STANDARD_TRIGGERS,, cgrates.org,1009,TEST_EXE,,, cgrates.org,1010,TEST_DATA_r,,true, cgrates.org,1011,TEST_VOICE,,, +cgrates.org,1012,PREPAID_10,,, diff --git a/data/tariffplans/testtp/DestinationRates.csv b/data/tariffplans/testtp/DestinationRates.csv index 9be903aef..2f51c5c18 100644 --- a/data/tariffplans/testtp/DestinationRates.csv +++ b/data/tariffplans/testtp/DestinationRates.csv @@ -3,4 +3,5 @@ DR_RETAIL,GERMANY,RT_1CENT,*up,4,0, DR_RETAIL,GERMANY_MOBILE,RT_1CENT,*up,4,0, DR_DATA_1,*any,RT_DATA_2c,*up,4,0, DR_SMS_1,*any,RT_SMS_5c,*up,4,0, -DR_DATA_r,DATA_DEST,RT_DATA_r,*up,5,0, \ No newline at end of file +DR_DATA_r,DATA_DEST,RT_DATA_r,*up,5,0, +DR_FREE,GERMANY,RT_ZERO,*middle,2,0, diff --git a/data/tariffplans/testtp/Rates.csv b/data/tariffplans/testtp/Rates.csv index 21c9abc4a..b8860104b 100644 --- a/data/tariffplans/testtp/Rates.csv +++ b/data/tariffplans/testtp/Rates.csv @@ -3,3 +3,4 @@ RT_1CENT,0,1,1s,1s,0s RT_DATA_2c,0,0.002,10,10,0 RT_SMS_5c,0,0.005,1,1,0 RT_DATA_r,0,0.1,1048576,10240,0 +RT_ZERO,0,0,1,1,0 diff --git a/data/tariffplans/testtp/RatingPlans.csv b/data/tariffplans/testtp/RatingPlans.csv index f7003dcf4..5be68df5d 100644 --- a/data/tariffplans/testtp/RatingPlans.csv +++ b/data/tariffplans/testtp/RatingPlans.csv @@ -3,3 +3,4 @@ RP_RETAIL,DR_RETAIL,ALWAYS,10 RP_DATA1,DR_DATA_1,ALWAYS,10 RP_SMS1,DR_SMS_1,ALWAYS,10 RP_DATAr,DR_DATA_r,ALWAYS,10 +RP_FREE,DR_FREE,ALWAYS,10 diff --git a/data/tariffplans/testtp/RatingProfiles.csv b/data/tariffplans/testtp/RatingProfiles.csv index ffa6bf2f6..3a6a28222 100644 --- a/data/tariffplans/testtp/RatingProfiles.csv +++ b/data/tariffplans/testtp/RatingProfiles.csv @@ -3,3 +3,4 @@ *out,cgrates.org,data,*any,2012-01-01T00:00:00Z,RP_DATA1,, *out,cgrates.org,sms,*any,2012-01-01T00:00:00Z,RP_SMS1,, *out,cgrates.org,data,datar,2016-01-01T00:00:00Z,RP_DATAr,, +*out,cgrates.org,call,free,2016-01-01T00:00:00Z,RP_FREE,, 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..cbea917f3 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" @@ -106,7 +107,7 @@ func TestTpBalanceCounter(t *testing.T) { var cc engine.CallCost if err := tpRPC.Call("Responder.Debit", cd, &cc); err != nil { t.Error("Got error on Responder.GetCost: ", err.Error()) - } else if cc.GetDuration() == 20 { + } else if cc.GetDuration() != 20*time.Second { t.Errorf("Calling Responder.MaxDebit got callcost: %v", cc.GetDuration()) } var acnt *engine.Account @@ -117,3 +118,72 @@ 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])) + } +} + +func TestTpZeroCost(t *testing.T) { + if !*testIntegration { + return + } + tStart := time.Date(2016, 3, 31, 0, 0, 0, 0, time.UTC) + cd := engine.CallDescriptor{ + Direction: "*out", + Category: "call", + Tenant: "cgrates.org", + Subject: "free", + Account: "1012", + Destination: "+49", + DurationIndex: 0, + TimeStart: tStart, + TimeEnd: tStart.Add(time.Duration(20) * time.Second), + } + var cc engine.CallCost + if err := tpRPC.Call("Responder.Debit", cd, &cc); err != nil { + t.Error("Got error on Responder.GetCost: ", err.Error()) + } else if cc.GetDuration() != 20*time.Second { + t.Errorf("Calling Responder.MaxDebit got callcost: %v", utils.ToIJSON(cc)) + } + var acnt *engine.Account + attrs := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1012"} + if err := tpRPC.Call("ApierV2.GetAccount", attrs, &acnt); err != nil { + t.Error("Got error on ApierV2.GetAccount: ", err.Error()) + } else if acnt.BalanceMap[utils.MONETARY][0].Value != 11.0 { + t.Errorf("Calling ApierV2.GetAccount received: %s", utils.ToIJSON(acnt)) + } +} diff --git a/packages/squeeze/rules b/packages/squeeze/rules index b813db9c6..34115a611 100755 --- a/packages/squeeze/rules +++ b/packages/squeeze/rules @@ -5,7 +5,6 @@ export DH_VERBOSE=1 export GOPATH=$(CURDIR) -export GO15VENDOREXPERIMENT=1 PKGDIR=debian/cgrates SRCDIR=src/github.com/cgrates/cgrates @@ -24,8 +23,8 @@ binary-arch: clean dh_installdirs mkdir -p src/github.com/cgrates ln -sf $(CURDIR) src/github.com/cgrates - go get -v github.com/Masterminds/glide - $(GOPATH)/bin/glide install + go get -u -v github.com/Masterminds/glide + $(GOPATH)/bin/glide install --force exec $(CURDIR)/build.sh mkdir -p $(PKGDIR)/usr/bin cp $(GOPATH)/bin/cgr-* $(PKGDIR)/usr/bin/