mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-15 13:19:53 +05:00
Go fmt on sources
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user