Apier: AddAccount -> SetAccount

This commit is contained in:
DanB
2014-01-10 12:51:37 +01:00
parent f393b600d4
commit 9f125e638f
5 changed files with 100 additions and 72 deletions

View File

@@ -78,7 +78,7 @@ func (self *ApierV1) RemActionTiming(attrs AttrRemActionTiming, reply *string) e
return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing)
}
}
_, err := engine.AccLock.Guard(engine.ACTION_TIMING_PREFIX, func() (float64, error) { // ToDo: Expand the scheduler to consider the locks also
_, err := engine.AccLock.Guard(engine.ACTION_TIMING_PREFIX, func() (float64, error) {
ats, err := self.AccountDb.GetActionTimings(attrs.ActionTimingsId)
if err != nil {
return 0, err
@@ -154,3 +154,73 @@ func (self *ApierV1) RemAccountActionTriggers(attrs AttrRemAcntActionTriggers, r
*reply = OK
return nil
}
type AttrSetAccount struct {
Tenant string
Direction string
Account string
Type string // <*prepaid|*postpaid>
ActionTimingsId string
}
// Ads a new account into dataDb. If already defined, returns success.
func (self *ApierV1) SetAccount(attr AttrSetAccount, reply *string) error {
if missing := utils.MissingStructFields(&attr, []string{"Tenant", "Direction", "Account"}); len(missing) != 0 {
return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing)
}
balanceId := utils.BalanceKey(attr.Tenant, attr.Account, attr.Direction)
var ub *engine.UserBalance
var ats engine.ActionTimings
_, err := engine.AccLock.Guard(balanceId, func() (float64, error) {
if bal, _ := self.AccountDb.GetUserBalance(balanceId); bal != nil {
ub = bal
} else { // Not found in db, create it here
if len(attr.Type) == 0 {
attr.Type = engine.UB_TYPE_PREPAID
} else if !utils.IsSliceMember([]string{engine.UB_TYPE_POSTPAID, engine.UB_TYPE_PREPAID}, attr.Type) {
return 0, fmt.Errorf("%s:%s", utils.ERR_MANDATORY_IE_MISSING, "Type")
}
ub = &engine.UserBalance{
Id: balanceId,
Type: attr.Type,
}
}
if len(attr.ActionTimingsId) != 0 {
var err error
ats, err = self.AccountDb.GetActionTimings(attr.ActionTimingsId)
if err != nil {
return 0, err
}
for _, at := range ats {
at.UserBalanceIds = append(at.UserBalanceIds, balanceId)
}
}
// All prepared, save account
if err := self.AccountDb.SetUserBalance(ub); err != nil {
return 0, err
}
return 0, nil
})
if err != nil {
return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
}
if len(ats) != 0 {
_, err := engine.AccLock.Guard(engine.ACTION_TIMING_PREFIX, func() (float64, error) { // ToDo: Try locking it above on read somehow
if err := self.AccountDb.SetActionTimings(attr.ActionTimingsId, ats); err != nil {
return 0, err
}
return 0, nil
})
if err != nil {
return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
}
if self.Sched != nil {
self.Sched.LoadActionTimings(self.AccountDb)
self.Sched.Restart()
}
}
*reply = OK // This will mark saving of the account, error still can show up in actionTimingsId
return nil
}

View File

@@ -403,49 +403,6 @@ func (self *ApierV1) AddTriggeredAction(attr AttrAddActionTrigger, reply *string
return nil
}
type AttrAddAccount struct {
Tenant string
Direction string
Account string
Type string // prepaid-postpaid
ActionTimingsId string
}
// Ads a new account into dataDb. If already defined, returns success.
func (self *ApierV1) AddAccount(attr AttrAddAccount, reply *string) error {
if missing := utils.MissingStructFields(&attr, []string{"Tenant", "Direction", "Account", "Type", "ActionTimingsId"}); len(missing) != 0 {
return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing)
}
tag := utils.BalanceKey(attr.Tenant, attr.Account, attr.Direction)
ub := &engine.UserBalance{
Id: tag,
Type: attr.Type,
}
if attr.ActionTimingsId != "" {
if ats, err := self.AccountDb.GetActionTimings(attr.ActionTimingsId); err == nil {
for _, at := range ats {
engine.Logger.Debug(fmt.Sprintf("Found action timings: %v", at))
at.UserBalanceIds = append(at.UserBalanceIds, tag)
}
err = self.AccountDb.SetActionTimings(attr.ActionTimingsId, ats)
if err != nil {
if self.Sched != nil {
self.Sched.LoadActionTimings(self.AccountDb)
self.Sched.Restart()
}
}
if err := self.AccountDb.SetUserBalance(ub); err != nil {
return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
}
} else {
return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
}
}
*reply = OK
return nil
}
// Process dependencies and load a specific AccountActions profile from storDb into dataDb.
func (self *ApierV1) LoadAccountActions(attrs utils.TPAccountActions, reply *string) error {
if missing := utils.MissingStructFields(&attrs, []string{"TPid", "LoadId", "Tenant", "Account", "Direction"}); len(missing) != 0 {

View File

@@ -1062,35 +1062,36 @@ func TestApierRemAccountActionTriggers(t *testing.T) {
}
// Test here AddAccount
func TestApierAddAccount(t *testing.T) {
if !*testLocal {
return
}
reply := ""
attrs := &AttrAddAccount{Tenant: "cgrates.org", Direction: "*out", Account: "dan4", Type: "prepaid", ActionTimingsId: "ATMS_1"}
if err := rater.Call("ApierV1.AddAccount", attrs, &reply); err != nil {
t.Error("Got error on ApierV1.AddAccount: ", err.Error())
} else if reply != "OK" {
t.Errorf("Calling ApierV1.AddAccount received: %s", reply)
}
reply2 := ""
attrs2 := new(AttrAddAccount)
*attrs2 = *attrs
attrs2.ActionTimingsId = "DUMMY_DATA" // Does not exist so it should error when adding triggers on it
// Add account with actions timing which does not exist
if err := rater.Call("ApierV1.AddAccount", attrs2, &reply2); err == nil || reply2 == "OK" {
t.Error("Expecting error on ApierV1.AddAccount.", err, reply2)
}
// Test here SetAccount
func TestApierSetAccount(t *testing.T) {
if !*testLocal {
return
}
reply := ""
attrs := &AttrSetAccount{Tenant: "cgrates.org", Direction: "*out", Account: "dan7", Type: "*prepaid", ActionTimingsId: "ATMS_1"}
if err := rater.Call("ApierV1.SetAccount", attrs, &reply); err != nil {
t.Error("Got error on ApierV1.SetAccount: ", err.Error())
} else if reply != "OK" {
t.Errorf("Calling ApierV1.SetAccount received: %s", reply)
}
reply2 := ""
attrs2 := new(AttrSetAccount)
*attrs2 = *attrs
attrs2.ActionTimingsId = "DUMMY_DATA" // Does not exist so it should error when adding triggers on it
// Add account with actions timing which does not exist
if err := rater.Call("ApierV1.SetAccount", attrs2, &reply2); err == nil || reply2 == "OK" { // OK is not welcomed
t.Error("Expecting error on ApierV1.SetAccount.", err, reply2)
}
}
// Test here GetAccountActionTimings
func TestApierGetAccountActionTimings(t *testing.T) {
if !*testLocal {
return
}
var reply []*AccountActionTiming
req := AttrAcntAction{Tenant: "cgrates.org", Account:"dan4", Direction: "*out"}
req := AttrAcntAction{Tenant: "cgrates.org", Account:"dan7", Direction: "*out"}
if err := rater.Call("ApierV1.GetAccountActionTimings", req, &reply); err != nil {
t.Error("Got error on ApierV1.GetAccountActionTimings: ", err.Error())
} else if len(reply) != 1 {

View File

@@ -30,7 +30,7 @@ func init() {
// Commander implementation
type CmdAddAccount struct {
rpcMethod string
rpcParams *apier.AttrAddAccount
rpcParams *apier.AttrSetAccount
rpcResult string
}
@@ -41,8 +41,8 @@ func (self *CmdAddAccount) Usage(name string) string {
// set param defaults
func (self *CmdAddAccount) defaults() error {
self.rpcMethod = "ApierV1.AddAccount"
self.rpcParams = &apier.AttrAddAccount{Direction: "*out"}
self.rpcMethod = "ApierV1.SetAccount"
self.rpcParams = &apier.AttrSetAccount{Direction: "*out"}
return nil
}

View File

@@ -326,21 +326,21 @@ AddTriggeredAction
Example
AddTriggeredAction(attr \*AttrAddActionTrigger, reply \*float64)
AddAcount
SetAcount
+++++++++
::
type AttrAddAccount struct {
type AttrSetAccount struct {
Tenant string
Direction string
Account string
Type string // prepaid-postpaid
Type string // <*prepaid|*postpaid>
ActionTimingsId string
}
Example
AddAccount(attr \*AttrAddAccount, reply \*float64)
AddAccount(attr \*AttrAddAccount, reply \*string)