new lcr structure

This commit is contained in:
Radu Ioan Fericean
2015-03-31 18:25:06 +03:00
parent 60754e86c0
commit 66abb755cb
8 changed files with 74 additions and 64 deletions

View File

@@ -244,14 +244,16 @@ 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,
`direction` varchar(8) NOT NULL,
`tpid` varchar(64) NOT NULL,
`tenant` varchar(64) NOT NULL,
`customer` varchar(64) NOT NULL,
`destination_tag` varchar(64) NOT NULL,
`category` varchar(32) NOT NULL,
`direction` varchar(8) NOT NULL,
`account` varchar(24) NOT NULL,
`subject` varchar(64) NOT NULL,
`destination_tag` varchar(64) NOT NULL,
`rp_category` varchar(32) NOT NULL,
`strategy` varchar(16) NOT NULL,
`suppliers` varchar(64) NOT NULL,
`strategy_params` varchar(256) NOT NULL,
`activation_time` varchar(24) NOT NULL,
`weight` DECIMAL(8,2) NOT NULL,
`created_at` TIMESTAMP,

View File

@@ -229,14 +229,16 @@ 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,
direction VARCHAR(8) NOT NULL,
tpid VARCHAR(64) NOT NULL,
tenant VARCHAR(64) NOT NULL,
customer VARCHAR(64) NOT NULL,
destination_tag VARCHAR(64) NOT NULL,
category VARCHAR(32) NOT NULL,
direction VARCHAR(8) NOT NULL,
account VARCHAR(24) NOT NULL,
subject VARCHAR(64) NOT NULL,
destination_tag VARCHAR(64) NOT NULL,
rp_category VARCHAR(32) NOT NULL,
strategy VARCHAR(16) NOT NULL,
suppliers VARCHAR(64) NOT NULL,
strategy_params VARCHAR(256) NOT NULL,
activation_time VARCHAR(24) NOT NULL,
weight NUMERIC(8,2) NOT NULL,
created_at TIMESTAMP

View File

