diff --git a/apier/v1/tpaccountactions.go b/apier/v1/tpaccountactions.go index 52a37c40a..4ffa7caee 100644 --- a/apier/v1/tpaccountactions.go +++ b/apier/v1/tpaccountactions.go @@ -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 diff --git a/apier/v1/tpactions.go b/apier/v1/tpactions.go index a8b48f25c..389811e40 100644 --- a/apier/v1/tpactions.go +++ b/apier/v1/tpactions.go @@ -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 diff --git a/apier/v1/tpratingprofiles.go b/apier/v1/tpratingprofiles.go index a56e8d275..ed3ae7d79 100644 --- a/apier/v1/tpratingprofiles.go +++ b/apier/v1/tpratingprofiles.go @@ -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 { diff --git a/apier/v1/tptimings.go b/apier/v1/tptimings.go index 8231004f9..b5d28e61c 100644 --- a/apier/v1/tptimings.go +++ b/apier/v1/tptimings.go @@ -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 } - diff --git a/cdrexporter/csv.go b/cdrexporter/csv.go index 43ed23dcf..2406b2b29 100644 --- a/cdrexporter/csv.go +++ b/cdrexporter/csv.go @@ -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 diff --git a/cdrexporter/csv_test.go b/cdrexporter/csv_test.go index 544b30df2..6b9a4a2a8 100644 --- a/cdrexporter/csv_test.go +++ b/cdrexporter/csv_test.go @@ -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" diff --git a/cdrs/cdrs.go b/cdrs/cdrs.go index 550174c24..9b62c03a6 100644 --- a/cdrs/cdrs.go +++ b/cdrs/cdrs.go @@ -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) } diff --git a/cdrs/cgrcdr.go b/cdrs/cgrcdr.go index 6063ed448..4dd46f4a2 100644 --- a/cdrs/cgrcdr.go +++ b/cdrs/cgrcdr.go @@ -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) diff --git a/cdrs/cgrcdr_test.go b/cdrs/cgrcdr_test.go index 49ccf731f..4b9f46b53 100644 --- a/cdrs/cgrcdr_test.go +++ b/cdrs/cgrcdr_test.go @@ -19,8 +19,8 @@ along with this program. If not, see 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) } diff --git a/engine/loader_csv.go b/engine/loader_csv.go index a2f8a53fb..d87047acf 100644 --- a/engine/loader_csv.go +++ b/engine/loader_csv.go @@ -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)) diff --git a/engine/loader_db.go b/engine/loader_db.go index 888f3c12d..0adb1f550 100644 --- a/engine/loader_db.go +++ b/engine/loader_db.go @@ -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)) diff --git a/engine/loader_helpers.go b/engine/loader_helpers.go index 68a47d1dc..fbff4e31f 100644 --- a/engine/loader_helpers.go +++ b/engine/loader_helpers.go @@ -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 } diff --git a/engine/loader_test.go b/engine/loader_test.go index d7f3e31b3..f1648bd47 100644 --- a/engine/loader_test.go +++ b/engine/loader_test.go @@ -19,11 +19,11 @@ along with this program. If not, see 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) } } -} +} diff --git a/engine/storage_interface.go b/engine/storage_interface.go index 7b99afafe..2e06fa397 100644 --- a/engine/storage_interface.go +++ b/engine/storage_interface.go @@ -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 { diff --git a/engine/storage_sql.go b/engine/storage_sql.go index 37cdd8b5c..9d13c57e6 100644 --- a/engine/storage_sql.go +++ b/engine/storage_sql.go @@ -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) } diff --git a/engine/storage_sql_test.go b/engine/storage_sql_test.go index 202fc451d..d9f12b8ee 100644 --- a/engine/storage_sql_test.go +++ b/engine/storage_sql_test.go @@ -19,11 +19,11 @@ along with this program. If not, see 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") } } - - - - diff --git a/engine/tpimporter_csv.go b/engine/tpimporter_csv.go index 1009eb09f..bb21d771f 100644 --- a/engine/tpimporter_csv.go +++ b/engine/tpimporter_csv.go @@ -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 { diff --git a/utils/apitpdata.go b/utils/apitpdata.go index b032e9b2e..35355dbc6 100644 --- a/utils/apitpdata.go +++ b/utils/apitpdata.go @@ -19,9 +19,9 @@ along with this program. If not, see 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 } - diff --git a/utils/consts.go b/utils/consts.go index 3bbeef81d..3a35bd579 100644 --- a/utils/consts.go +++ b/utils/consts.go @@ -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" - ) diff --git a/utils/ratedcdr.go b/utils/ratedcdr.go index 111b029d5..94801062f 100644 --- a/utils/ratedcdr.go +++ b/utils/ratedcdr.go @@ -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 } diff --git a/utils/ratedcdr_test.go b/utils/ratedcdr_test.go index 8c755175d..eaa82c90a 100644 --- a/utils/ratedcdr_test.go +++ b/utils/ratedcdr_test.go @@ -19,8 +19,8 @@ along with this program. If not, see 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) }