ApierV1.GetCdrs method, CDR fields now exported from rated_cdrs table to reflect derived charging, duration layout, added upgrade script for mysql schema

This commit is contained in:
DanB
2014-05-15 12:13:03 +02:00
parent d6299cd08d
commit d0d49481a2
17 changed files with 336 additions and 119 deletions

View File

@@ -71,7 +71,7 @@ func (self *ApierV1) ExportCdrsToFile(attr utils.AttrExpFileCdrs, reply *utils.E
maskLen = attr.MaskLength
}
cdrs, err := self.CdrDb.GetStoredCdrs(attr.CgrIds, attr.MediationRunId, attr.TOR, attr.CdrHost, attr.CdrSource, attr.ReqType, attr.Direction,
attr.Tenant, attr.Category, attr.Account, attr.Subject, attr.DestinationPrefix, attr.OrderIdStart, attr.OrderIdEnd, tStart, tEnd, attr.SkipErrors, attr.SkipRated)
attr.Tenant, attr.Category, attr.Account, attr.Subject, attr.DestinationPrefix, attr.OrderIdStart, attr.OrderIdEnd, tStart, tEnd, attr.SkipErrors, attr.SkipRated, false)
if err != nil {
return err
} else if len(cdrs) == 0 {

View File

@@ -22,6 +22,7 @@ import (
"fmt"
"github.com/cgrates/cgrates/engine"
"github.com/cgrates/cgrates/utils"
"time"
)
type AttrGetCallCost struct {
@@ -43,3 +44,27 @@ func (apier *ApierV1) GetCallCostLog(attrs AttrGetCallCost, reply *engine.CallCo
}
return nil
}
// Retrieves CDRs based on the filters
func (apier *ApierV1) GetCdrs(attrs utils.AttrGetCdrs, reply *[]*utils.StoredCdr) error {
var tStart, tEnd time.Time
var err error
if len(attrs.TimeStart) != 0 {
if tStart, err = utils.ParseTimeDetectLayout(attrs.TimeStart); err != nil {
return err
}
}
if len(attrs.TimeEnd) != 0 {
if tEnd, err = utils.ParseTimeDetectLayout(attrs.TimeEnd); err != nil {
return err
}
}
if cdrs, err := apier.CdrDb.GetStoredCdrs(attrs.CgrIds, attrs.MediationRunId, attrs.TOR, attrs.CdrHost, attrs.CdrSource, attrs.ReqType, attrs.Direction,
attrs.Tenant, attrs.Category, attrs.Account, attrs.Subject, attrs.DestinationPrefix,
attrs.OrderIdStart, attrs.OrderIdEnd, tStart, tEnd, attrs.SkipErrors, attrs.SkipRated, false); err != nil {
return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
} else {
*reply = cdrs
}
return nil
}

View File

@@ -40,7 +40,7 @@ func TestCsvCdrWriter(t *testing.T) {
}
csvCdrWriter.WriteCdr(ratedCdr)
csvCdrWriter.Close()
expected := `dbafe9c8614c785a65aabd116dd3959c3c56f7f6,default,*voice,dsafdsaf,192.168.1.1,rated,*out,cgrates.org,call,1001,1001,1002,2013-11-07 08:42:25 +0000 UTC,2013-11-07 08:42:26 +0000 UTC,10,1.0100,val_extra3,"",val_extra1`
expected := `dbafe9c8614c785a65aabd116dd3959c3c56f7f6,default,*voice,dsafdsaf,192.168.1.1,rated,*out,cgrates.org,call,1001,1001,1002,2013-11-07 08:42:25 +0000 UTC,2013-11-07 08:42:26 +0000 UTC,10000000000,1.0100,val_extra3,"",val_extra1`
result := strings.TrimSpace(writer.String())
if result != expected {
t.Errorf("Expected: \n%s received: \n%s.", expected, result)

View File

@@ -120,6 +120,8 @@ func (fwv *FixedWidthCdrWriter) cdrFieldValue(cdr *utils.StoredCdr, cfgHdr, layo
}
case utils.COST:
cdrVal = cdr.FormatCost(fwv.costShiftDigits, fwv.roundDecimals)
case utils.DURATION:
cdrVal = cdr.FormatDuration(layout)
case utils.SETUP_TIME:
cdrVal = cdr.SetupTime.Format(layout)
case utils.ANSWER_TIME: // Format time based on layout

View File

@@ -47,7 +47,7 @@ var contentCfgFlds = []*config.CgrXmlCfgCdrField{
&config.CgrXmlCfgCdrField{Name: "TOR", Type: CONSTANT, Value: "02", Width: 2},
&config.CgrXmlCfgCdrField{Name: "SubtypeTOR", Type: CONSTANT, Value: "11", Width: 4, Padding: "right"},
&config.CgrXmlCfgCdrField{Name: "SetupTime", Type: CDRFIELD, Value: utils.SETUP_TIME, Width: 12, Strip: "right", Padding: "right", Layout: "020106150400"},
&config.CgrXmlCfgCdrField{Name: "Duration", Type: CDRFIELD, Value: utils.DURATION, Width: 6, Strip: "right", Padding: "right"},
&config.CgrXmlCfgCdrField{Name: "Duration", Type: CDRFIELD, Value: utils.DURATION, Width: 6, Strip: "right", Padding: "right", Layout: utils.SECONDS},
&config.CgrXmlCfgCdrField{Name: "DataVolume", Type: FILLER, Width: 6},
&config.CgrXmlCfgCdrField{Name: "TaxCode", Type: CONSTANT, Value: "1", Width: 1},
&config.CgrXmlCfgCdrField{Name: "OperatorCode", Type: CDRFIELD, Value: "opercode", Width: 2, Strip: "right", Padding: "right"},

View File

@@ -0,0 +1,48 @@
ALTER TABLE cdrs_primary
CHANGE COLUMN tor category varchar(16) NOT NULL,
CHANGE COLUMN duration `usage` bigint(20) NOT NULL,
ADD COLUMN tor varchar(16) NOT NULL AFTER cgrid;
UPDATE cdrs_primary SET tor="*voice";
ALTER TABLE cost_details
DROP COLUMN accid,
MODIFY COLUMN cost_time datetime NOT NULL AFTER tbid,
CHANGE COLUMN `source` cost_source varchar(64) NOT NULL AFTER cost_time,
MODIFY COLUMN runid varchar(64) NOT NULL AFTER cgrid,
CHANGE COLUMN tor category varchar(32) NOT NULL AFTER tenant,
ADD COLUMN tor varchar(16) NOT NULL after runid,
MODIFY COLUMN direction varchar(8) NOT NULL AFTER tor;
UPDATE cost_details SET tor="*voice";
ALTER TABLE rated_cdrs
MODIFY COLUMN mediation_time datetime NOT NULL AFTER tbid,
MODIFY COLUMN subject varchar(128) NOT NULL,
ADD COLUMN reqtype varchar(24) NOT NULL AFTER runid,
ADD COLUMN direction varchar(8) NOT NULL AFTER reqtype,
ADD COLUMN tenant varchar(64) NOT NULL AFTER direction,
ADD COLUMN category varchar(16) NOT NULL AFTER tenant,
ADD COLUMN account varchar(128) NOT NULL AFTER category,
ADD COLUMN destination varchar(128) NOT NULL AFTER subject,
ADD COLUMN setup_time datetime NOT NULL AFTER destination,
ADD COLUMN answer_time datetime NOT NULL AFTER setup_time,
ADD COLUMN `usage` bigint(20) NOT NULL AFTER answer_time;
ALTER TABLE tp_rates
DROP COLUMN rounding_method,
DROP COLUMN rounding_decimals;
ALTER TABLE tp_destination_rates
ADD COLUMN rounding_method varchar(255) NOT NULL,
ADD COLUMN rounding_decimals tinyint(4) NOT NULL;
ALTER TABLE tp_rating_profiles
DROP KEY tpid_loadid_tenant_tor_dir_subj_atime,
CHANGE COLUMN tor category varchar(16) NOT NULL,
ADD UNIQUE KEY `tpid_loadid_tenant_category_dir_subj_atime` (`tpid`,`loadid`,`tenant`,`category`,`direction`,`subject`,`activation_time`);

View File

@@ -113,7 +113,7 @@ type CdrStorage interface {
SetCdr(*utils.StoredCdr) error
SetRatedCdr(*utils.StoredCdr, string) error
GetStoredCdrs([]string, []string, []string, []string, []string, []string, []string, []string, []string, []string, []string, []string,
int64, int64, time.Time, time.Time, bool, bool) ([]*utils.StoredCdr, error)
int64, int64, time.Time, time.Time, bool, bool, bool) ([]*utils.StoredCdr, error)
RemStoredCdrs([]string) error
}

View File

@@ -23,6 +23,7 @@ import (
"database/sql"
"encoding/json"
"fmt"
"github.com/go-sql-driver/mysql"
"io/ioutil"
"strings"
"time"
@@ -607,35 +608,66 @@ func (self *SQLStorage) SetRatedCdr(storedCdr *utils.StoredCdr, extraInfo string
// ignoreErr - do not consider cdrs with rating errors
// ignoreRated - do not consider cdrs which were already rated, including here the ones with errors
func (self *SQLStorage) GetStoredCdrs(cgrIds, runIds, tors, cdrHosts, cdrSources, reqTypes, directions, tenants, categories, accounts, subjects, destPrefixes []string, orderIdStart, orderIdEnd int64,
timeStart, timeEnd time.Time, ignoreErr, ignoreRated bool) ([]*utils.StoredCdr, error) {
timeStart, timeEnd time.Time, ignoreErr, ignoreRated, ignoreDerived bool) ([]*utils.StoredCdr, error) {
var cdrs []*utils.StoredCdr
q := bytes.NewBufferString(fmt.Sprintf("SELECT %s.cgrid,%s.tbid,%s.tor,%s.accid,%s.cdrhost,%s.cdrsource,%s.reqtype,%s.direction,%s.tenant,%s.category,%s.account,%s.subject,%s.destination,%s.setup_time,%s.answer_time,%s.`usage`,%s.extra_fields,%s.runid,%s.cost FROM %s LEFT JOIN %s ON %s.cgrid=%s.cgrid LEFT JOIN %s ON %s.cgrid=%s.cgrid",
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_EXTRA,
utils.TBL_RATED_CDRS,
utils.TBL_RATED_CDRS,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_EXTRA,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_EXTRA,
utils.TBL_RATED_CDRS,
utils.TBL_CDRS_PRIMARY,
utils.TBL_RATED_CDRS))
var q *bytes.Buffer // Need to query differently since in case of primary, unmediated CDRs some values will be missing
if ignoreDerived {
q = bytes.NewBufferString(fmt.Sprintf("SELECT %s.cgrid,%s.tbid,%s.tor,%s.accid,%s.cdrhost,%s.cdrsource,%s.reqtype,%s.direction,%s.tenant,%s.category,%s.account,%s.subject,%s.destination,%s.setup_time,%s.answer_time,%s.`usage`,%s.extra_fields,%s.runid,%s.cost FROM %s LEFT JOIN %s ON %s.cgrid=%s.cgrid LEFT JOIN %s ON %s.cgrid=%s.cgrid",
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_EXTRA,
utils.TBL_RATED_CDRS,
utils.TBL_RATED_CDRS,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_EXTRA,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_EXTRA,
utils.TBL_RATED_CDRS,
utils.TBL_CDRS_PRIMARY,
utils.TBL_RATED_CDRS))
} else {
q = bytes.NewBufferString(fmt.Sprintf("SELECT %s.cgrid,%s.tbid,%s.tor,%s.accid,%s.cdrhost,%s.cdrsource,%s.reqtype,%s.direction,%s.tenant,%s.category,%s.account,%s.subject,%s.destination,%s.setup_time,%s.answer_time,%s.`usage`,%s.extra_fields,%s.runid,%s.cost FROM %s LEFT JOIN %s ON %s.cgrid=%s.cgrid LEFT JOIN %s ON %s.cgrid=%s.cgrid",
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_PRIMARY,
utils.TBL_RATED_CDRS,
utils.TBL_RATED_CDRS,
utils.TBL_RATED_CDRS,
utils.TBL_RATED_CDRS,
utils.TBL_RATED_CDRS,
utils.TBL_RATED_CDRS,
utils.TBL_RATED_CDRS,
utils.TBL_RATED_CDRS,
utils.TBL_RATED_CDRS,
utils.TBL_RATED_CDRS,
utils.TBL_CDRS_EXTRA,
utils.TBL_RATED_CDRS,
utils.TBL_RATED_CDRS,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_EXTRA,
utils.TBL_CDRS_PRIMARY,
utils.TBL_CDRS_EXTRA,
utils.TBL_RATED_CDRS,
utils.TBL_CDRS_PRIMARY,
utils.TBL_RATED_CDRS))
}
fltr := new(bytes.Buffer)
if len(cgrIds) != 0 {
qIds := bytes.NewBufferString(" (")
@@ -844,6 +876,12 @@ func (self *SQLStorage) GetStoredCdrs(cgrIds, runIds, tors, cdrHosts, cdrSources
}
fltr.WriteString(fmt.Sprintf(" (%s.cost!=-1 OR %s.cost IS NULL)", utils.TBL_RATED_CDRS, utils.TBL_RATED_CDRS))
}
if ignoreDerived {
if fltr.Len() != 0 {
fltr.WriteString(" AND")
}
fltr.WriteString(fmt.Sprintf(" (%s.runid='%s' OR %s.cost IS NULL)", utils.TBL_RATED_CDRS, utils.DEFAULT_RUNID, utils.TBL_RATED_CDRS))
}
if fltr.Len() != 0 {
q.WriteString(fmt.Sprintf(" WHERE %s", fltr.String()))
}
@@ -853,11 +891,11 @@ func (self *SQLStorage) GetStoredCdrs(cgrIds, runIds, tors, cdrHosts, cdrSources
}
defer rows.Close()
for rows.Next() {
var cgrid, tor, accid, cdrhost, cdrsrc, reqtype, direction, tenant, category, account, subject, destination string
var cgrid, tor, accid, cdrhost, cdrsrc, reqtype, direction, tenant, category, account, subject, destination, runid sql.NullString
var extraFields []byte
var setupTime, answerTime time.Time
var runid sql.NullString // So we can export unmediated CDRs
var orderid, usage int64
var setupTime, answerTime mysql.NullTime
var orderid int64
var usage sql.NullInt64
var cost sql.NullFloat64 // So we can export unmediated CDRs
var extraFieldsMp map[string]string
if err := rows.Scan(&cgrid, &orderid, &tor, &accid, &cdrhost, &cdrsrc, &reqtype, &direction, &tenant, &category, &account, &subject, &destination, &setupTime, &answerTime, &usage,
@@ -868,8 +906,10 @@ func (self *SQLStorage) GetStoredCdrs(cgrIds, runIds, tors, cdrHosts, cdrSources
return nil, fmt.Errorf("JSON unmarshal error for cgrid: %s, runid: %v, error: %s", cgrid, runid, err.Error())
}
storCdr := &utils.StoredCdr{
CgrId: cgrid, OrderId: orderid, TOR: tor, AccId: accid, CdrHost: cdrhost, CdrSource: cdrsrc, ReqType: reqtype, Direction: direction, Tenant: tenant,
Category: category, Account: account, Subject: subject, Destination: destination, SetupTime: setupTime, AnswerTime: answerTime, Duration: time.Duration(usage),
CgrId: cgrid.String, OrderId: orderid, TOR: tor.String, AccId: accid.String, CdrHost: cdrhost.String, CdrSource: cdrsrc.String, ReqType: reqtype.String,
Direction: direction.String, Tenant: tenant.String,
Category: category.String, Account: account.String, Subject: subject.String, Destination: destination.String,
SetupTime: setupTime.Time, AnswerTime: answerTime.Time, Duration: time.Duration(usage.Int64),
ExtraFields: extraFieldsMp, MediationRunId: runid.String, Cost: cost.Float64,
}
cdrs = append(cdrs, storCdr)

View File

@@ -33,15 +33,15 @@ README:
Enable these tests by passing '-local' to the go test command
Only database supported for now is MySQL. Postgres could be easily extended if needed.
Only database supported for now is mysqlDb. Postgres could be easily extended if needed.
It is expected that the data folder of CGRateS exists at path /usr/share/cgrates/data.
Prior running the tests, create database and users by running:
mysql -pyourrootpwd < /usr/share/cgrates/storage/mysql/create_mysql_with_users.sql
mysqlDb -pyourrootpwd < /usr/share/cgrates/storage/mysqlDb/create_mysqlDb_with_users.sql
*/
var mysql *MySQLStorage
var mysqlDb *MySQLStorage
func TestCreateTables(t *testing.T) {
if !*testLocal {
@@ -52,16 +52,16 @@ func TestCreateTables(t *testing.T) {
t.Error("Error on opening database connection: ", err)
return
} else {
mysql = d.(*MySQLStorage)
mysqlDb = d.(*MySQLStorage)
}
for _, scriptName := range []string{CREATE_CDRS_TABLES_SQL, CREATE_TARIFFPLAN_TABLES_SQL} {
if err := mysql.CreateTablesFromScript(path.Join(*dataDir, "storage", "mysql", scriptName)); err != nil {
t.Error("Error on mysql creation: ", err.Error())
if err := mysqlDb.CreateTablesFromScript(path.Join(*dataDir, "storage", "mysql", scriptName)); err != nil {
t.Error("Error on mysqlDb creation: ", err.Error())
return // No point in going further
}
}
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 := mysqlDb.Db.Query(fmt.Sprintf("SELECT 1 from %s", tbl)); err != nil {
t.Error(err.Error())
}
}
@@ -73,19 +73,19 @@ func TestRemoveData(t *testing.T) {
}
// Create Timings
tm := &utils.TPTiming{Id: "ALWAYS", StartTime: "00:00:00"}
if err := mysql.SetTPTiming(TEST_SQL, tm); err != nil {
if err := mysqlDb.SetTPTiming(TEST_SQL, tm); err != nil {
t.Error(err.Error())
}
if tmgs, err := mysql.GetTpTimings(TEST_SQL, tm.Id); err != nil {
if tmgs, err := mysqlDb.GetTpTimings(TEST_SQL, tm.Id); err != nil {
t.Error(err.Error())
} else if len(tmgs) == 0 {
t.Error("Could not store TPTiming")
}
// Remove Timings
if err := mysql.RemTPData(utils.TBL_TP_TIMINGS, TEST_SQL, tm.Id); err != nil {
if err := mysqlDb.RemTPData(utils.TBL_TP_TIMINGS, TEST_SQL, tm.Id); err != nil {
t.Error(err.Error())
}
if tmgs, err := mysql.GetTpTimings(TEST_SQL, tm.Id); err != nil {
if tmgs, err := mysqlDb.GetTpTimings(TEST_SQL, tm.Id); err != nil {
t.Error(err.Error())
} else if len(tmgs) != 0 {
t.Error("Did not remove TPTiming")
@@ -93,19 +93,19 @@ func TestRemoveData(t *testing.T) {
// 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", Category: "call", Direction: "*out", Subject: "*any", RatingPlanActivations: ras}
if err := mysql.SetTPRatingProfiles(TEST_SQL, map[string]*utils.TPRatingProfile{rp.KeyId(): rp}); err != nil {
if err := mysqlDb.SetTPRatingProfiles(TEST_SQL, map[string]*utils.TPRatingProfile{rp.KeyId(): rp}); err != nil {
t.Error(err.Error())
}
if rps, err := mysql.GetTpRatingProfiles(rp); err != nil {
if rps, err := mysqlDb.GetTpRatingProfiles(rp); err != nil {
t.Error(err.Error())
} else if len(rps) == 0 {
t.Error("Could not store TPRatingProfile")
}
// Remove RatingProfile
if err := mysql.RemTPData(utils.TBL_TP_RATE_PROFILES, rp.TPid, rp.LoadId, rp.Tenant, rp.Category, rp.Direction, rp.Subject); err != nil {
if err := mysqlDb.RemTPData(utils.TBL_TP_RATE_PROFILES, rp.TPid, rp.LoadId, rp.Tenant, rp.Category, rp.Direction, rp.Subject); err != nil {
t.Error(err.Error())
}
if rps, err := mysql.GetTpRatingProfiles(rp); err != nil {
if rps, err := mysqlDb.GetTpRatingProfiles(rp); err != nil {
t.Error(err.Error())
} else if len(rps) != 0 {
t.Error("Did not remove TPRatingProfile")
@@ -114,19 +114,19 @@ func TestRemoveData(t *testing.T) {
// Create AccountActions
aa := &utils.TPAccountActions{TPid: TEST_SQL, LoadId: TEST_SQL, Tenant: "cgrates.org", Account: "1001",
Direction: "*out", ActionPlanId: "PREPAID_10", ActionTriggersId: "STANDARD_TRIGGERS"}
if err := mysql.SetTPAccountActions(aa.TPid, map[string]*utils.TPAccountActions{aa.KeyId(): aa}); err != nil {
if err := mysqlDb.SetTPAccountActions(aa.TPid, map[string]*utils.TPAccountActions{aa.KeyId(): aa}); err != nil {
t.Error(err.Error())
}
if aas, err := mysql.GetTpAccountActions(aa); err != nil {
if aas, err := mysqlDb.GetTpAccountActions(aa); err != nil {
t.Error(err.Error())
} else if len(aas) == 0 {
t.Error("Could not create TPAccountActions")
}
// Remove AccountActions
if err := mysql.RemTPData(utils.TBL_TP_ACCOUNT_ACTIONS, aa.TPid, aa.LoadId, aa.Tenant, aa.Account, aa.Direction); err != nil {
if err := mysqlDb.RemTPData(utils.TBL_TP_ACCOUNT_ACTIONS, aa.TPid, aa.LoadId, aa.Tenant, aa.Account, aa.Direction); err != nil {
t.Error(err.Error())
}
if aas, err := mysql.GetTpAccountActions(aa); err != nil {
if aas, err := mysqlDb.GetTpAccountActions(aa); err != nil {
t.Error(err.Error())
} else if len(aas) != 0 {
t.Error("Did not remove TPAccountActions")
@@ -157,7 +157,7 @@ func TestSetCdr(t *testing.T) {
utils.ANSWER_TIME: "2013-11-07T08:42:26Z", utils.DURATION: "15s", "field_extr1": "val_extr1", "fieldextr2": "valextr2", "cdrsource": TEST_SQL}
for _, cdr := range []*utils.CgrCdr{cgrCdr1, cgrCdr2, cgrCdr3, cgrCdr4, cgrCdr5} {
if err := mysql.SetCdr(cdr.AsStoredCdr()); err != nil {
if err := mysqlDb.SetCdr(cdr.AsStoredCdr()); err != nil {
t.Error(err.Error())
}
}
@@ -181,7 +181,7 @@ func TestSetCdr(t *testing.T) {
strCdr3.CgrId = utils.Sha1(strCdr3.AccId, strCdr3.SetupTime.String())
for _, cdr := range []*utils.StoredCdr{strCdr1, strCdr2, strCdr3} {
if err := mysql.SetCdr(cdr); err != nil {
if err := mysqlDb.SetCdr(cdr); err != nil {
t.Error(err.Error())
}
}
@@ -211,7 +211,7 @@ func TestSetRatedCdr(t *testing.T) {
strCdr3.CgrId = utils.Sha1(strCdr3.AccId, strCdr3.SetupTime.String())
for _, cdr := range []*utils.StoredCdr{strCdr1, strCdr2, strCdr3} {
if err := mysql.SetRatedCdr(cdr, ""); err != nil {
if err := mysqlDb.SetRatedCdr(cdr, ""); err != nil {
t.Error(err.Error())
}
}
@@ -223,159 +223,174 @@ func TestGetStoredCdrs(t *testing.T) {
}
var timeStart, timeEnd time.Time
// All CDRs, no filter
if storedCdrs, err := mysql.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 8 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on cgrids
if storedCdrs, err := mysql.GetStoredCdrs([]string{utils.Sha1("bbb1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String()),
if storedCdrs, err := mysqlDb.GetStoredCdrs([]string{utils.Sha1("bbb1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String()),
utils.Sha1("bbb2", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())},
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false); err != nil {
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 2 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on cgrids plus reqType
if storedCdrs, err := mysql.GetStoredCdrs([]string{utils.Sha1("bbb1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String()),
if storedCdrs, err := mysqlDb.GetStoredCdrs([]string{utils.Sha1("bbb1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String()),
utils.Sha1("bbb2", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())},
nil, nil, nil, nil, []string{"prepaid"}, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false); err != nil {
nil, nil, nil, nil, []string{"prepaid"}, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 1 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on runId
if storedCdrs, err := mysql.GetStoredCdrs(nil, []string{utils.DEFAULT_RUNID}, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, []string{utils.DEFAULT_RUNID},
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 2 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on TOR
if storedCdrs, err := mysql.GetStoredCdrs(nil, nil, []string{utils.SMS}, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, []string{utils.SMS},
nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 0 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on multiple TOR
if storedCdrs, err := mysql.GetStoredCdrs(nil, nil, []string{utils.SMS, utils.VOICE}, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, []string{utils.SMS, utils.VOICE},
nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 8 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on cdrHost
if storedCdrs, err := mysql.GetStoredCdrs(nil, nil, nil, []string{"192.168.1.2"}, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, []string{"192.168.1.2"},
nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 3 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on multiple cdrHost
if storedCdrs, err := mysql.GetStoredCdrs(nil, nil, nil, []string{"192.168.1.1", "192.168.1.2"}, nil, nil, nil, nil, nil, nil, nil, nil,
0, 0, timeStart, timeEnd, false, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, []string{"192.168.1.1", "192.168.1.2"}, nil, nil, nil, nil, nil, nil, nil, nil,
0, 0, timeStart, timeEnd, false, false, false); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 8 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on cdrSource
if storedCdrs, err := mysql.GetStoredCdrs(nil, nil, nil, nil, []string{"UNKNOWN"}, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, []string{"UNKNOWN"},
nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 1 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on multiple cdrSource
if storedCdrs, err := mysql.GetStoredCdrs(nil, nil, nil, nil, []string{"UNKNOWN", "UNKNOWN2"}, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, []string{"UNKNOWN", "UNKNOWN2"},
nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 2 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on reqType
if storedCdrs, err := mysql.GetStoredCdrs(nil, nil, nil, nil, nil, []string{"prepaid"}, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, []string{"prepaid"},
nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 2 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on multiple reqType
if storedCdrs, err := mysql.GetStoredCdrs(nil, nil, nil, nil, nil, []string{"prepaid", "pseudoprepaid"}, nil, nil, nil, nil, nil, nil,
0, 0, timeStart, timeEnd, false, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, []string{"prepaid", "pseudoprepaid"}, nil, nil, nil, nil, nil, nil,
0, 0, timeStart, timeEnd, false, false, false); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 3 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on direction
if storedCdrs, err := mysql.GetStoredCdrs(nil, nil, nil, nil, nil, nil, []string{"*out"}, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, []string{"*out"}, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 8 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on tenant
if storedCdrs, err := mysql.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, []string{"itsyscom.com"}, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, []string{"itsyscom.com"}, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 3 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on multiple tenants
if storedCdrs, err := mysql.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, []string{"itsyscom.com", "cgrates.org"}, nil, nil, nil, nil,
0, 0, timeStart, timeEnd, false, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, []string{"itsyscom.com", "cgrates.org"}, nil, nil, nil, nil,
0, 0, timeStart, timeEnd, false, false, false); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 8 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on tor
if storedCdrs, err := mysql.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, []string{"premium_call"}, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, []string{"premium_call"},
nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 1 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on multiple tor
if storedCdrs, err := mysql.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, []string{"premium_call", "call"}, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, []string{"premium_call", "call"},
nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 8 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on account
if storedCdrs, err := mysql.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"1002"}, nil, nil, 0, 0, timeStart, timeEnd, false, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"1002"},
nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 3 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on multiple account
if storedCdrs, err := mysql.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"1001", "1002"}, nil, nil, 0, 0, timeStart, timeEnd, false, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"1001", "1002"},
nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 8 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on subject
if storedCdrs, err := mysql.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"1000"}, nil, 0, 0, timeStart, timeEnd, false, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"1000"},
nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 1 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on multiple subject
if storedCdrs, err := mysql.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"1000", "1002"}, nil, 0, 0, timeStart, timeEnd, false, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"1000", "1002"},
nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 3 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on destPrefix
if storedCdrs, err := mysql.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"+498651"}, 0, 0, timeStart, timeEnd, false, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil,
nil, nil, nil, nil, nil, []string{"+498651"}, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 3 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on multiple destPrefixes
if storedCdrs, err := mysql.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"1001", "+498651"}, 0, 0, timeStart, timeEnd, false, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"1001", "+498651"},
0, 0, timeStart, timeEnd, false, false, false); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 4 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on ignoreErr
if storedCdrs, err := mysql.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, true, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, true, false, false); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 8 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on ignoreRated
var orderIdStart, orderIdEnd int64 // Capture also orderIds for the next test
if storedCdrs, err := mysql.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, true); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, true, false); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 5 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
@@ -390,37 +405,45 @@ func TestGetStoredCdrs(t *testing.T) {
}
}
// Filter on orderIdStart
if storedCdrs, err := mysql.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, orderIdStart, 0, timeStart, timeEnd, false, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, orderIdStart, 0, timeStart, timeEnd, false, false, false); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 8 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on orderIdStart and orderIdEnd
if storedCdrs, err := mysql.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, orderIdStart, orderIdEnd+1, timeStart, timeEnd, false, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, orderIdStart, orderIdEnd+1, timeStart, timeEnd,
false, false, false); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 5 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on timeStart
timeStart = time.Date(2013, 11, 8, 8, 0, 0, 0, time.UTC)
if storedCdrs, err := mysql.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 5 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on timeStart and timeEnd
timeEnd = time.Date(2013, 12, 1, 8, 0, 0, 0, time.UTC)
if storedCdrs, err := mysql.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 2 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Combined filter
if storedCdrs, err := mysql.GetStoredCdrs(nil, nil, nil, nil, nil, []string{"rated"}, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, []string{"rated"}, nil, nil, nil, nil, nil,
nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 1 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on ignoreDerived
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, true); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 2 { // ToDo: Recheck this value
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
}
func TestCallCost(t *testing.T) {
@@ -440,10 +463,10 @@ func TestCallCost(t *testing.T) {
},
},
}
if err := mysql.LogCallCost(cgrId, TEST_SQL, TEST_SQL, cc); err != nil {
if err := mysqlDb.LogCallCost(cgrId, TEST_SQL, TEST_SQL, cc); err != nil {
t.Error(err.Error())
}
if ccRcv, err := mysql.GetCallCostLog(cgrId, TEST_SQL, TEST_SQL); err != nil {
if ccRcv, err := mysqlDb.GetCallCostLog(cgrId, TEST_SQL, TEST_SQL); err != nil {
t.Error(err.Error())
} else if !reflect.DeepEqual(cc, ccRcv) {
t.Errorf("Expecting call cost: %v, received: %v", cc, ccRcv)
@@ -456,10 +479,10 @@ func TestRemStoredCdrs(t *testing.T) {
}
var timeStart, timeEnd time.Time
cgrIdB1 := utils.Sha1("bbb1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())
if err := mysql.RemStoredCdrs([]string{cgrIdB1}); err != nil {
if err := mysqlDb.RemStoredCdrs([]string{cgrIdB1}); err != nil {
t.Error(err.Error())
}
if storedCdrs, err := mysql.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 7 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
@@ -476,11 +499,11 @@ func TestRemStoredCdrs(t *testing.T) {
cgrIdA5 := utils.Sha1("aaa5", tm.String())
cgrIdB2 := utils.Sha1("bbb2", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())
cgrIdB3 := utils.Sha1("bbb3", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())
if err := mysql.RemStoredCdrs([]string{cgrIdA1, cgrIdA2, cgrIdA3, cgrIdA4, cgrIdA5,
if err := mysqlDb.RemStoredCdrs([]string{cgrIdA1, cgrIdA2, cgrIdA3, cgrIdA4, cgrIdA5,
cgrIdB2, cgrIdB3}); err != nil {
t.Error(err.Error())
}
if storedCdrs, err := mysql.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 0 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
@@ -502,10 +525,10 @@ func TestSetGetTPActionTriggers(t *testing.T) {
ActionsId: "LOG_BALANCE",
}
mpAtrgs := map[string][]*utils.TPActionTrigger{TEST_SQL: []*utils.TPActionTrigger{atrg}}
if err := mysql.SetTPActionTriggers(TEST_SQL+"1", mpAtrgs); err != nil {
if err := mysqlDb.SetTPActionTriggers(TEST_SQL+"1", mpAtrgs); err != nil {
t.Error("Unexpected error: ", err.Error())
}
if rcvMpAtrgs, err := mysql.GetTpActionTriggers(TEST_SQL+"1", TEST_SQL); err != nil {
if rcvMpAtrgs, err := mysqlDb.GetTpActionTriggers(TEST_SQL+"1", TEST_SQL); err != nil {
t.Error("Unexpected error: ", err.Error())
} else if !reflect.DeepEqual(mpAtrgs, rcvMpAtrgs) {
t.Errorf("Expecting: %v, received: %v", mpAtrgs, rcvMpAtrgs)

View File

@@ -156,7 +156,7 @@ func (self *Mediator) RateCdr(storedCdr *utils.StoredCdr) error {
}
func (self *Mediator) RateCdrs(timeStart, timeEnd time.Time, rerateErrors, rerateRated bool) error {
cdrs, err := self.cdrDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, !rerateErrors, !rerateRated)
cdrs, err := self.cdrDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, !rerateErrors, !rerateRated, true)
if err != nil {
return err
}

View File

@@ -150,12 +150,12 @@ func TestPostCdrs(t *testing.T) {
}
}
time.Sleep(100 * time.Millisecond) // Give time for CDRs to reach database
if storedCdrs, err := cdrStor.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, time.Time{}, time.Time{}, false, false); err != nil {
if storedCdrs, err := cdrStor.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, time.Time{}, time.Time{}, false, false, false); err != nil {
t.Error(err)
} else if len(storedCdrs) != 4 { // Make sure CDRs made it into StorDb
t.Error(fmt.Sprintf("Unexpected number of CDRs stored: %d", len(storedCdrs)))
}
if nonErrorCdrs, err := cdrStor.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, time.Time{}, time.Time{}, true, false); err != nil {
if nonErrorCdrs, err := cdrStor.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, time.Time{}, time.Time{}, true, false, false); err != nil {
t.Error(err)
} else if len(nonErrorCdrs) != 0 { // Just two of them should be without errors
t.Error(fmt.Sprintf("Unexpected number of CDRs stored: %d", len(nonErrorCdrs)))
@@ -178,12 +178,12 @@ func TestInjectCdrs(t *testing.T) {
t.Error(err)
}
}
if storedCdrs, err := cdrStor.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, time.Time{}, time.Time{}, false, false); err != nil {
if storedCdrs, err := cdrStor.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, time.Time{}, time.Time{}, false, false, false); err != nil {
t.Error(err)
} else if len(storedCdrs) != 6 { // Make sure CDRs made it into StorDb
t.Error(fmt.Sprintf("Unexpected number of CDRs stored: %d", len(storedCdrs)))
}
if nonRatedCdrs, err := cdrStor.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, time.Time{}, time.Time{}, true, true); err != nil {
if nonRatedCdrs, err := cdrStor.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, time.Time{}, time.Time{}, true, true, false); err != nil {
t.Error(err)
} else if len(nonRatedCdrs) != 2 { // Just two of them should be non-rated
t.Error(fmt.Sprintf("Unexpected number of CDRs non-rated: %d", len(nonRatedCdrs)))
@@ -215,12 +215,12 @@ func TestRateCdrs(t *testing.T) {
} else if reply != utils.OK {
t.Errorf("Unexpected reply: %s", reply)
}
if nonRatedCdrs, err := cdrStor.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, time.Time{}, time.Time{}, true, true); err != nil {
if nonRatedCdrs, err := cdrStor.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, time.Time{}, time.Time{}, true, true, false); err != nil {
t.Error(err)
} else if len(nonRatedCdrs) != 0 { // Just two of them should be non-rated
} else if len(nonRatedCdrs) != 0 { // All CDRs should be rated
t.Error(fmt.Sprintf("Unexpected number of CDRs non-rated: %d", len(nonRatedCdrs)))
}
if errRatedCdrs, err := cdrStor.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, time.Time{}, time.Time{}, false, true); err != nil {
if errRatedCdrs, err := cdrStor.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, time.Time{}, time.Time{}, false, true, false); err != nil {
t.Error(err)
} else if len(errRatedCdrs) != 4 { // The first 2 with errors should be still there before rerating
t.Error(fmt.Sprintf("Unexpected number of CDRs with errors: %d", len(errRatedCdrs)))
@@ -230,7 +230,7 @@ func TestRateCdrs(t *testing.T) {
} else if reply != utils.OK {
t.Errorf("Unexpected reply: %s", reply)
}
if errRatedCdrs, err := cdrStor.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, time.Time{}, time.Time{}, false, true); err != nil {
if errRatedCdrs, err := cdrStor.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, time.Time{}, time.Time{}, false, true, false); err != nil {
t.Error(err)
} else if len(errRatedCdrs) != 2 {
t.Error(fmt.Sprintf("Unexpected number of CDRs with errors: %d", len(errRatedCdrs)))

View File

@@ -360,6 +360,27 @@ type ExportedFileCdrs struct {
}
type AttrGetCdrs struct {
CgrIds []string // If provided, it will filter based on the cgrids present in list
MediationRunId []string // If provided, it will filter on mediation runid
TOR []string // If provided, filter on TypeOfRecord
CdrHost []string // If provided, it will filter cdrhost
CdrSource []string // If provided, it will filter cdrsource
ReqType []string // If provided, it will fiter reqtype
Direction []string // If provided, it will fiter direction
Tenant []string // If provided, it will filter tenant
Category []string // If provided, it will filter çategory
Account []string // If provided, it will filter account
Subject []string // If provided, it will filter the rating subject
DestinationPrefix []string // If provided, it will filter on destination prefix
OrderIdStart int64 // Export from this order identifier
OrderIdEnd int64 // Export smaller than this order identifier
TimeStart string // If provided, it will represent the starting of the CDRs interval (>=)
TimeEnd string // If provided, it will represent the end of the CDRs interval (<)
SkipErrors bool // Do not export errored CDRs
SkipRated bool // Do not export rated CDRs
}
type AttrRemCdrs struct {
CgrIds []string // List of CgrIds to remove from storeDb
}

View File

@@ -111,6 +111,10 @@ const (
DATA = "*data"
VOICE = "*voice"
TOR = "tor"
HOURS = "hours"
MINUTES = "minutes"
NANOSECONDS = "nanoseconds"
SECONDS = "seconds"
)
var (

View File

@@ -201,6 +201,13 @@ func ParseDurationWithSecs(durStr string) (time.Duration, error) {
return time.ParseDuration(durStr)
}
func ParseDurationWithNanosecs(durStr string) (time.Duration, error) {
if _, err := strconv.Atoi(durStr); err == nil { // No suffix, default to seconds
durStr += "ns"
}
return time.ParseDuration(durStr)
}
func BalanceKey(tenant, account, direction string) string {
return fmt.Sprintf("%s:%s:%s", direction, tenant, account)
}

View File

@@ -59,6 +59,19 @@ func (storedCdr *StoredCdr) FormatCost(shiftDecimals, roundDecimals int) string
return strconv.FormatFloat(cost, 'f', roundDecimals, 64)
}
func (storedCdr *StoredCdr) FormatDuration(layout string) string {
switch layout {
case HOURS:
return strconv.FormatFloat(storedCdr.Duration.Hours(), 'f', -1, 64)
case MINUTES:
return strconv.FormatFloat(storedCdr.Duration.Minutes(), 'f', -1, 64)
case SECONDS:
return strconv.FormatFloat(storedCdr.Duration.Seconds(), 'f', -1, 64)
default:
return strconv.FormatInt(storedCdr.Duration.Nanoseconds(), 10)
}
}
// Used to retrieve fields as string, primary fields are const labeled
func (storedCdr *StoredCdr) FieldAsString(rsrFld *RSRField) string {
switch rsrFld.Id {
@@ -93,7 +106,7 @@ func (storedCdr *StoredCdr) FieldAsString(rsrFld *RSRField) string {
case ANSWER_TIME:
return rsrFld.ParseValue(storedCdr.AnswerTime.String())
case DURATION:
return rsrFld.ParseValue(strconv.FormatFloat(storedCdr.Duration.Seconds(), 'f', -1, 64))
return rsrFld.ParseValue(strconv.FormatInt(storedCdr.Duration.Nanoseconds(), 10))
case MEDI_RUNID:
return rsrFld.ParseValue(storedCdr.MediationRunId)
case COST:
@@ -126,7 +139,7 @@ func (storedCdr *StoredCdr) AsHttpForm() url.Values {
v.Set(DESTINATION, storedCdr.Destination)
v.Set(SETUP_TIME, storedCdr.SetupTime.String())
v.Set(ANSWER_TIME, storedCdr.AnswerTime.String())
v.Set(DURATION, strconv.FormatFloat(storedCdr.Duration.Seconds(), 'f', -1, 64))
v.Set(DURATION, strconv.FormatInt(storedCdr.Duration.Nanoseconds(), 10))
return v
}
@@ -216,7 +229,7 @@ func (storedCdr *StoredCdr) ForkCdr(runId string, reqTypeFld, directionFld, tena
durStr := storedCdr.FieldAsString(durationFld)
if primaryMandatory && len(durStr) == 0 {
return nil, errors.New(fmt.Sprintf("%s:%s:%s", ERR_MANDATORY_IE_MISSING, DURATION, durationFld.Id))
} else if frkStorCdr.Duration, err = ParseDurationWithSecs(durStr); err != nil {
} else if frkStorCdr.Duration, err = ParseDurationWithNanosecs(durStr); err != nil {
return nil, err
}
frkStorCdr.ExtraFields = make(map[string]string, len(extraFlds))

View File

@@ -48,7 +48,7 @@ func TestFieldAsString(t *testing.T) {
cdr.FieldAsString(&RSRField{Id: DESTINATION}) != cdr.Destination ||
cdr.FieldAsString(&RSRField{Id: SETUP_TIME}) != cdr.SetupTime.String() ||
cdr.FieldAsString(&RSRField{Id: ANSWER_TIME}) != cdr.AnswerTime.String() ||
cdr.FieldAsString(&RSRField{Id: DURATION}) != "10" ||
cdr.FieldAsString(&RSRField{Id: DURATION}) != "10000000000" ||
cdr.FieldAsString(&RSRField{Id: MEDI_RUNID}) != cdr.MediationRunId ||
cdr.FieldAsString(&RSRField{Id: COST}) != "1.01" ||
cdr.FieldAsString(&RSRField{Id: "field_extr1"}) != cdr.ExtraFields["field_extr1"] ||
@@ -69,7 +69,7 @@ func TestFieldAsString(t *testing.T) {
cdr.FieldAsString(&RSRField{Id: DESTINATION}) != cdr.Destination,
cdr.FieldAsString(&RSRField{Id: SETUP_TIME}) != cdr.SetupTime.String(),
cdr.FieldAsString(&RSRField{Id: ANSWER_TIME}) != cdr.AnswerTime.String(),
cdr.FieldAsString(&RSRField{Id: DURATION}) != "10",
cdr.FieldAsString(&RSRField{Id: DURATION}) != "10000000000",
cdr.FieldAsString(&RSRField{Id: MEDI_RUNID}) != cdr.MediationRunId,
cdr.FieldAsString(&RSRField{Id: COST}) != "1.01",
cdr.FieldAsString(&RSRField{Id: "field_extr1"}) != cdr.ExtraFields["field_extr1"],
@@ -98,6 +98,16 @@ func TestFormatCost(t *testing.T) {
}
}
func TestFormatDuration(t *testing.T) {
cdr := StoredCdr{Duration: time.Duration(10) * time.Second}
if cdr.FormatDuration(SECONDS) != "10" {
t.Error("Wrong duration format: ", cdr.FormatDuration(SECONDS))
}
if cdr.FormatDuration("default") != "10000000000" {
t.Error("Wrong duration format: ", cdr.FormatDuration("default"))
}
}
func TestStoredCdrAsHttpForm(t *testing.T) {
storCdr := StoredCdr{CgrId: Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, TOR: VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1",
CdrSource: UNIT_TEST, ReqType: "rated", Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002",
@@ -144,8 +154,8 @@ func TestStoredCdrAsHttpForm(t *testing.T) {
if cdrForm.Get(ANSWER_TIME) != "2013-11-07 08:42:26 +0000 UTC" {
t.Errorf("Expected: %s, received: %s", "2013-11-07 08:42:26 +0000 UTC", cdrForm.Get(ANSWER_TIME))
}
if cdrForm.Get(DURATION) != "10" {
t.Errorf("Expected: %s, received: %s", "10", cdrForm.Get(DURATION))
if cdrForm.Get(DURATION) != "10000000000" {
t.Errorf("Expected: %s, received: %s", "10000000000", cdrForm.Get(DURATION))
}
if cdrForm.Get("field_extr1") != "val_extr1" {
t.Errorf("Expected: %s, received: %s", "val_extr1", cdrForm.Get("field_extr1"))

View File

@@ -375,6 +375,30 @@ func TestParseDurationWithSecs(t *testing.T) {
}
}
func TestParseDurationWithNanosecs(t *testing.T) {
durStr := "2"
durExpected := time.Duration(2) * time.Nanosecond
if parsed, err := ParseDurationWithNanosecs(durStr); err != nil {
t.Error(err)
} else if parsed != durExpected {
t.Error("Parsed different than expected")
}
durStr = "2s"
durExpected = time.Duration(2) * time.Second
if parsed, err := ParseDurationWithNanosecs(durStr); err != nil {
t.Error(err)
} else if parsed != durExpected {
t.Error("Parsed different than expected")
}
durStr = "2ms"
durExpected = time.Duration(2) * time.Millisecond
if parsed, err := ParseDurationWithNanosecs(durStr); err != nil {
t.Error(err)
} else if parsed != durExpected {
t.Error("Parsed different than expected")
}
}
func TestMinDuration(t *testing.T) {
d1, _ := time.ParseDuration("1m")
d2, _ := time.ParseDuration("59s")