ApierV2.GetAccounts

This commit is contained in:
DanB
2015-02-06 13:24:51 +01:00
parent 8576d8f6fc
commit ff68023ca5
5 changed files with 185 additions and 13 deletions

View File

@@ -1,6 +1,6 @@
/*
Real-time Charging System for Telecom & ISP environments
Copyright (C) 2012-2014 ITsysCOM GmbH
Copyright (C) ITsysCOM GmbH
This program is free software: you can Storagetribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -20,6 +20,8 @@ package v2
import (
"github.com/cgrates/cgrates/engine"
"github.com/cgrates/cgrates/utils"
"strings"
)
type AttrGetAccountIds struct {
@@ -40,3 +42,51 @@ func (self *ApierV2) GetAccountIds(attrs AttrGetAccountIds, reply *[]string) err
*reply = accountKeys
return nil
}
type AttrGetAccounts struct {
Tenant string
Account string
Offset int // Set the item offset
Limit int // Limit number of items retrieved
}
func (self *ApierV2) GetAccounts(attr AttrGetAccounts, reply *[]*engine.Account) error {
searchKeyPrefix := engine.ACCOUNT_PREFIX + utils.OUT + ":"
if len(attr.Tenant) != 0 { // ToDO: Update here as soon as redis 2.8 becomes last supported platform
searchKeyPrefix += attr.Tenant + ":"
if len(attr.Account) != 0 {
searchKeyPrefix += attr.Account
}
}
accountKeys, err := self.AccountDb.GetKeysForPrefix(searchKeyPrefix)
if err != nil {
return err
} else if len(accountKeys) == 0 {
return nil
}
if len(attr.Tenant) == 0 && len(attr.Account) != 0 { // Since redis version lower than 2.8 does not support masked searches in middle, we filter records out here
filteredAccounts := make([]string, 0)
for _, acntKey := range accountKeys {
if strings.HasSuffix(acntKey, ":"+attr.Account) {
filteredAccounts = append(filteredAccounts, acntKey)
}
}
accountKeys = filteredAccounts
}
var limitedAccounts []string
if attr.Limit != 0 {
limitedAccounts = accountKeys[attr.Offset : attr.Offset+attr.Limit]
} else {
limitedAccounts = accountKeys[attr.Offset:]
}
retAccounts := make([]*engine.Account, len(limitedAccounts))
for idx, acntKey := range limitedAccounts {
retAccounts[idx], err = self.AccountDb.GetAccount(acntKey[len(engine.ACCOUNT_PREFIX):])
if err != nil {
return err
}
}
*reply = retAccounts
return nil
}

117
apier/v2/accounts_test.go Normal file
View File

@@ -0,0 +1,117 @@
/*
Real-time Charging System for Telecom & ISP environments
Copyright (C) ITsysCOM GmbH
This program is free software: you can Storagetribute 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 WITH*out 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 v2
import (
"github.com/cgrates/cgrates/apier/v1"
"github.com/cgrates/cgrates/config"
"github.com/cgrates/cgrates/engine"
"github.com/cgrates/cgrates/utils"
"testing"
)
var (
apierAcnts *ApierV2
apierAcntsAcntStorage *engine.MapStorage
)
func init() {
apierAcntsAcntStorage, _ = engine.NewMapStorage()
cfg, _ := config.NewDefaultCGRConfig()
apierAcnts = &ApierV2{v1.ApierV1{AccountDb: engine.AccountingStorage(apierAcntsAcntStorage), Config: cfg}}
}
func TestSetAccounts(t *testing.T) {
cgrTenant := "cgrates.org"
iscTenant := "itsyscom.com"
b10 := &engine.Balance{Value: 10, Weight: 10}
cgrAcnt1 := &engine.Account{Id: utils.ConcatenatedKey(utils.OUT, cgrTenant, "account1"),
BalanceMap: map[string]engine.BalanceChain{engine.CREDIT + engine.OUTBOUND: engine.BalanceChain{b10}}}
cgrAcnt2 := &engine.Account{Id: utils.ConcatenatedKey(utils.OUT, cgrTenant, "account2"),
BalanceMap: map[string]engine.BalanceChain{engine.CREDIT + engine.OUTBOUND: engine.BalanceChain{b10}}}
cgrAcnt3 := &engine.Account{Id: utils.ConcatenatedKey(utils.OUT, cgrTenant, "account3"),
BalanceMap: map[string]engine.BalanceChain{engine.CREDIT + engine.OUTBOUND: engine.BalanceChain{b10}}}
iscAcnt1 := &engine.Account{Id: utils.ConcatenatedKey(utils.OUT, iscTenant, "account1"),
BalanceMap: map[string]engine.BalanceChain{engine.CREDIT + engine.OUTBOUND: engine.BalanceChain{b10}}}
iscAcnt2 := &engine.Account{Id: utils.ConcatenatedKey(utils.OUT, iscTenant, "account2"),
BalanceMap: map[string]engine.BalanceChain{engine.CREDIT + engine.OUTBOUND: engine.BalanceChain{b10}}}
for _, account := range []*engine.Account{cgrAcnt1, cgrAcnt2, cgrAcnt3, iscAcnt1, iscAcnt2} {
if err := apierAcntsAcntStorage.SetAccount(account); err != nil {
t.Error(err)
}
}
noReload := []string{}
apierAcntsAcntStorage.CacheAccounting(nil, noReload, noReload, noReload)
}
func TestGetAccountIds(t *testing.T) {
var accountIds []string
var attrs AttrGetAccountIds
if err := apierAcnts.GetAccountIds(attrs, &accountIds); err != nil {
t.Error("Unexpected error", err.Error())
} else if len(accountIds) != 5 {
t.Errorf("Accounts returned: %+v", accountIds)
}
}
func TestGetAccounts(t *testing.T) {
var accounts []*engine.Account
var attrs AttrGetAccounts
if err := apierAcnts.GetAccounts(attrs, &accounts); err != nil {
t.Error("Unexpected error", err.Error())
} else if len(accounts) != 5 {
t.Errorf("Accounts returned: %+v", accounts)
}
attrs = AttrGetAccounts{Tenant: "itsyscom.com"}
if err := apierAcnts.GetAccounts(attrs, &accounts); err != nil {
t.Error("Unexpected error", err.Error())
} else if len(accounts) != 2 {
t.Errorf("Accounts returned: %+v", accounts)
}
attrs = AttrGetAccounts{Tenant: "cgrates.org", Account: "account1"}
if err := apierAcnts.GetAccounts(attrs, &accounts); err != nil {
t.Error("Unexpected error", err.Error())
} else if len(accounts) != 1 {
t.Errorf("Accounts returned: %+v", accounts)
}
attrs = AttrGetAccounts{Account: "account1"}
if err := apierAcnts.GetAccounts(attrs, &accounts); err != nil {
t.Error("Unexpected error", err.Error())
} else if len(accounts) != 2 {
t.Errorf("Accounts returned: %+v", accounts)
}
attrs = AttrGetAccounts{Account: "account3"}
if err := apierAcnts.GetAccounts(attrs, &accounts); err != nil {
t.Error("Unexpected error", err.Error())
} else if len(accounts) != 1 {
t.Errorf("Accounts returned: %+v", accounts)
}
attrs = AttrGetAccounts{Account: "INVALID"}
if err := apierAcnts.GetAccounts(attrs, &accounts); err != nil {
t.Error("Unexpected error", err.Error())
} else if len(accounts) != 0 {
t.Errorf("Accounts returned: %+v", accounts)
}
attrs = AttrGetAccounts{Tenant: "INVALID"}
if err := apierAcnts.GetAccounts(attrs, &accounts); err != nil {
t.Error("Unexpected error", err.Error())
} else if len(accounts) != 0 {
t.Errorf("Accounts returned: %+v", accounts)
}
}

View File

@@ -52,8 +52,14 @@ func (ms *MapStorage) Flush(ignore string) error {
return nil
}
func (ms *MapStorage) GetKeysForPrefix(string) ([]string, error) {
return nil, nil
func (ms *MapStorage) GetKeysForPrefix(prefix string) ([]string, error) {
keysForPrefix := make([]string, 0)
for key := range ms.dict {
if strings.HasPrefix(key, prefix) {
keysForPrefix = append(keysForPrefix, key)
}
}
return keysForPrefix, nil
}
func (ms *MapStorage) CacheRating(dKeys, rpKeys, rpfKeys, alsKeys, lcrKeys []string) error {

View File

@@ -959,17 +959,16 @@ func (self *SQLStorage) GetStoredCdrs(qryFltr *utils.CdrsFilter) ([]*utils.Store
if qryFltr.PaginatorLimit != 0 {
q = q.Limit(qryFltr.PaginatorLimit)
}
/* ToDo: Fix as soon as issue on Gorm analyzed: https://github.com/jinzhu/gorm/issues/354
if qryFltr.Count {
var cnt int64
fmt.Printf("Rows is: %+v\n", rows)
//fmt.Printf("Counting, got count: %+v\n", q.Count())
if err := q.Count(&cnt).Error; err != nil {
fmt.Printf("Counting, got error %s", err.Error())
return nil, 0, err
/*
// ToDo: Fix as soon as issue on Gorm analyzed: https://github.com/jinzhu/gorm/issues/354
if qryFltr.Count {
var cnt int64
//if err := q.Count(&cnt).Error; err != nil {
if err := q.Debug().Count(&cnt).Error; err != nil {
return nil, 0, err
}
return nil, cnt, nil
}
return nil, cnt, nil
}
*/
// Execute query
rows, err := q.Rows()