Go fmt on sources

This commit is contained in:
DanB
2013-11-19 20:06:53 +01:00
parent a20d6258e2
commit 87ea266c4a
21 changed files with 252 additions and 269 deletions

View File

@@ -38,9 +38,9 @@ func (self *ApierV1) SetTPAccountActions(attrs utils.TPAccountActions, reply *st
}
type AttrGetTPAccountActions struct {
TPid string // Tariff plan id
TPid string // Tariff plan id
LoadId string // AccountActions id
}
// Queries specific AccountActions profile on tariff plan

View File

@@ -84,7 +84,6 @@ func (self *ApierV1) GetTPActionIds(attrs AttrGetTPActionIds, reply *[]string) e
return nil
}
// Removes specific Actions on Tariff plan
func (self *ApierV1) RemTPActions(attrs AttrGetTPActions, reply *string) error {
if missing := utils.MissingStructFields(&attrs, []string{"TPid", "ActionsId"}); len(missing) != 0 { //Params missing

View File

@@ -39,7 +39,7 @@ func (self *ApierV1) SetTPRatingProfile(attrs utils.TPRatingProfile, reply *stri
}
type AttrGetTPRatingProfile struct {
TPid string // Tariff plan id
TPid string // Tariff plan id
LoadId string // RatingProfile id
}
@@ -47,7 +47,7 @@ type AttrGetTPRatingProfile struct {
func (self *ApierV1) GetTPRatingProfiles(attrs utils.TPRatingProfile, reply *[]*utils.TPRatingProfile) error {
mndtryFlds := []string{"TPid", "LoadId"}
if len(attrs.Subject) != 0 { // If Subject provided as filter, make all related fields mandatory
mndtryFlds = append(mndtryFlds, "Tenant", "TOR", "Direction","Subject")
mndtryFlds = append(mndtryFlds, "Tenant", "TOR", "Direction", "Subject")
}
if missing := utils.MissingStructFields(&attrs, mndtryFlds); len(missing) != 0 { //Params missing
return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing)
@@ -85,10 +85,9 @@ func (self *ApierV1) GetTPRatingProfileLoadIds(attrs utils.AttrTPRatingProfileId
return nil
}
// Removes specific RatingProfile on Tariff plan
func (self *ApierV1) RemTPRatingProfile(attrs utils.TPRatingProfile, reply *string) error {
if missing := utils.MissingStructFields(&attrs, []string{"TPid", "LoadId", "Tenant", "TOR", "Direction","Subject"}); len(missing) != 0 { //Params missing
if missing := utils.MissingStructFields(&attrs, []string{"TPid", "LoadId", "Tenant", "TOR", "Direction", "Subject"}); len(missing) != 0 { //Params missing
return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing)
}
if err := self.StorDb.RemTPData(utils.TBL_TP_RATE_PROFILES, attrs.TPid, attrs.LoadId, attrs.Tenant, attrs.TOR, attrs.Direction, attrs.Subject); err != nil {

View File

@@ -88,7 +88,6 @@ func (self *ApierV1) GetTPTimingIds(attrs AttrGetTPTimingIds, reply *[]string) e
return nil
}
// Removes specific Timing on Tariff plan
func (self *ApierV1) RemTPTiming(attrs AttrGetTPTiming, reply *string) error {
if missing := utils.MissingStructFields(&attrs, []string{"TPid", "TimingId"}); len(missing) != 0 { //Params missing
@@ -101,4 +100,3 @@ func (self *ApierV1) RemTPTiming(attrs AttrGetTPTiming, reply *string) error {
}
return nil
}

View File

@@ -20,16 +20,16 @@ package cdrexporter
import (
"encoding/csv"
"github.com/cgrates/cgrates/utils"
"io"
"sort"
"strconv"
"github.com/cgrates/cgrates/utils"
)
type CsvCdrWriter struct {
writer *csv.Writer
roundDecimals int // Round floats like Cost using this number of decimals
extraFields []string // Extra fields to append after primary ones, order important
writer *csv.Writer
roundDecimals int // Round floats like Cost using this number of decimals
extraFields []string // Extra fields to append after primary ones, order important
}
func NewCsvCdrWriter(writer io.Writer, roundDecimals int, extraFields []string) *CsvCdrWriter {
@@ -38,7 +38,7 @@ func NewCsvCdrWriter(writer io.Writer, roundDecimals int, extraFields []string)
func (dcw *CsvCdrWriter) Write(cdr *utils.RatedCDR) error {
primaryFields := []string{cdr.CgrId, cdr.AccId, cdr.CdrHost, cdr.ReqType, cdr.Direction, cdr.Tenant, cdr.TOR, cdr.Account, cdr.Subject,
cdr.Destination, cdr.AnswerTime.String(), strconv.Itoa(int(cdr.Duration)), strconv.FormatFloat(cdr.Cost, 'f', dcw.roundDecimals, 64)}
cdr.Destination, cdr.AnswerTime.String(), strconv.Itoa(int(cdr.Duration)), strconv.FormatFloat(cdr.Cost, 'f', dcw.roundDecimals, 64)}
if len(dcw.extraFields) == 0 {
dcw.extraFields = utils.MapKeys(cdr.ExtraFields)
sort.Strings(dcw.extraFields) // Controlled order in case of dynamic extra fields

View File

@@ -20,19 +20,19 @@ package cdrexporter
import (
"bytes"
"github.com/cgrates/cgrates/utils"
"strings"
"testing"
"time"
"github.com/cgrates/cgrates/utils"
)
func TestCsvCdrWriter(t *testing.T) {
writer := &bytes.Buffer{}
csvCdrWriter := NewCsvCdrWriter(writer, 4, []string{"extra3", "extra1"})
ratedCdr := &utils.RatedCDR{ CgrId: utils.FSCgrId("dsafdsaf"), AccId:"dsafdsaf", CdrHost:"192.168.1.1", ReqType:"rated", Direction:"*out", Tenant:"cgrates.org",
TOR:"call", Account:"1001", Subject:"1001", Destination:"1002", AnswerTime:time.Unix(1383813746,0).UTC(), Duration:10,
ExtraFields:map[string]string{"extra1":"val_extra1", "extra2":"val_extra2", "extra3":"val_extra3"}, Cost:1.01,
}
ratedCdr := &utils.RatedCDR{CgrId: utils.FSCgrId("dsafdsaf"), AccId: "dsafdsaf", CdrHost: "192.168.1.1", ReqType: "rated", Direction: "*out", Tenant: "cgrates.org",
TOR: "call", Account: "1001", Subject: "1001", Destination: "1002", AnswerTime: time.Unix(1383813746, 0).UTC(), Duration: 10,
ExtraFields: map[string]string{"extra1": "val_extra1", "extra2": "val_extra2", "extra3": "val_extra3"}, Cost: 1.01,
}
csvCdrWriter.Write(ratedCdr)
csvCdrWriter.Close()
expected := "b18944ef4dc618569f24c27b9872827a242bad0c,dsafdsaf,192.168.1.1,rated,*out,cgrates.org,call,1001,1001,1002,2013-11-07 08:42:26 +0000 UTC,10,1.0100,val_extra3,val_extra1"

View File

@@ -75,7 +75,7 @@ func New(s engine.CdrStorage, m *mediator.Mediator, c *config.CGRConfig) *CDRS {
}
func (cdrs *CDRS) StartCapturingCDRs() {
http.HandleFunc("/cgr", cgrCdrHandler) // Attach CGR CDR Handler
http.HandleFunc("/cgr", cgrCdrHandler) // Attach CGR CDR Handler
http.HandleFunc("/freeswitch_json", fsCdrHandler) // Attach FreeSWITCH JSON CDR Handler
http.ListenAndServe(cfg.CDRSListen, nil)
}

View File

@@ -20,23 +20,23 @@ package cdrs
import (
"github.com/cgrates/cgrates/utils"
"net/http"
"strconv"
"time"
"net/http"
)
const (
ACCID = "accid"
CDRHOST = "cdrhost"
REQTYPE = "reqtype"
DIRECTION = "direction"
TENANT = "tenant"
TOR = "tor"
ACCOUNT = "account"
SUBJECT = "subject"
ACCID = "accid"
CDRHOST = "cdrhost"
REQTYPE = "reqtype"
DIRECTION = "direction"
TENANT = "tenant"
TOR = "tor"
ACCOUNT = "account"
SUBJECT = "subject"
DESTINATION = "destination"
TIME_ANSWER = "time_answer"
DURATION = "duration"
DURATION = "duration"
)
var primaryFields []string = []string{ACCID, CDRHOST, REQTYPE, DIRECTION, TENANT, TOR, ACCOUNT, SUBJECT, DESTINATION, TIME_ANSWER, DURATION}
@@ -53,7 +53,6 @@ func NewCgrCdrFromHttpReq(req *http.Request) (CgrCdr, error) {
}
return cgrCdr, nil
}
type CgrCdr map[string]string
@@ -109,6 +108,7 @@ func (cgrCdr CgrCdr) GetExtraFields() map[string]string {
func (cgrCdr CgrCdr) GetAnswerTime() (t time.Time, err error) {
return utils.ParseDate(cgrCdr[TIME_ANSWER])
}
// Extracts duration as considered by the telecom switch
func (cgrCdr CgrCdr) GetDuration() int64 {
dur, _ := strconv.ParseInt(cgrCdr[DURATION], 0, 64)

View File

@@ -19,8 +19,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
package cdrs
import (
"github.com/cgrates/cgrates/utils"
"github.com/cgrates/cgrates/config"
"github.com/cgrates/cgrates/utils"
"testing"
"time"
)
@@ -31,8 +31,8 @@ curl --data "accid=asbfdsaf&cdrhost=192.168.1.1&reqtype=rated&direction=*out&ten
func TestCgrCdrFields(t *testing.T) {
cfg, _ = config.NewDefaultCGRConfig()
cgrCdr := CgrCdr{ "accid":"dsafdsaf", "cdrhost":"192.168.1.1", "reqtype":"rated", "direction":"*out", "tenant":"cgrates.org", "tor":"call",
"account":"1001", "subject":"1001", "destination":"1002", "time_answer":"1383813746", "duration":"10", "field_extr1":"val_extr1", "fieldextr2":"valextr2"}
cgrCdr := CgrCdr{"accid": "dsafdsaf", "cdrhost": "192.168.1.1", "reqtype": "rated", "direction": "*out", "tenant": "cgrates.org", "tor": "call",
"account": "1001", "subject": "1001", "destination": "1002", "time_answer": "1383813746", "duration": "10", "field_extr1": "val_extr1", "fieldextr2": "valextr2"}
if cgrCdr.GetCgrId() != utils.FSCgrId("dsafdsaf") {
t.Error("Error parsing cdr: ", cgrCdr)
}

View File

@@ -372,7 +372,7 @@ func (csvr *CSVReader) LoadRatingProfiles() (err error) {
rpa := &RatingPlanActivation{
ActivationTime: at,
RatingPlanId: record[5],
FallbackKeys: utils.FallbackSubjKeys(direction, tenant, tor, fallbacksubject),
FallbackKeys: utils.FallbackSubjKeys(direction, tenant, tor, fallbacksubject),
}
rp.RatingPlanActivations = append(rp.RatingPlanActivations, rpa)
csvr.ratingProfiles[rp.Id] = rp
@@ -544,7 +544,7 @@ func (csvr *CSVReader) LoadAccountActions() (err error) {
}
// Returns the identities loaded for a specific category, useful for cache reloads
func (csvr *CSVReader) GetLoadedIds( categ string ) ([]string, error) {
func (csvr *CSVReader) GetLoadedIds(categ string) ([]string, error) {
switch categ {
case DESTINATION_PREFIX:
ids := make([]string, len(csvr.destinations))

View File

@@ -185,7 +185,7 @@ func (dbr *DbReader) LoadRatingPlans() error {
return err
}
for tag, rplBnds := range mpRpls {
for _,rplBnd := range rplBnds {
for _, rplBnd := range rplBnds {
t, exists := dbr.timings[rplBnd.TimingId]
if !exists {
return errors.New(fmt.Sprintf("Could not get timing for tag %v", rplBnd.TimingId))
@@ -209,7 +209,7 @@ func (dbr *DbReader) LoadRatingPlans() error {
}
func (dbr *DbReader) LoadRatingProfiles() error {
mpTpRpfs, err := dbr.storDb.GetTpRatingProfiles(&utils.TPRatingProfile{TPid:dbr.tpid}) //map[string]*utils.TPRatingProfile
mpTpRpfs, err := dbr.storDb.GetTpRatingProfiles(&utils.TPRatingProfile{TPid: dbr.tpid}) //map[string]*utils.TPRatingProfile
if err != nil {
return err
}
@@ -291,12 +291,12 @@ func (dbr *DbReader) LoadRatingPlanByTag(tag string) error {
return err
}
}
return nil
return nil
}
func (dbr *DbReader) LoadRatingProfileByTag(tag string) error {
resultRatingProfile := &RatingProfile{}
mpTpRpfs, err := dbr.storDb.GetTpRatingProfiles(&utils.TPRatingProfile{TPid:dbr.tpid, LoadId:tag}) //map[string]*utils.TPRatingProfile
mpTpRpfs, err := dbr.storDb.GetTpRatingProfiles(&utils.TPRatingProfile{TPid: dbr.tpid, LoadId: tag}) //map[string]*utils.TPRatingProfile
if err != nil || len(mpTpRpfs) == 0 {
return fmt.Errorf("No RateProfile with id %s: %v", tag, err)
}
@@ -316,9 +316,9 @@ func (dbr *DbReader) LoadRatingProfileByTag(tag string) error {
return errors.New(fmt.Sprintf("Could not load rating plans for tag: %v", tpRa.RatingPlanId))
}
}
resultRatingProfile.RatingPlanActivations = append(resultRatingProfile.RatingPlanActivations,
&RatingPlanActivation{at, tpRa.RatingPlanId,
utils.FallbackSubjKeys(tpRpf.Direction, tpRpf.Tenant, tpRpf.TOR, tpRa.FallbackSubjects)})
resultRatingProfile.RatingPlanActivations = append(resultRatingProfile.RatingPlanActivations,
&RatingPlanActivation{at, tpRa.RatingPlanId,
utils.FallbackSubjKeys(tpRpf.Direction, tpRpf.Tenant, tpRpf.TOR, tpRa.FallbackSubjects)})
}
}
return dbr.dataDb.SetRatingProfile(resultRatingProfile)
@@ -374,14 +374,14 @@ func (dbr *DbReader) LoadActionTriggers() (err error) {
atrs := make([]*ActionTrigger, len(atrsLst))
for idx, apiAtr := range atrsLst {
atrs[idx] = &ActionTrigger{Id: utils.GenUUID(),
BalanceId: apiAtr.BalanceType,
Direction: apiAtr.Direction,
ThresholdType: apiAtr.ThresholdType,
ThresholdValue: apiAtr.ThresholdValue,
DestinationId: apiAtr.DestinationId,
Weight: apiAtr.Weight,
ActionsId: apiAtr.ActionsId,
}
BalanceId: apiAtr.BalanceType,
Direction: apiAtr.Direction,
ThresholdType: apiAtr.ThresholdType,
ThresholdValue: apiAtr.ThresholdValue,
DestinationId: apiAtr.DestinationId,
Weight: apiAtr.Weight,
ActionsId: apiAtr.ActionsId,
}
}
dbr.actionsTriggers[key] = atrs
}
@@ -389,7 +389,7 @@ func (dbr *DbReader) LoadActionTriggers() (err error) {
}
func (dbr *DbReader) LoadAccountActions() (err error) {
acs, err := dbr.storDb.GetTpAccountActions(&utils.TPAccountActions{TPid:dbr.tpid})
acs, err := dbr.storDb.GetTpAccountActions(&utils.TPAccountActions{TPid: dbr.tpid})
if err != nil {
return err
}
@@ -417,7 +417,7 @@ func (dbr *DbReader) LoadAccountActions() (err error) {
}
func (dbr *DbReader) LoadAccountActionsByTag(tag string) error {
accountActions, err := dbr.storDb.GetTpAccountActions(&utils.TPAccountActions{TPid:dbr.tpid, LoadId:tag})
accountActions, err := dbr.storDb.GetTpAccountActions(&utils.TPAccountActions{TPid: dbr.tpid, LoadId: tag})
if err != nil {
return err
} else if len(accountActions) == 0 {
@@ -508,19 +508,19 @@ func (dbr *DbReader) LoadAccountActionsByTag(tag string) error {
if err != nil {
return err
}
atrsMap := make( map[string][]*ActionTrigger )
atrsMap := make(map[string][]*ActionTrigger)
for key, atrsLst := range apiAtrsMap {
atrs := make([]*ActionTrigger, len(atrsLst))
for idx, apiAtr := range atrsLst {
atrs[idx] = &ActionTrigger{Id: utils.GenUUID(),
BalanceId: apiAtr.BalanceType,
Direction: apiAtr.Direction,
ThresholdType: apiAtr.ThresholdType,
ThresholdValue: apiAtr.ThresholdValue,
DestinationId: apiAtr.DestinationId,
Weight: apiAtr.Weight,
ActionsId: apiAtr.ActionsId,
}
BalanceId: apiAtr.BalanceType,
Direction: apiAtr.Direction,
ThresholdType: apiAtr.ThresholdType,
ThresholdValue: apiAtr.ThresholdValue,
DestinationId: apiAtr.DestinationId,
Weight: apiAtr.Weight,
ActionsId: apiAtr.ActionsId,
}
}
atrsMap[key] = atrs
}
@@ -562,9 +562,8 @@ func (dbr *DbReader) LoadAccountActionsByTag(tag string) error {
return dbr.dataDb.SetUserBalance(ub)
}
// Returns the identities loaded for a specific entity category
func (dbr *DbReader) GetLoadedIds( categ string ) ([]string, error) {
func (dbr *DbReader) GetLoadedIds(categ string) ([]string, error) {
switch categ {
case DESTINATION_PREFIX:
ids := make([]string, len(dbr.destinations))

View File

@@ -43,9 +43,8 @@ type TPLoader interface {
LoadActionTimings() error
LoadActionTriggers() error
LoadAccountActions() error
GetLoadedIds( string ) ([]string, error)
GetLoadedIds(string) ([]string, error)
WriteToDatabase(bool, bool) error
}
/*type LoadRate struct {
@@ -71,14 +70,14 @@ func NewLoadRate(tag, connectFee, price, ratedUnits, rateIncrements, groupInterv
log.Printf("Error parsing rounding decimals: %s", roundingDecimals)
return
}
rs, err := utils.NewRateSlot( cf, p, ratedUnits, rateIncrements, groupInterval, roundingMethod, rd )
rs, err := utils.NewRateSlot(cf, p, ratedUnits, rateIncrements, groupInterval, roundingMethod, rd)
if err != nil {
return nil, err
}
r = &utils.TPRate{
RateId: tag,
RateId: tag,
RateSlots: []*utils.RateSlot{rs},
}
}
return
}

View File

@@ -19,11 +19,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
package engine
import (
"github.com/cgrates/cgrates/utils"
"github.com/cgrates/cgrates/config"
"testing"
"path"
"flag"
"github.com/cgrates/cgrates/config"
"github.com/cgrates/cgrates/utils"
"path"
"testing"
)
/*
@@ -49,14 +49,13 @@ var testLocal = flag.Bool("local", false, "Perform the tests only on local test
var dataDir = flag.String("data_dir", "/usr/share/cgrates/data", "CGR data dir path here")
var tpCsvScenario = flag.String("tp_scenario", "prepaid1centpsec", "Use this scenario folder to import tp csv data from")
// Create connection to dataDb
// Will use 3 different datadbs in order to be able to see differences in data loaded
func TestConnDataDbs(t *testing.T) {
if !*testLocal {
if !*testLocal {
return
}
cfg,_ = config.NewDefaultCGRConfig()
cfg, _ = config.NewDefaultCGRConfig()
var err error
if dataDbCsv, err = ConfigureDataStorage(cfg.DataDBType, cfg.DataDBHost, cfg.DataDBPort, "13", cfg.DataDBUser, cfg.DataDBPass, cfg.DBDataEncoding); err != nil {
t.Fatal("Error on dataDb connection: ", err.Error())
@@ -68,12 +67,12 @@ func TestConnDataDbs(t *testing.T) {
// Create/reset storage tariff plan tables, used as database connectin establishment also
func TestCreateStorTpTables(t *testing.T) {
if !*testLocal {
if !*testLocal {
return
}
var db *MySQLStorage
if d, err := NewMySQLStorage(cfg.StorDBHost, cfg.StorDBPort, cfg.StorDBName, cfg.StorDBUser, cfg.StorDBPass); err != nil {
t.Error("Error on opening database connection: ",err)
t.Error("Error on opening database connection: ", err)
return
} else {
db = d.(*MySQLStorage)
@@ -88,7 +87,7 @@ func TestCreateStorTpTables(t *testing.T) {
// Loads data from csv files in tp scenarion to dataDbCsv
func TestLoadFromCSV(t *testing.T) {
if !*testLocal {
if !*testLocal {
return
}
var err error
@@ -97,18 +96,18 @@ func TestLoadFromCSV(t *testing.T) {
t.Error("Failed validating data: ", err.Error())
}
}
loader := NewFileCSVReader(dataDbCsv, utils.CSV_SEP,
path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.DESTINATIONS_CSV),
path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.TIMINGS_CSV),
path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.RATES_CSV),
path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.DESTINATION_RATES_CSV),
path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.RATING_PLANS_CSV),
path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.RATING_PROFILES_CSV),
path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.ACTIONS_CSV),
path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.ACTION_TIMINGS_CSV),
path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.ACTION_TRIGGERS_CSV),
path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.ACCOUNT_ACTIONS_CSV),
)
loader := NewFileCSVReader(dataDbCsv, utils.CSV_SEP,
path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.DESTINATIONS_CSV),
path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.TIMINGS_CSV),
path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.RATES_CSV),
path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.DESTINATION_RATES_CSV),
path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.RATING_PLANS_CSV),
path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.RATING_PROFILES_CSV),
path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.ACTIONS_CSV),
path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.ACTION_TIMINGS_CSV),
path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.ACTION_TRIGGERS_CSV),
path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.ACCOUNT_ACTIONS_CSV),
)
if err = loader.LoadDestinations(); err != nil {
t.Error("Failed loading destinations: ", err.Error())
@@ -216,7 +215,7 @@ func TestMatchLoadCsvWithStor(t *testing.T) {
if err != nil {
t.Fatal("Failed querying redis keys for csv data")
}
for _,key := range keysCsv {
for _, key := range keysCsv {
valCsv, err := rsCsv.db.Get(key)
if err != nil {
t.Errorf("Error when querying dataDbCsv for key: %s - %s ", key, err.Error())
@@ -231,4 +230,4 @@ func TestMatchLoadCsvWithStor(t *testing.T) {
t.Errorf("Missmatched data for key: %s\n\t, dataDbCsv: %s \n\t dataDbStor: %s\n", key, valCsv, valStor)
}
}
}
}

View File

@@ -51,11 +51,11 @@ const (
SCHED_SOURCE = "SCH"
RATER_SOURCE = "RAT"
// Some consts used in tests
CREATE_CDRS_TABLES_SQL = "create_cdrs_tables.sql"
CREATE_CDRS_TABLES_SQL = "create_cdrs_tables.sql"
CREATE_COSTDETAILS_TABLES_SQL = "create_costdetails_tables.sql"
CREATE_MEDIATOR_TABLES_SQL = "create_mediator_tables.sql"
CREATE_TARIFFPLAN_TABLES_SQL = "create_tariffplan_tables.sql"
TEST_SQL = "TEST_SQL"
CREATE_MEDIATOR_TABLES_SQL = "create_mediator_tables.sql"
CREATE_TARIFFPLAN_TABLES_SQL = "create_tariffplan_tables.sql"
TEST_SQL = "TEST_SQL"
)
type Storage interface {

View File

@@ -23,9 +23,9 @@ import (
"encoding/json"
"fmt"
"github.com/cgrates/cgrates/utils"
"time"
"io/ioutil"
"strings"
"time"
)
type SQLStorage struct {
@@ -40,13 +40,13 @@ func (self *SQLStorage) Flush() (err error) {
return
}
func (self *SQLStorage) CreateTablesFromScript( scriptPath string) error {
func (self *SQLStorage) CreateTablesFromScript(scriptPath string) error {
fileContent, err := ioutil.ReadFile(scriptPath)
if err != nil {
return err
}
qries := strings.Split(string(fileContent), ";") // Script has normally multiple queries separate by ';' go driver does not understand this so we handle it here
for _,qry := range qries {
for _, qry := range qries {
qry = strings.TrimSpace(qry) // Avoid empty queries
if len(qry) == 0 {
continue
@@ -58,7 +58,6 @@ func (self *SQLStorage) CreateTablesFromScript( scriptPath string) error {
return nil
}
// Return a list with all TPids defined in the system, even if incomplete, isolated in some table.
func (self *SQLStorage) GetTPIds() ([]string, error) {
rows, err := self.Db.Query(
@@ -129,17 +128,15 @@ func (self *SQLStorage) GetTPTimingIds(tpid string) ([]string, error) {
return ids, nil
}
func (self *SQLStorage) RemTPData(table, tpid string, args ...string) error {
q := fmt.Sprintf("DELETE FROM %s WHERE tpid='%s' AND tag='%s'", table, tpid, args[0])
switch table {
case utils.TBL_TP_RATE_PROFILES:
q = fmt.Sprintf("DELETE FROM %s WHERE tpid='%s' AND loadid='%s' AND tenant='%s' AND tor='%s' AND direction='%s' AND subject='%s'",
table, tpid, args[0], args[1], args[2], args[3], args[4])
q = fmt.Sprintf("DELETE FROM %s WHERE tpid='%s' AND loadid='%s' AND tenant='%s' AND tor='%s' AND direction='%s' AND subject='%s'",
table, tpid, args[0], args[1], args[2], args[3], args[4])
case utils.TBL_TP_ACCOUNT_ACTIONS:
q = fmt.Sprintf("DELETE FROM %s WHERE tpid='%s' AND loadid='%s' AND tenant='%s' AND account='%s' AND direction='%s'",
table, tpid, args[0], args[1], args[2], args[3])
q = fmt.Sprintf("DELETE FROM %s WHERE tpid='%s' AND loadid='%s' AND tenant='%s' AND account='%s' AND direction='%s'",
table, tpid, args[0], args[1], args[2], args[3])
}
if _, err := self.Db.Exec(q); err != nil {
return err
@@ -206,8 +203,8 @@ func (self *SQLStorage) SetTPDestination(tpid string, dest *Destination) error {
}
vals += fmt.Sprintf("('%s','%s','%s')", tpid, dest.Id, prefix)
}
q := fmt.Sprintf("INSERT INTO %s (tpid, tag, prefix) VALUES %s ON DUPLICATE KEY UPDATE prefix=values(prefix)",
utils.TBL_TP_DESTINATIONS, vals)
q := fmt.Sprintf("INSERT INTO %s (tpid, tag, prefix) VALUES %s ON DUPLICATE KEY UPDATE prefix=values(prefix)",
utils.TBL_TP_DESTINATIONS, vals)
if _, err := self.Db.Exec(q); err != nil {
return err
}
@@ -255,10 +252,10 @@ func (self *SQLStorage) GetTPRate(tpid, rtId string) (*utils.TPRate, error) {
if err != nil {
return nil, err
}
if rs, err := utils.NewRateSlot(connectFee, rate, rateUnit, rateIncrement, groupIntervalStart, roundingMethod, roundingDecimals); err!=nil {
if rs, err := utils.NewRateSlot(connectFee, rate, rateUnit, rateIncrement, groupIntervalStart, roundingMethod, roundingDecimals); err != nil {
return nil, err
} else {
rt.RateSlots = append(rt.RateSlots, rs)
rt.RateSlots = append(rt.RateSlots, rs)
}
}
if i == 0 {
@@ -398,7 +395,7 @@ func (self *SQLStorage) GetTPRatingPlan(tpid, drtId string) (*utils.TPRatingPlan
if err != nil {
return nil, err
}
drt.RatingPlanBindings = append(drt.RatingPlanBindings, &utils.TPRatingPlanBinding{DestinationRatesId:drTag, TimingId:timingTag, Weight:weight})
drt.RatingPlanBindings = append(drt.RatingPlanBindings, &utils.TPRatingPlanBinding{DestinationRatesId: drTag, TimingId: timingTag, Weight: weight})
}
if i == 0 {
return nil, nil
@@ -911,14 +908,14 @@ func (self *SQLStorage) GetTpRates(tpid, tag string) (map[string]*utils.TPRate,
return nil, err
}
rs, err := utils.NewRateSlot(connect_fee, rate, rate_unit, rate_increment, group_interval_start, roundingMethod, roundingDecimals)
if err!=nil {
if err != nil {
return nil, err
}
r := &utils.TPRate{
RateId: tag,
RateId: tag,
RateSlots: []*utils.RateSlot{rs},
}
}
// same tag only to create rate groups
existingRates, exists := rts[tag]
if exists {
@@ -1015,10 +1012,10 @@ func (self *SQLStorage) GetTpRatingPlans(tpid, tag string) (map[string][]*utils.
}
rpb := &utils.TPRatingPlanBinding{
DestinationRatesId: destination_rates_tag,
TimingId: timings_tag,
Weight: weight,
TimingId: timings_tag,
Weight: weight,
}
if rpBnLst,exists := rpbns[tag]; exists {
if rpBnLst, exists := rpbns[tag]; exists {
rpBnLst = append(rpBnLst, rpb)
} else { // New
rpbns[tag] = []*utils.TPRatingPlanBinding{rpb}
@@ -1044,7 +1041,7 @@ func (self *SQLStorage) GetTpRatingProfiles(qryRpf *utils.TPRatingProfile) (map[
}
if len(qryRpf.Subject) != 0 {
q += fmt.Sprintf(" AND subject='%s'", qryRpf.Subject)
}
}
rows, err := self.Db.Query(q)
if err != nil {
return nil, err
@@ -1056,14 +1053,14 @@ func (self *SQLStorage) GetTpRatingProfiles(qryRpf *utils.TPRatingProfile) (map[
if err := rows.Scan(&rcvLoadId, &tenant, &tor, &direction, &subject, &activation_time, &rating_plan_tag, &fallback_subjects); err != nil {
return nil, err
}
rp := &utils.TPRatingProfile{TPid: qryRpf.TPid, LoadId: rcvLoadId, Tenant: tenant, TOR: tor, Direction:direction, Subject:subject}
if existingRp,has := rpfs[rp.KeyId()]; !has {
rp := &utils.TPRatingProfile{TPid: qryRpf.TPid, LoadId: rcvLoadId, Tenant: tenant, TOR: tor, Direction: direction, Subject: subject}
if existingRp, has := rpfs[rp.KeyId()]; !has {
rp.RatingPlanActivations = []*utils.TPRatingActivation{
&utils.TPRatingActivation{ActivationTime:activation_time, RatingPlanId:rating_plan_tag, FallbackSubjects:fallback_subjects}}
&utils.TPRatingActivation{ActivationTime: activation_time, RatingPlanId: rating_plan_tag, FallbackSubjects: fallback_subjects}}
rpfs[rp.KeyId()] = rp
} else { // Exists, update
existingRp.RatingPlanActivations = append( existingRp.RatingPlanActivations,
&utils.TPRatingActivation{ActivationTime:activation_time, RatingPlanId:rating_plan_tag, FallbackSubjects:fallback_subjects} )
existingRp.RatingPlanActivations = append(existingRp.RatingPlanActivations,
&utils.TPRatingActivation{ActivationTime: activation_time, RatingPlanId: rating_plan_tag, FallbackSubjects: fallback_subjects})
}
}
return rpfs, nil
@@ -1125,10 +1122,10 @@ func (self *SQLStorage) GetTpActionTimings(tpid, tag string) (map[string][]*util
if err := rows.Scan(&tag, &actions_tag, &timing_tag, &weight); err != nil {
return nil, err
}
at := &utils.TPActionTiming {
at := &utils.TPActionTiming{
ActionsId: tag,
TimingId: timing_tag,
Weight: weight,
TimingId: timing_tag,
Weight: weight,
}
ats[tag] = append(ats[tag], at)
}

View File

@@ -19,11 +19,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
package engine
import (
"github.com/cgrates/cgrates/utils"
"github.com/cgrates/cgrates/config"
"testing"
"path"
"fmt"
"github.com/cgrates/cgrates/config"
"github.com/cgrates/cgrates/utils"
"path"
"testing"
)
/*
@@ -40,14 +40,14 @@ README:
*/
var mysql *MySQLStorage
func TestCreateTables(t *testing.T) {
if !*testLocal {
if !*testLocal {
return
}
cgrConfig, _ := config.NewDefaultCGRConfig()
if d, err := NewMySQLStorage(cgrConfig.StorDBHost, cgrConfig.StorDBPort, cgrConfig.StorDBName, cgrConfig.StorDBUser, cgrConfig.StorDBPass); err != nil {
t.Error("Error on opening database connection: ",err)
t.Error("Error on opening database connection: ", err)
return
} else {
mysql = d.(*MySQLStorage)
@@ -59,19 +59,19 @@ func TestCreateTables(t *testing.T) {
}
}
for _, tbl := range []string{utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_EXTRA} {
if _, err := mysql.Db.Query(fmt.Sprintf("SELECT 1 from %s", tbl)); err != nil {
if _, err := mysql.Db.Query(fmt.Sprintf("SELECT 1 from %s", tbl)); err != nil {
t.Error(err.Error())
}
}
}
func TestRemoveData(t *testing.T) {
if !*testLocal {
if !*testLocal {
return
}
// Create Timings
tm := &utils.TPTiming{Id:"ALWAYS", StartTime:"00:00:00"}
if err := mysql.SetTPTiming(TEST_SQL,tm); err != nil {
tm := &utils.TPTiming{Id: "ALWAYS", StartTime: "00:00:00"}
if err := mysql.SetTPTiming(TEST_SQL, tm); err != nil {
t.Error(err.Error())
}
if tmgs, err := mysql.GetTpTimings(TEST_SQL, tm.Id); err != nil {
@@ -89,14 +89,14 @@ func TestRemoveData(t *testing.T) {
t.Error("Did not remove TPTiming")
}
// Create RatingProfile
ras := []*utils.TPRatingActivation{&utils.TPRatingActivation{ActivationTime: "2012-01-01T00:00:00Z", RatingPlanId:"RETAIL1"}}
rp := &utils.TPRatingProfile{TPid:TEST_SQL, LoadId:TEST_SQL, Tenant:"cgrates.org", TOR:"call", Direction:"*out", Subject:"*any", RatingPlanActivations:ras}
if err := mysql.SetTPRatingProfiles(TEST_SQL, map[string]*utils.TPRatingProfile{rp.KeyId():rp}); err != nil {
ras := []*utils.TPRatingActivation{&utils.TPRatingActivation{ActivationTime: "2012-01-01T00:00:00Z", RatingPlanId: "RETAIL1"}}
rp := &utils.TPRatingProfile{TPid: TEST_SQL, LoadId: TEST_SQL, Tenant: "cgrates.org", TOR: "call", Direction: "*out", Subject: "*any", RatingPlanActivations: ras}
if err := mysql.SetTPRatingProfiles(TEST_SQL, map[string]*utils.TPRatingProfile{rp.KeyId(): rp}); err != nil {
t.Error(err.Error())
}
if rps, err := mysql.GetTpRatingProfiles(rp); err != nil {
t.Error(err.Error())
} else if len(rps) == 0{
} else if len(rps) == 0 {
t.Error("Could not store TPRatingProfile")
}
// Remove RatingProfile
@@ -105,13 +105,13 @@ func TestRemoveData(t *testing.T) {
}
if rps, err := mysql.GetTpRatingProfiles(rp); err != nil {
t.Error(err.Error())
} else if len(rps) != 0{
} else if len(rps) != 0 {
t.Error("Did not remove TPRatingProfile")
}
// Create AccountActions
aa := &utils.TPAccountActions{TPid:TEST_SQL, LoadId:TEST_SQL, Tenant:"cgrates.org", Account:"1001",
Direction:"*out", ActionTimingsId:"PREPAID_10", ActionTriggersId:"STANDARD_TRIGGERS"}
aa := &utils.TPAccountActions{TPid: TEST_SQL, LoadId: TEST_SQL, Tenant: "cgrates.org", Account: "1001",
Direction: "*out", ActionTimingsId: "PREPAID_10", ActionTriggersId: "STANDARD_TRIGGERS"}
if err := mysql.SetTPAccountActions(aa.TPid, map[string]*utils.TPAccountActions{aa.KeyId(): aa}); err != nil {
t.Error(err.Error())
}
@@ -130,7 +130,3 @@ func TestRemoveData(t *testing.T) {
t.Error("Did not remove TPAccountActions")
}
}

View File

@@ -178,11 +178,11 @@ func (self *TPCSVImporter) importDestinationRates(fn string) error {
continue
}
drs := []*utils.DestinationRate{
&utils.DestinationRate{
DestinationId: record[1],
RateId: record[2],
},
}
&utils.DestinationRate{
DestinationId: record[1],
RateId: record[2],
},
}
if err := self.StorDb.SetTPDestinationRates(self.TPid,
map[string][]*utils.DestinationRate{record[0]: drs}); err != nil {
if self.Verbose {
@@ -221,12 +221,12 @@ func (self *TPCSVImporter) importRatingPlans(fn string) error {
continue
}
drt := []*utils.TPRatingPlanBinding{
&utils.TPRatingPlanBinding{
DestinationRatesId: record[1],
Weight: weight,
TimingId: record[2],
},
}
&utils.TPRatingPlanBinding{
DestinationRatesId: record[1],
Weight: weight,
TimingId: record[2],
},
}
if err := self.StorDb.SetTPRatingPlans(self.TPid, map[string][]*utils.TPRatingPlanBinding{record[0]: drt}); err != nil {
if self.Verbose {
log.Printf("Ignoring line %d, storDb operational error: <%s> ", lineNr, err.Error())
@@ -269,13 +269,13 @@ func (self *TPCSVImporter) importRatingProfiles(fn string) error {
loadId += "_" + self.ImportId
}
rp := &utils.TPRatingProfile{
LoadId: loadId,
Tenant: tenant,
TOR: tor,
Direction: direction,
Subject: subject,
RatingPlanActivations: []*utils.TPRatingActivation{
&utils.TPRatingActivation{ ActivationTime: record[4], RatingPlanId: ratingPlanTag, FallbackSubjects: fallbacksubject}},
LoadId: loadId,
Tenant: tenant,
TOR: tor,
Direction: direction,
Subject: subject,
RatingPlanActivations: []*utils.TPRatingActivation{
&utils.TPRatingActivation{ActivationTime: record[4], RatingPlanId: ratingPlanTag, FallbackSubjects: fallbacksubject}},
}
if err := self.StorDb.SetTPRatingProfiles(self.TPid, map[string]*utils.TPRatingProfile{rp.KeyId(): rp}); err != nil {
if self.Verbose {
@@ -323,16 +323,16 @@ func (self *TPCSVImporter) importActions(fn string) error {
continue
}
act := &utils.TPAction{
Identifier: actionType,
BalanceType: balanceType,
Direction: direction,
Units: units,
ExpiryTime: record[5],
DestinationId: destTag,
RatingSubject: rateSubject,
BalanceWeight: balanceWeight,
ExtraParameters: record[9],
Weight: weight,
Identifier: actionType,
BalanceType: balanceType,
Direction: direction,
Units: units,
ExpiryTime: record[5],
DestinationId: destTag,
RatingSubject: rateSubject,
BalanceWeight: balanceWeight,
ExtraParameters: record[9],
Weight: weight,
}
if err := self.StorDb.SetTPActions(self.TPid, map[string][]*utils.TPAction{actId: []*utils.TPAction{act}}); err != nil {
if self.Verbose {
@@ -372,12 +372,12 @@ func (self *TPCSVImporter) importActionTimings(fn string) error {
continue
}
at := []*utils.TPActionTiming{
&utils.TPActionTiming{
ActionsId: actionsTag,
TimingId: timingTag,
Weight: weight,
},
}
&utils.TPActionTiming{
ActionsId: actionsTag,
TimingId: timingTag,
Weight: weight,
},
}
if err := self.StorDb.SetTPActionTimings(self.TPid, map[string][]*utils.TPActionTiming{tag: at}); err != nil {
if self.Verbose {
log.Printf("Ignoring line %d, storDb operational error: <%s> ", lineNr, err.Error())
@@ -423,7 +423,7 @@ func (self *TPCSVImporter) importActionTriggers(fn string) error {
continue
}
at := &utils.TPActionTrigger{
BalanceType: balanceType,
BalanceType: balanceType,
Direction: direction,
ThresholdType: thresholdType,
ThresholdValue: threshold,
@@ -466,7 +466,7 @@ func (self *TPCSVImporter) importAccountActions(fn string) error {
loadId += "_" + self.ImportId
}
tpaa := &utils.TPAccountActions{TPid: self.TPid, LoadId: loadId, Tenant: tenant, Account: account, Direction: direction,
ActionTimingsId: actionTimingsTag, ActionTriggersId: actionTriggersTag}
ActionTimingsId: actionTimingsTag, ActionTriggersId: actionTriggersTag}
aa := map[string]*utils.TPAccountActions{tpaa.KeyId(): tpaa}
if err := self.StorDb.SetTPAccountActions(self.TPid, aa); err != nil {
if self.Verbose {

View File

@@ -19,9 +19,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
package utils
import (
"time"
"fmt"
"strings"
"time"
)
// This file deals with tp_* data definition
@@ -33,31 +33,30 @@ type TPRate struct {
}
// Needed so we make sure we always use SetDurations() on a newly created value
func NewRateSlot( connectFee, rate float64, rateUnit, rateIncrement, grpInterval, rndMethod string, rndDecimals int ) (*RateSlot, error) {
rs := &RateSlot{ ConnectFee: connectFee, Rate: rate, RateUnit: rateUnit, RateIncrement: rateIncrement,
GroupIntervalStart: grpInterval, RoundingMethod: rndMethod, RoundingDecimals: rndDecimals }
func NewRateSlot(connectFee, rate float64, rateUnit, rateIncrement, grpInterval, rndMethod string, rndDecimals int) (*RateSlot, error) {
rs := &RateSlot{ConnectFee: connectFee, Rate: rate, RateUnit: rateUnit, RateIncrement: rateIncrement,
GroupIntervalStart: grpInterval, RoundingMethod: rndMethod, RoundingDecimals: rndDecimals}
if err := rs.SetDurations(); err != nil {
return nil, err
}
return rs, nil
}
type RateSlot struct {
ConnectFee float64 // ConnectFee applied once the call is answered
Rate float64 // Rate applied
RateUnit string // Number of billing units this rate applies to
RateIncrement string // This rate will apply in increments of duration
GroupIntervalStart string // Group position
RoundingMethod string // Use this method to round the cost
RoundingDecimals int // Round the cost number of decimals
rateUnitDur time.Duration
rateIncrementDur time.Duration
groupIntervalStartDur time.Duration
ConnectFee float64 // ConnectFee applied once the call is answered
Rate float64 // Rate applied
RateUnit string // Number of billing units this rate applies to
RateIncrement string // This rate will apply in increments of duration
GroupIntervalStart string // Group position
RoundingMethod string // Use this method to round the cost
RoundingDecimals int // Round the cost number of decimals
rateUnitDur time.Duration
rateIncrementDur time.Duration
groupIntervalStartDur time.Duration
}
// Used to set the durations we need out of strings
func(self *RateSlot) SetDurations() error {
func (self *RateSlot) SetDurations() error {
var err error
if self.rateUnitDur, err = time.ParseDuration(self.RateUnit); err != nil {
return err
@@ -70,16 +69,15 @@ func(self *RateSlot) SetDurations() error {
}
return nil
}
func(self *RateSlot) RateUnitDuration() time.Duration {
func (self *RateSlot) RateUnitDuration() time.Duration {
return self.rateUnitDur
}
func(self *RateSlot) RateIncrementDuration() time.Duration {
func (self *RateSlot) RateIncrementDuration() time.Duration {
return self.rateIncrementDur
}
func(self *RateSlot) GroupIntervalStartDuration() time.Duration {
func (self *RateSlot) GroupIntervalStartDuration() time.Duration {
return self.groupIntervalStartDur
}
type TPDestinationRate struct {
TPid string // Tariff plan id
@@ -103,44 +101,45 @@ type TPTiming struct {
}
type TPRatingPlan struct {
TPid string // Tariff plan id
RatingPlanId string // RatingPlan profile id
RatingPlanBindings []*TPRatingPlanBinding // Set of destinationid-rateid bindings
TPid string // Tariff plan id
RatingPlanId string // RatingPlan profile id
RatingPlanBindings []*TPRatingPlanBinding // Set of destinationid-rateid bindings
}
type TPRatingPlanBinding struct {
DestinationRatesId string // The DestinationRate identity
TimingId string // The timing identity
Weight float64 // Binding priority taken into consideration when more DestinationRates are active on a time slot
timing *TPTiming // Not exporting it via JSON
DestinationRatesId string // The DestinationRate identity
TimingId string // The timing identity
Weight float64 // Binding priority taken into consideration when more DestinationRates are active on a time slot
timing *TPTiming // Not exporting it via JSON
}
func(self *TPRatingPlanBinding) SetTiming(tm *TPTiming) {
func (self *TPRatingPlanBinding) SetTiming(tm *TPTiming) {
self.timing = tm
}
func(self *TPRatingPlanBinding) Timing() *TPTiming {
func (self *TPRatingPlanBinding) Timing() *TPTiming {
return self.timing
}
type TPRatingProfile struct {
TPid string // Tariff plan id
LoadId string // Gives ability to load specific RatingProfile based on load identifier, hence being able to keep history also in stordb
Tenant string // Tenant's Id
TOR string // TypeOfRecord
Direction string // Traffic direction, OUT is the only one supported for now
Subject string // Rating subject, usually the same as account
TPid string // Tariff plan id
LoadId string // Gives ability to load specific RatingProfile based on load identifier, hence being able to keep history also in stordb
Tenant string // Tenant's Id
TOR string // TypeOfRecord
Direction string // Traffic direction, OUT is the only one supported for now
Subject string // Rating subject, usually the same as account
RatingPlanActivations []*TPRatingActivation // Activate rate profiles at specific time
}
// Used as key in nosql db (eg: redis)
func(self *TPRatingProfile) KeyId() string {
func (self *TPRatingProfile) KeyId() string {
return fmt.Sprintf("%s:%s:%s:%s", self.Direction, self.Tenant, self.TOR, self.Subject)
}
type TPRatingActivation struct {
ActivationTime string // Time when this profile will become active, defined as unix epoch time
RatingPlanId string // Id of RatingPlan profile
FallbackSubjects string // So we follow the api
RatingPlanId string // Id of RatingPlan profile
FallbackSubjects string // So we follow the api
}
// Helper to return the subject fallback keys we need in dataDb
@@ -167,8 +166,8 @@ type AttrTPRatingProfileIds struct {
}
type TPActions struct {
TPid string // Tariff plan id
ActionsId string // Actions id
TPid string // Tariff plan id
ActionsId string // Actions id
Actions []*TPAction // Set of actions this Actions profile will perform
}
@@ -186,8 +185,8 @@ type TPAction struct {
}
type TPActionTimings struct {
TPid string // Tariff plan id
ActionTimingsId string // ActionTimings id
TPid string // Tariff plan id
ActionTimingsId string // ActionTimings id
ActionTimings []*TPActionTiming // Set of ActionTiming bindings this profile will group
}
@@ -198,8 +197,8 @@ type TPActionTiming struct {
}
type TPActionTriggers struct {
TPid string // Tariff plan id
ActionTriggersId string // Profile id
TPid string // Tariff plan id
ActionTriggersId string // Profile id
ActionTriggers []*TPActionTrigger // Set of triggers grouped in this profile
}
@@ -223,15 +222,14 @@ type TPAccountActions struct {
ActionTimingsId string // Id of ActionTimings profile to use
ActionTriggersId string // Id of ActionTriggers profile to use
}
// Returns the id used in some nosql dbs (eg: redis)
func(self *TPAccountActions) KeyId() string {
func (self *TPAccountActions) KeyId() string {
return fmt.Sprintf("%s:%s:%s", self.Direction, self.Tenant, self.Account)
}
// Data used to do remote cache reloads via api
type ApiReloadCache struct {
DestinationIds []string
RatingPlanIds []string
DestinationIds []string
RatingPlanIds []string
}

View File

@@ -30,7 +30,7 @@ const (
TBL_TP_ACTION_TRIGGERS = "tp_action_triggers"
TBL_TP_ACCOUNT_ACTIONS = "tp_account_actions"
TBL_CDRS_PRIMARY = "cdrs_primary"
TBL_CDRS_EXTRA = "cdrs_extra"
TBL_CDRS_EXTRA = "cdrs_extra"
TBL_COST_DETAILS = "cost_details"
TBL_RATED_CDRS = "rated_cdrs"
TIMINGS_CSV = "Timings.csv"
@@ -61,5 +61,4 @@ const (
FALLBACK_SEP = ';'
JSON = "json"
MSGPACK = "msgpack"
)

View File

@@ -24,70 +24,70 @@ import (
// CDR as extracted from StorDb. Kinda standard of internal CDR
type RatedCDR struct {
CgrId string
AccId string
CdrHost string
ReqType string
Direction string
Tenant string
TOR string
Account string
Subject string
Destination string
AnswerTime time.Time
Duration int64
ExtraFields map[string]string
Cost float64
CgrId string
AccId string
CdrHost string
ReqType string
Direction string
Tenant string
TOR string
Account string
Subject string
Destination string
AnswerTime time.Time
Duration int64
ExtraFields map[string]string
Cost float64
}
func(ratedCdr *RatedCDR) GetCgrId() string {
func (ratedCdr *RatedCDR) GetCgrId() string {
return ratedCdr.CgrId
}
func(ratedCdr *RatedCDR) GetAccId() string {
func (ratedCdr *RatedCDR) GetAccId() string {
return ratedCdr.AccId
}
func(ratedCdr *RatedCDR) GetCdrHost() string {
func (ratedCdr *RatedCDR) GetCdrHost() string {
return ratedCdr.CdrHost
}
func(ratedCdr *RatedCDR) GetDirection() string {
func (ratedCdr *RatedCDR) GetDirection() string {
return ratedCdr.Direction
}
func(ratedCdr *RatedCDR) GetSubject() string {
func (ratedCdr *RatedCDR) GetSubject() string {
return ratedCdr.Subject
}
func(ratedCdr *RatedCDR) GetAccount() string {
func (ratedCdr *RatedCDR) GetAccount() string {
return ratedCdr.Account
}
func(ratedCdr *RatedCDR) GetDestination() string {
func (ratedCdr *RatedCDR) GetDestination() string {
return ratedCdr.Destination
}
func(ratedCdr *RatedCDR) GetTOR() string {
func (ratedCdr *RatedCDR) GetTOR() string {
return ratedCdr.TOR
}
func(ratedCdr *RatedCDR) GetTenant() string {
func (ratedCdr *RatedCDR) GetTenant() string {
return ratedCdr.Tenant
}
func(ratedCdr *RatedCDR) GetReqType() string {
func (ratedCdr *RatedCDR) GetReqType() string {
return ratedCdr.ReqType
}
func(ratedCdr *RatedCDR) GetAnswerTime() (time.Time, error) {
func (ratedCdr *RatedCDR) GetAnswerTime() (time.Time, error) {
return ratedCdr.AnswerTime, nil
}
func(ratedCdr *RatedCDR) GetDuration() int64 {
func (ratedCdr *RatedCDR) GetDuration() int64 {
return ratedCdr.Duration
}
func(ratedCdr *RatedCDR) GetExtraFields() map[string]string {
func (ratedCdr *RatedCDR) GetExtraFields() map[string]string {
return ratedCdr.ExtraFields
}

View File

@@ -19,8 +19,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
package utils
import (
"time"
"testing"
"time"
)
func TestRatedCDRInterfaces(t *testing.T) {
@@ -29,10 +29,10 @@ func TestRatedCDRInterfaces(t *testing.T) {
}
func TestRatedCdrFields(t *testing.T) {
ratedCdr := RatedCDR{ CgrId: FSCgrId("dsafdsaf"), AccId:"dsafdsaf", CdrHost:"192.168.1.1", ReqType:"rated", Direction:"*out", Tenant:"cgrates.org",
TOR:"call", Account:"1001", Subject:"1001", Destination:"1002", AnswerTime:time.Unix(1383813746,0), Duration:10,
ExtraFields:map[string]string{"field_extr1":"val_extr1", "fieldextr2":"valextr2"}, Cost:1.01,
}
ratedCdr := RatedCDR{CgrId: FSCgrId("dsafdsaf"), AccId: "dsafdsaf", CdrHost: "192.168.1.1", ReqType: "rated", Direction: "*out", Tenant: "cgrates.org",
TOR: "call", Account: "1001", Subject: "1001", Destination: "1002", AnswerTime: time.Unix(1383813746, 0), Duration: 10,
ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01,
}
if ratedCdr.GetCgrId() != "b18944ef4dc618569f24c27b9872827a242bad0c" {
t.Error("Error parsing cdr: ", ratedCdr)
}