@@ -692,8 +692,8 @@ func (cd *CallDescriptor) GetLCR() (*LCRCost, error) {
}
for _, ts := range lcrCost.TimeSpans {
if ts.Entry.Strategy == LCR_STRATEGY_STATIC {
for _, supplier := range strings.Split(ts.Entry.Suppliers, ";") {
supplier = strings.TrimSpace(supplier)
for _, param := range strings.Split(ts.Entry.StrategyParams, ";") {
supplier := strings.TrimSpace(param)
lcrCD := cd.Clone()
lcrCD.Subject = supplier
if cc, err := lcrCD.GetCost(); err != nil || cc == nil {
@@ -710,7 +710,7 @@ func (cd *CallDescriptor) GetLCR() (*LCRCost, error) {
}
} else {
// find rating profiles
ratingProfileSearchKey := fmt.Sprintf("%s:%s:%s:", lcr.Direction, lcr.Tenant, ts.Entry.Category)
ratingProfileSearchKey := fmt.Sprintf("%s:%s:%s:", lcr.Direction, lcr.Tenant, ts.Entry.RPCategory)
suppliers := cache2go.GetEntriesKeys(LCR_PREFIX + ratingProfileSearchKey)
for _, supplier := range suppliers {
split := strings.Split(supplier, ":")

View File

@@ -19,7 +19,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
package engine
import (
"fmt"
"sort"
"time"
@@ -34,9 +33,11 @@ const (
)
type LCR struct {
Direction string
Tenant string
Customer string
Category string
Direction string
Account string
Subject string
Activations []*LCRActivation
}
type LCRActivation struct {
@@ -44,12 +45,12 @@ type LCRActivation struct {
Entries []*LCREntry
}
type LCREntry struct {
DestinationId string
Category string
Strategy string
Suppliers string
Weight float64
precision int
DestinationId string
RPCategory string
Strategy string
StrategyParams string
Weight float64
precision int
}
type LCRCost struct {
@@ -69,7 +70,7 @@ type LCRSupplierCost struct {
}
func (lcr *LCR) GetId() string {
return fmt.Sprintf("%s:%s:%s", lcr.Direction, lcr.Tenant, lcr.Customer)
return utils.ConcatenatedKey(lcr.Direction, lcr.Tenant, lcr.Category, lcr.Account, lcr.Subject)
}
func (lcr *LCR) Len() int {

View File

@@ -608,22 +608,24 @@ func (csvr *CSVReader) LoadLCRs() (err error) {
defer fp.Close()
}
for record, err := csvReader.Read(); err == nil; record, err = csvReader.Read() {
direction, tenant, customer := record[0], record[1], record[2]
id := fmt.Sprintf("%s:%s:%s", direction, tenant, customer)
tenant, category, direction, account, subject := record[0], record[1], record[2], record[3], record[4]
id := utils.ConcatenatedKey(direction, tenant, category, account, subject)
lcr, found := csvr.lcrs[id]
activationTime, err := utils.ParseTimeDetectLayout(record[7])
activationTime, err := utils.ParseTimeDetectLayout(record[9])
if err != nil {
return fmt.Errorf("Could not parse LCR activation time: %v", err)
}
weight, err := strconv.ParseFloat(record[8], 64)
weight, err := strconv.ParseFloat(record[10], 64)
if err != nil {
return fmt.Errorf("Could not parse LCR weight: %v", err)
}
if !found {
lcr = &LCR{
Direction: direction,
Tenant: tenant,
Customer: customer,
Category: category,
Direction: direction,
Account: account,
Subject: subject,
}
}
var act *LCRActivation
@@ -640,11 +642,11 @@ func (csvr *CSVReader) LoadLCRs() (err error) {
lcr.Activations = append(lcr.Activations, act)
}
act.Entries = append(act.Entries, &LCREntry{
DestinationId: record[3],
Category: record[4],
Strategy: record[5],
Suppliers: record[6],
Weight: weight,
DestinationId: record[5],
RPCategory: record[6],
Strategy: record[7],
StrategyParams: record[8],
Weight: weight,
})
csvr.lcrs[id] = lcr
}

View File

@@ -141,10 +141,9 @@ SG3,*any,*lowest,
`
lcrs = `
*in,cgrates.org,*any,EU_LANDLINE,LCR_STANDARD,*static,ivo;dan;rif,2012-01-01T00:00:00Z,10
*in,cgrates.org,*any,*any,LCR_STANDARD,*lowest_cost,,2012-01-01T00:00:00Z,20
cgrates.org,call,*in,*any,*any,EU_LANDLINE,LCR_STANDARD,*static,ivo;dan;rif,2012-01-01T00:00:00Z,10
cgrates.org,call,*in,*any,*any,*any,LCR_STANDARD,*lowest_cost,,2012-01-01T00:00:00Z,20
`
actions = `
MINI,*topup_reset,,,*monetary,*out,,,,,*unlimited,,10,10,10
MINI,*topup,,,*voice,*out,,NAT,test,,*unlimited,,100,10,10
@@ -809,35 +808,37 @@ func TestLoadLCRs(t *testing.T) {
t.Error("Failed to load LCRs: ", csvr.lcrs)
}
lcr := csvr.lcrs["*in:cgrates.org:*any"]
lcr := csvr.lcrs["*in:cgrates.org:call:*any:*any"]
expected := &LCR{
Direction: "*in",
Tenant: "cgrates.org",
Customer: "*any",
Category: "call",
Direction: "*in",
Account: "*any",
Subject: "*any",
Activations: []*LCRActivation{
&LCRActivation{
ActivationTime: time.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC),
Entries: []*LCREntry{
&LCREntry{
DestinationId: "EU_LANDLINE",
Category: "LCR_STANDARD",
Strategy: "*static",
Suppliers: "ivo;dan;rif",
Weight: 10,
DestinationId: "EU_LANDLINE",
RPCategory: "LCR_STANDARD",
Strategy: "*static",
StrategyParams: "ivo;dan;rif",
Weight: 10,
},
&LCREntry{
DestinationId: "*any",
Category: "LCR_STANDARD",
Strategy: "*lowest_cost",
Suppliers: "",
Weight: 20,
DestinationId: "*any",
RPCategory: "LCR_STANDARD",
Strategy: "*lowest_cost",
StrategyParams: "",
Weight: 20,
},
},
},
},
}
if !reflect.DeepEqual(lcr, expected) {
t.Errorf("Error loading lcr %+v: ", lcr.Activations)
t.Errorf("Error loading lcr %+v: ", lcr)
}
}

View File

@@ -482,8 +482,8 @@ func (self *SQLStorage) SetTPLCRs(tpid string, lcrs map[string]*LCR) error {
if i != 0 { //Consecutive values after the first will be prefixed with "," as separator
buffer.WriteRune(',')
}
buffer.WriteString(fmt.Sprintf("('%s','%s','%s','%s','%s','%s','%s','%v','%v', '%v')",
tpid, lcr.Direction, lcr.Tenant, lcr.Customer, entry.DestinationId, entry.Category, entry.Strategy, entry.Suppliers, act.ActivationTime, entry.Weight))
buffer.WriteString(fmt.Sprintf("('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%v', '%v')",
tpid, lcr.Tenant, lcr.Category, lcr.Direction, lcr.Account, lcr.Subject, entry.DestinationId, entry.RPCategory, entry.Strategy, entry.RPCategory, act.ActivationTime, entry.Weight))
i++
}
}
@@ -1379,19 +1379,21 @@ func (self *SQLStorage) GetTpLCRs(tpid, tag string) (map[string]*LCR, error) {
defer rows.Close()
for rows.Next() {
var id int
var tpid, direction, tenant, customer, destinationId, category, strategy, suppliers, activationTimeString string
var tpid, tenant, category, direction, account, subject, destinationId, rpCategory, strategy, strategyParams, suppliers, activationTimeString string
var weight float64
if err := rows.Scan(&id, &tpid, &direction, &tenant, &customer, &destinationId, &category, &strategy, &suppliers, &activationTimeString, &weight); err != nil {
if err := rows.Scan(&id, &tpid, &tenant, &category, &direction, &account, &subject, &destinationId, &rpCategory, &strategy, &strategyParams, &suppliers, &activationTimeString, &weight); err != nil {
return nil, err
}
tag := fmt.Sprintf("%s:%s:%s", direction, tenant, customer)
tag := utils.ConcatenatedKey(direction, tenant, category, account, subject)
lcr, found := lcrs[tag]
activationTime, _ := utils.ParseTimeDetectLayout(activationTimeString)
if !found {
lcr = &LCR{
Direction: direction,
Tenant: tenant,
Customer: customer,
Category: category,
Direction: direction,
Account: account,
Subject: subject,
}
}
var act *LCRActivation
@@ -1408,11 +1410,11 @@ func (self *SQLStorage) GetTpLCRs(tpid, tag string) (map[string]*LCR, error) {
lcr.Activations = append(lcr.Activations, act)
}
act.Entries = append(act.Entries, &LCREntry{
DestinationId: destinationId,
Category: category,
Strategy: strategy,
Suppliers: suppliers,
Weight: weight,
DestinationId: destinationId,
RPCategory: category,
Strategy: strategy,
StrategyParams: strategyParams,
Weight: weight,
})
lcrs[tag] = lcr
}

View File

@@ -65,7 +65,7 @@ const (
DESTRATE_TIMINGS_NRCOLS = 4
RATE_PROFILES_NRCOLS = 7
SHARED_GROUPS_NRCOLS = 4
LCRS_NRCOLS = 9
LCRS_NRCOLS = 11
ACTIONS_NRCOLS = 15
ACTION_PLANS_NRCOLS = 4
ACTION_TRIGGERS_NRCOLS = 19