fixes and tests for lcr

This commit is contained in:
Radu Ioan Fericean
2015-04-06 18:30:40 +03:00
parent 4cc9789871
commit 25a1858eac
9 changed files with 67 additions and 26 deletions

View File

@@ -246,10 +246,10 @@ CREATE TABLE `tp_account_actions` (
DROP TABLE IF EXISTS tp_lcr_rules;
CREATE TABLE tp_lcr_rules (
`id` int(11) NOT NULL AUTO_INCREMENT,
`tpid` varchar(64) NOT NULL,
`tenant` varchar(64) NOT NULL,
`category` varchar(32) NOT NULL,
`tpid` varchar(64) NOT NULL,
`direction` varchar(8) NOT NULL,
`tenant` varchar(64) NOT NULL,
`category` varchar(32) NOT NULL,
`account` varchar(24) NOT NULL,
`subject` varchar(64) NOT NULL,
`destination_tag` varchar(64) NOT NULL,

View File

@@ -241,10 +241,10 @@ CREATE INDEX tpaccountactions_idx ON tp_account_actions (tpid,loadid,tenant,acco
DROP TABLE IF EXISTS tp_lcr_rules;
CREATE TABLE tp_lcr_rules (
id SERIAL PRIMARY KEY,
tpid VARCHAR(64) NOT NULL,
tenant VARCHAR(64) NOT NULL,
category VARCHAR(32) NOT NULL,
tpid VARCHAR(64) NOT NULL,
direction VARCHAR(8) NOT NULL,
tenant VARCHAR(64) NOT NULL,
category VARCHAR(32) NOT NULL,
account VARCHAR(24) NOT NULL,
subject VARCHAR(64) NOT NULL,
destination_tag VARCHAR(64) NOT NULL,

View File

@@ -292,10 +292,6 @@ func (cd *CallDescriptor) GetAccountKey() string {
return utils.ConcatenatedKey(cd.Direction, cd.Tenant, subj)
}
func (cd *CallDescriptor) GetLCRKey(subj string) string {
return utils.ConcatenatedKey(cd.Direction, cd.Tenant, cd.Category, cd.Account, cd.Subject)
}
// Splits the received timespan into sub time spans according to the activation periods intervals.
func (cd *CallDescriptor) splitInTimeSpans() (timespans []*TimeSpan) {
firstSpan := &TimeSpan{TimeStart: cd.TimeStart, TimeEnd: cd.TimeEnd, DurationIndex: cd.DurationIndex}
@@ -657,19 +653,35 @@ func (cd *CallDescriptor) Clone() *CallDescriptor {
}
}
func (cd *CallDescriptor) GetLCR(stats StatsInterface) (LCRCost, error) {
lcr, err := dataStorage.GetLCR(cd.GetLCRKey(""), false)
if err != nil || lcr == nil {
// try the *any customer
if lcr, err = dataStorage.GetLCR(cd.GetLCRKey(utils.ANY), false); err != nil || lcr == nil {
func (cd *CallDescriptor) GetLCRFromStorage() (*LCR, error) {
keyVariants := []string{
utils.LCRKey(cd.Direction, cd.Tenant, cd.Category, cd.Account, cd.Subject),
utils.LCRKey(cd.Direction, cd.Tenant, cd.Category, cd.Account, utils.ANY),
utils.LCRKey(cd.Direction, cd.Tenant, cd.Category, utils.ANY, utils.ANY),
utils.LCRKey(cd.Direction, cd.Tenant, utils.ANY, utils.ANY, utils.ANY),
utils.LCRKey(cd.Direction, utils.ANY, utils.ANY, utils.ANY, utils.ANY),
}
for _, key := range keyVariants {
if lcr, err := dataStorage.GetLCR(key, false); err != nil && err.Error() != utils.ERR_NOT_FOUND {
return nil, err
} else if err == nil {
return lcr, nil
}
}
return nil, errors.New(utils.ERR_NOT_FOUND)
}
func (cd *CallDescriptor) GetLCR(stats StatsInterface) (LCRCost, error) {
lcr, err := cd.GetLCRFromStorage()
if err != nil {
return nil, err
}
lcr.Sort()
lcrCost := LCRCost{&LCRTimeSpan{StartTime: cd.TimeStart}}
for _, lcrActivation := range lcr.Activations {
// TODO: filer entry by destination
//log.Printf("Activation: %+v", lcrActivation)
lcrEntry := lcrActivation.GetLCREntryForPrefix(cd.Destination)
//log.Printf("Entry: %+v", lcrEntry)
if lcrActivation.ActivationTime.Before(cd.TimeStart) ||
lcrActivation.ActivationTime.Equal(cd.TimeStart) {
lcrCost[0].Entry = lcrEntry
@@ -684,6 +696,11 @@ func (cd *CallDescriptor) GetLCR(stats StatsInterface) (LCRCost, error) {
}
}
for _, ts := range lcrCost {
//log.Printf("TS: %+v", ts)
if ts.Entry == nil {
continue
}
//log.Printf("Entry: %+v", ts.Entry)
if ts.Entry.Strategy == LCR_STRATEGY_STATIC {
for _, supplier := range ts.Entry.GetParams() {
lcrCD := cd.Clone()
@@ -707,7 +724,7 @@ func (cd *CallDescriptor) GetLCR(stats StatsInterface) (LCRCost, error) {
} else {
// find rating profiles
ratingProfileSearchKey := utils.ConcatenatedKey(lcr.Direction, lcr.Tenant, ts.Entry.RPCategory)
suppliers := cache2go.GetEntriesKeys(LCR_PREFIX + ratingProfileSearchKey)
suppliers := cache2go.GetEntriesKeys(RATING_PROFILE_PREFIX + ratingProfileSearchKey)
for _, supplier := range suppliers {
split := strings.Split(supplier, ":")
supplier = split[len(split)-1]

View File

@@ -37,9 +37,9 @@ const (
)
type LCR struct {
Direction string
Tenant string
Category string
Direction string
Account string
Subject string
Activations []*LCRActivation
@@ -74,7 +74,7 @@ type LCRSupplierCost struct {
}
func (lcr *LCR) GetId() string {
return utils.ConcatenatedKey(lcr.Direction, lcr.Tenant, lcr.Category, lcr.Account, lcr.Subject)
return utils.LCRKey(lcr.Direction, lcr.Tenant, lcr.Category, lcr.Account, lcr.Subject)
}
func (lcr *LCR) Len() int {
@@ -155,8 +155,10 @@ func (lcra *LCRActivation) GetLCREntryForPrefix(destination string) *LCREntry {
var potentials LCREntriesSorter
for _, p := range utils.SplitPrefix(destination, MIN_PREFIX_MATCH) {
if x, err := cache2go.GetCached(DESTINATION_PREFIX + p); err == nil {
destIds := x.([]string)
for _, dId := range destIds {
destIds := x.(map[interface{}]struct{})
for idId := range destIds {
dId := idId.(string)
for _, entry := range lcra.Entries {
if entry.DestinationId == dId {
entry.precision = len(p)

View File

@@ -170,3 +170,20 @@ func TestLcrGetQosSortParamsFull(t *testing.T) {
t.Error("Wrong qos sort params parsed: ", sort)
}
}
func TestLcrGet(t *testing.T) {
cd := &CallDescriptor{
TimeStart: time.Date(2015, 04, 06, 17, 40, 0, 0, time.UTC),
TimeEnd: time.Date(2015, 04, 06, 17, 41, 0, 0, time.UTC),
Tenant: "cgrates.org",
Direction: "*in",
Category: "call",
Destination: "0723098765",
Account: "rif",
Subject: "rif",
}
lcrs, err := cd.GetLCR(nil)
if err != nil || len(lcrs) != 1 {
t.Errorf("Bad lcr: %+v, %v", lcrs, err)
}
}

View File

@@ -610,7 +610,7 @@ func (csvr *CSVReader) LoadLCRs() (err error) {
}
for record, err := csvReader.Read(); err == nil; record, err = csvReader.Read() {
tenant, category, direction, account, subject := record[0], record[1], record[2], record[3], record[4]
id := utils.ConcatenatedKey(direction, tenant, category, account, subject)
id := utils.LCRKey(direction, tenant, category, account, subject)
lcr, found := csvr.lcrs[id]
activationTime, err := utils.ParseTimeDetectLayout(record[9])
if err != nil {

View File

@@ -128,6 +128,7 @@ func (rp *RatingProfile) GetRatingPlansForPrefix(cd *CallDescriptor) (err error)
} else {
for _, p := range utils.SplitPrefix(cd.Destination, MIN_PREFIX_MATCH) {
if x, err := cache2go.GetCached(DESTINATION_PREFIX + p); err == nil {
destIds := x.(map[interface{}]struct{})
for idId := range destIds {
dId := idId.(string)

View File

@@ -1500,19 +1500,19 @@ func (self *SQLStorage) GetTpLCRs(tpid, tag string) (map[string]*LCR, error) {
defer rows.Close()
for rows.Next() {
var id int
var tpid, tenant, category, direction, account, subject, destinationId, rpCategory, strategy, strategyParams, suppliers, activationTimeString string
var tpid, direction, tenant, category, account, subject, destinationId, rpCategory, strategy, strategyParams, suppliers, activationTimeString string
var weight float64
if err := rows.Scan(&id, &tpid, &tenant, &category, &direction, &account, &subject, &destinationId, &rpCategory, &strategy, &strategyParams, &suppliers, &activationTimeString, &weight); err != nil {
if err := rows.Scan(&id, &tpid, &direction, &tenant, &category, &account, &subject, &destinationId, &rpCategory, &strategy, &strategyParams, &suppliers, &activationTimeString, &weight); err != nil {
return nil, err
}
tag := utils.ConcatenatedKey(direction, tenant, category, account, subject)
tag := utils.LCRKey(direction, tenant, category, account, subject)
lcr, found := lcrs[tag]
activationTime, _ := utils.ParseTimeDetectLayout(activationTimeString)
if !found {
lcr = &LCR{
Direction: direction,
Tenant: tenant,
Category: category,
Direction: direction,
Account: account,
Subject: subject,
}

View File

@@ -259,6 +259,10 @@ func ConcatenatedKey(keyVals ...string) string {
return strings.Join(keyVals, CONCATENATED_KEY_SEP)
}
func LCRKey(direction, tenant, category, account, subject string) string {
return ConcatenatedKey(direction, tenant, category, account, subject)
}
func RatingSubjectAliasKey(tenant, subject string) string {
return ConcatenatedKey(tenant, subject)
}