From 44fa456eb5b8d034a4b408274fd2c7dc9e5eccc3 Mon Sep 17 00:00:00 2001 From: DanB Date: Sun, 22 Mar 2015 18:04:38 +0100 Subject: [PATCH] Moving Cdr* from utils to engine package so we can attach CostDetails to StoredCdr --- apier/v1/apier_local_test.go | 6 +- apier/v1/callsetup.go | 4 +- apier/v1/cdrs.go | 4 +- apier/v1/cdrstatsv1_local_test.go | 10 +- apier/v1/cdrsv1.go | 2 +- apier/v2/cdrs.go | 5 +- apier/v2/cdrs_mysql_local_test.go | 12 +- apier/v2/cdrs_psql_local_test.go | 12 +- cdrc/cdrc.go | 8 +- cdrc/cdrc_test.go | 19 +- cdre/cdrexporter.go | 18 +- cdre/cdrexporter_test.go | 16 +- cdre/csv_test.go | 8 +- cdre/fixedwidth_test.go | 14 +- engine/cdrs.go | 14 +- engine/cdrs_local_test.go | 6 +- engine/cdrstats.go | 2 +- {utils => engine}/cgrcdr.go | 37 +- {utils => engine}/cgrcdr_test.go | 20 +- {utils => engine}/event.go | 7 +- engine/fscdr.go | 4 +- engine/fscdr_test.go | 4 +- engine/loader_local_test.go | 3 - engine/mediator.go | 12 +- engine/mediator_local_test.go | 6 +- {utils => engine}/rawcdr.go | 2 +- engine/responder.go | 18 +- engine/responder_test.go | 4 +- engine/stats.go | 6 +- engine/stats_queue.go | 6 +- engine/stats_test.go | 22 +- engine/storage_interface.go | 6 +- engine/storage_mysql.go | 2 +- engine/storage_mysql_local_test.go | 28 +- engine/storage_postgres.go | 2 +- engine/storage_psql_local_test.go | 28 +- engine/storage_sql.go | 10 +- {utils => engine}/storedcdr.go | 292 +++++------ .../storedcdr_local_test.go | 18 +- engine/storedcdr_test.go | 478 ++++++++++++++++++ general_tests/tutorial_fs_calls_test.go | 2 +- local_test.sh | 4 +- sessionmanager/fsevent.go | 7 +- sessionmanager/fsevent_test.go | 3 +- sessionmanager/fssessionmanager.go | 10 +- sessionmanager/kamailiosm.go | 4 +- sessionmanager/kamevent.go | 9 +- sessionmanager/kamevent_test.go | 3 +- sessionmanager/osipsevent.go | 7 +- sessionmanager/osipsevent_test.go | 5 +- sessionmanager/osipssm.go | 4 +- sessionmanager/session.go | 9 +- sessionmanager/sessionmanager.go | 5 +- utils/storedcdr_test.go | 467 ----------------- 54 files changed, 870 insertions(+), 844 deletions(-) rename {utils => engine}/cgrcdr.go (60%) rename {utils => engine}/cgrcdr_test.go (60%) rename {utils => engine}/event.go (91%) rename {utils => engine}/rawcdr.go (98%) rename {utils => engine}/storedcdr.go (56%) rename utils/utils_local_test.go => engine/storedcdr_local_test.go (56%) create mode 100644 engine/storedcdr_test.go delete mode 100644 utils/storedcdr_test.go diff --git a/apier/v1/apier_local_test.go b/apier/v1/apier_local_test.go index 602950046..92857c141 100644 --- a/apier/v1/apier_local_test.go +++ b/apier/v1/apier_local_test.go @@ -1441,7 +1441,7 @@ func TestLocalGetCdrs(t *testing.T) { if !*testLocal { return } - var reply []*utils.CgrExtCdr + var reply []*engine.CgrExtCdr req := utils.AttrGetCdrs{} if err := rater.Call("ApierV1.GetCdrs", req, &reply); err != nil { t.Error("Unexpected error: ", err.Error()) @@ -1455,7 +1455,7 @@ func TestLocalProcessCdr(t *testing.T) { return } var reply string - cdr := utils.StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", + cdr := engine.StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", CdrSource: "test", ReqType: utils.META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), MediationRunId: utils.DEFAULT_RUNID, Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, RatedAccount: "dan", RatedSubject: "dans", @@ -1465,7 +1465,7 @@ func TestLocalProcessCdr(t *testing.T) { } else if reply != utils.OK { t.Error("Unexpected reply received: ", reply) } - var cdrs []*utils.CgrExtCdr + var cdrs []*engine.CgrExtCdr req := utils.AttrGetCdrs{} if err := rater.Call("ApierV1.GetCdrs", req, &cdrs); err != nil { t.Error("Unexpected error: ", err.Error()) diff --git a/apier/v1/callsetup.go b/apier/v1/callsetup.go index e12f77e44..e1e8c3c97 100644 --- a/apier/v1/callsetup.go +++ b/apier/v1/callsetup.go @@ -19,12 +19,12 @@ along with this program. If not, see package v1 import ( - "github.com/cgrates/cgrates/utils" + "github.com/cgrates/cgrates/engine" "time" ) // Returns MaxSessionTime in seconds, -1 for no limit -func (self *ApierV1) GetMaxSessionTime(cdr utils.StoredCdr, maxSessionTime *float64) error { +func (self *ApierV1) GetMaxSessionTime(cdr engine.StoredCdr, maxSessionTime *float64) error { var maxDur float64 if err := self.Responder.GetDerivedMaxSessionTime(cdr, &maxDur); err != nil { return err diff --git a/apier/v1/cdrs.go b/apier/v1/cdrs.go index daab4e56e..e3f3c98d1 100644 --- a/apier/v1/cdrs.go +++ b/apier/v1/cdrs.go @@ -46,7 +46,7 @@ func (apier *ApierV1) GetCallCostLog(attrs AttrGetCallCost, reply *engine.CallCo } // Retrieves CDRs based on the filters -func (apier *ApierV1) GetCdrs(attrs utils.AttrGetCdrs, reply *[]*utils.CgrExtCdr) error { +func (apier *ApierV1) GetCdrs(attrs utils.AttrGetCdrs, reply *[]*engine.CgrExtCdr) error { cdrsFltr, err := attrs.AsCdrsFilter() if err != nil { return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) @@ -54,7 +54,7 @@ func (apier *ApierV1) GetCdrs(attrs utils.AttrGetCdrs, reply *[]*utils.CgrExtCdr if cdrs, _, err := apier.CdrDb.GetStoredCdrs(cdrsFltr); err != nil { return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) } else if len(cdrs) == 0 { - *reply = make([]*utils.CgrExtCdr, 0) + *reply = make([]*engine.CgrExtCdr, 0) } else { for _, cdr := range cdrs { *reply = append(*reply, cdr.AsCgrExtCdr()) diff --git a/apier/v1/cdrstatsv1_local_test.go b/apier/v1/cdrstatsv1_local_test.go index 6a753de2d..3d0d266c8 100644 --- a/apier/v1/cdrstatsv1_local_test.go +++ b/apier/v1/cdrstatsv1_local_test.go @@ -132,27 +132,27 @@ func TestCDRStatsLclPostCdrs(t *testing.T) { return } httpClient := new(http.Client) - storedCdrs := []*utils.StoredCdr{ - &utils.StoredCdr{CgrId: utils.Sha1("dsafdsafa", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", CdrSource: "test", + storedCdrs := []*engine.StoredCdr{ + &engine.StoredCdr{CgrId: utils.Sha1("dsafdsafa", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", CdrSource: "test", ReqType: utils.META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "+4986517174963", SetupTime: time.Now(), AnswerTime: time.Now(), MediationRunId: utils.DEFAULT_RUNID, Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, RatedAccount: "dan", RatedSubject: "dan", }, - &utils.StoredCdr{CgrId: utils.Sha1("dsafdsafb", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", CdrSource: "test", + &engine.StoredCdr{CgrId: utils.Sha1("dsafdsafb", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", CdrSource: "test", ReqType: utils.META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "+4986517174963", SetupTime: time.Now(), AnswerTime: time.Now(), MediationRunId: utils.DEFAULT_RUNID, Usage: time.Duration(5) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, RatedAccount: "dan", RatedSubject: "dan", }, - &utils.StoredCdr{CgrId: utils.Sha1("dsafdsafc", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", CdrSource: "test", + &engine.StoredCdr{CgrId: utils.Sha1("dsafdsafc", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", CdrSource: "test", ReqType: utils.META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "+4986517174963", SetupTime: time.Now(), AnswerTime: time.Now(), MediationRunId: utils.DEFAULT_RUNID, Usage: time.Duration(30) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, RatedAccount: "dan", RatedSubject: "dan", }, - &utils.StoredCdr{CgrId: utils.Sha1("dsafdsafd", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", CdrSource: "test", + &engine.StoredCdr{CgrId: utils.Sha1("dsafdsafd", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", CdrSource: "test", ReqType: utils.META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "+4986517174963", SetupTime: time.Now(), AnswerTime: time.Time{}, MediationRunId: utils.DEFAULT_RUNID, diff --git a/apier/v1/cdrsv1.go b/apier/v1/cdrsv1.go index 0a5a46f78..361e4072d 100644 --- a/apier/v1/cdrsv1.go +++ b/apier/v1/cdrsv1.go @@ -29,7 +29,7 @@ type CDRSV1 struct { CdrSrv *engine.CDRS } -func (cdrsrv *CDRSV1) ProcessCdr(cdr *utils.StoredCdr, reply *string) error { +func (cdrsrv *CDRSV1) ProcessCdr(cdr *engine.StoredCdr, reply *string) error { if cdrsrv.CdrSrv == nil { return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, "CDRS_NOT_RUNNING") } diff --git a/apier/v2/cdrs.go b/apier/v2/cdrs.go index 68a13c617..253365ac2 100644 --- a/apier/v2/cdrs.go +++ b/apier/v2/cdrs.go @@ -22,11 +22,12 @@ import ( "fmt" "github.com/cgrates/cgrates/apier/v1" + "github.com/cgrates/cgrates/engine" "github.com/cgrates/cgrates/utils" ) // Retrieves CDRs based on the filters -func (apier *ApierV2) GetCdrs(attrs utils.RpcCdrsFilter, reply *[]*utils.CgrExtCdr) error { +func (apier *ApierV2) GetCdrs(attrs utils.RpcCdrsFilter, reply *[]*engine.CgrExtCdr) error { cdrsFltr, err := attrs.AsCdrsFilter() if err != nil { return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) @@ -34,7 +35,7 @@ func (apier *ApierV2) GetCdrs(attrs utils.RpcCdrsFilter, reply *[]*utils.CgrExtC if cdrs, _, err := apier.CdrDb.GetStoredCdrs(cdrsFltr); err != nil { return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) } else if len(cdrs) == 0 { - *reply = make([]*utils.CgrExtCdr, 0) + *reply = make([]*engine.CgrExtCdr, 0) } else { for _, cdr := range cdrs { *reply = append(*reply, cdr.AsCgrExtCdr()) diff --git a/apier/v2/cdrs_mysql_local_test.go b/apier/v2/cdrs_mysql_local_test.go index af032db74..d39c5d665 100644 --- a/apier/v2/cdrs_mysql_local_test.go +++ b/apier/v2/cdrs_mysql_local_test.go @@ -83,7 +83,7 @@ func TestV2CdrsMysqlInjectUnratedCdr(t *testing.T) { } else { mysqlDb = d.(*engine.MySQLStorage) } - strCdr1 := &utils.StoredCdr{CgrId: utils.Sha1("bbb1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String()), + strCdr1 := &engine.StoredCdr{CgrId: utils.Sha1("bbb1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String()), TOR: utils.VOICE, AccId: "bbb1", CdrHost: "192.168.1.1", CdrSource: "UNKNOWN", ReqType: utils.META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC), @@ -122,20 +122,20 @@ func TestV2CdrsMysqlProcessCdr(t *testing.T) { return } var reply string - cdrs := []*utils.StoredCdr{ - &utils.StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", + cdrs := []*engine.StoredCdr{ + &engine.StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", CdrSource: "test", ReqType: utils.META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), MediationRunId: utils.DEFAULT_RUNID, Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, RatedAccount: "dan", RatedSubject: "dans", Rated: true, }, - &utils.StoredCdr{CgrId: utils.Sha1("abcdeftg", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", + &engine.StoredCdr{CgrId: utils.Sha1("abcdeftg", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", CdrSource: "test", ReqType: utils.META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1002", Subject: "1002", Destination: "1002", SetupTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), MediationRunId: utils.DEFAULT_RUNID, Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, RatedAccount: "dan", RatedSubject: "dans", }, - &utils.StoredCdr{CgrId: utils.Sha1("aererfddf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", + &engine.StoredCdr{CgrId: utils.Sha1("aererfddf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", CdrSource: "test", ReqType: utils.META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1003", Subject: "1003", Destination: "1002", SetupTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), MediationRunId: utils.DEFAULT_RUNID, Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, @@ -155,7 +155,7 @@ func TestV2CdrsMysqlGetCdrs(t *testing.T) { if !*testLocal { return } - var reply []*utils.CgrExtCdr + var reply []*engine.CgrExtCdr req := utils.RpcCdrsFilter{} if err := cdrsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { t.Error("Unexpected error: ", err.Error()) diff --git a/apier/v2/cdrs_psql_local_test.go b/apier/v2/cdrs_psql_local_test.go index ae22bc029..500d316d6 100644 --- a/apier/v2/cdrs_psql_local_test.go +++ b/apier/v2/cdrs_psql_local_test.go @@ -77,7 +77,7 @@ func TestV2CdrsPsqlInjectUnratedCdr(t *testing.T) { } else { psqlDb = d.(*engine.PostgresStorage) } - strCdr1 := &utils.StoredCdr{CgrId: utils.Sha1("bbb1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String()), + strCdr1 := &engine.StoredCdr{CgrId: utils.Sha1("bbb1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String()), TOR: utils.VOICE, AccId: "bbb1", CdrHost: "192.168.1.1", CdrSource: "UNKNOWN", ReqType: utils.META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC), @@ -116,20 +116,20 @@ func TestV2CdrsPsqlProcessCdr(t *testing.T) { return } var reply string - cdrs := []*utils.StoredCdr{ - &utils.StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", + cdrs := []*engine.StoredCdr{ + &engine.StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", CdrSource: "test", ReqType: utils.META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), MediationRunId: utils.DEFAULT_RUNID, Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, RatedAccount: "dan", RatedSubject: "dans", Rated: true, }, - &utils.StoredCdr{CgrId: utils.Sha1("abcdeftg", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", + &engine.StoredCdr{CgrId: utils.Sha1("abcdeftg", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", CdrSource: "test", ReqType: utils.META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1002", Subject: "1002", Destination: "1002", SetupTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), MediationRunId: utils.DEFAULT_RUNID, Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, RatedAccount: "dan", RatedSubject: "dans", }, - &utils.StoredCdr{CgrId: utils.Sha1("aererfddf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", + &engine.StoredCdr{CgrId: utils.Sha1("aererfddf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", CdrSource: "test", ReqType: utils.META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1003", Subject: "1003", Destination: "1002", SetupTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), MediationRunId: utils.DEFAULT_RUNID, Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, @@ -149,7 +149,7 @@ func TestV2CdrsPsqlGetCdrs(t *testing.T) { if !*testLocal { return } - var reply []*utils.CgrExtCdr + var reply []*engine.CgrExtCdr req := utils.RpcCdrsFilter{} if err := cdrsPsqlRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { t.Error("Unexpected error: ", err.Error()) diff --git a/cdrc/cdrc.go b/cdrc/cdrc.go index 8d159fd15..c98da3908 100644 --- a/cdrc/cdrc.go +++ b/cdrc/cdrc.go @@ -42,7 +42,7 @@ const ( ) // Populates the -func populateStoredCdrField(cdr *utils.StoredCdr, fieldId, fieldVal string) error { +func populateStoredCdrField(cdr *engine.StoredCdr, fieldId, fieldVal string) error { var err error switch fieldId { case utils.TOR: @@ -215,7 +215,7 @@ func (self *Cdrc) processFile(filePath string) error { engine.Logger.Err(fmt.Sprintf(" Row %d - csv error: %s", procRowNr, err.Error())) continue // Other csv related errors, ignore } - recordCdrs := make([]*utils.StoredCdr, 0) // More CDRs based on the number of filters and field templates + recordCdrs := make([]*engine.StoredCdr, 0) // More CDRs based on the number of filters and field templates for idx, cdrFieldsInst := range self.cdrFields { // Make sure filters are matching filterBreak := false @@ -266,8 +266,8 @@ func (self *Cdrc) processFile(filePath string) error { } // Takes the record out of csv and turns it into http form which can be posted -func (self *Cdrc) recordToStoredCdr(record []string, cdrFields []*config.CfgCdrField) (*utils.StoredCdr, error) { - storedCdr := &utils.StoredCdr{CdrHost: "0.0.0.0", CdrSource: self.cdrSourceId, ExtraFields: make(map[string]string), Cost: -1} +func (self *Cdrc) recordToStoredCdr(record []string, cdrFields []*config.CfgCdrField) (*engine.StoredCdr, error) { + storedCdr := &engine.StoredCdr{CdrHost: "0.0.0.0", CdrSource: self.cdrSourceId, ExtraFields: make(map[string]string), Cost: -1} var err error var lazyHttpFields []*config.CfgCdrField for _, cdrFldCfg := range cdrFields { diff --git a/cdrc/cdrc_test.go b/cdrc/cdrc_test.go index 11bc83485..104be6fd0 100644 --- a/cdrc/cdrc_test.go +++ b/cdrc/cdrc_test.go @@ -24,6 +24,7 @@ import ( "time" "github.com/cgrates/cgrates/config" + "github.com/cgrates/cgrates/engine" "github.com/cgrates/cgrates/utils" ) @@ -43,7 +44,7 @@ func TestRecordForkCdr(t *testing.T) { if err != nil { t.Error("Failed to parse CDR in rated cdr", err) } - expectedCdr := &utils.StoredCdr{ + expectedCdr := &engine.StoredCdr{ CgrId: utils.Sha1(cdrRow[3], time.Date(2013, 2, 3, 19, 50, 0, 0, time.UTC).String()), TOR: cdrRow[2], AccId: cdrRow[3], @@ -77,7 +78,7 @@ func TestDataMultiplyFactor(t *testing.T) { t.Error("Failed to parse CDR in rated cdr", err) } var sTime time.Time - expectedCdr := &utils.StoredCdr{ + expectedCdr := &engine.StoredCdr{ CgrId: utils.Sha1("", sTime.String()), TOR: cdrRow[0], CdrHost: "0.0.0.0", @@ -90,7 +91,7 @@ func TestDataMultiplyFactor(t *testing.T) { t.Errorf("Expected: \n%v, \nreceived: \n%v", expectedCdr, rtCdr) } cdrc.duMultiplyFactor = 1024 - expectedCdr = &utils.StoredCdr{ + expectedCdr = &engine.StoredCdr{ CgrId: utils.Sha1("", sTime.String()), TOR: cdrRow[0], CdrHost: "0.0.0.0", @@ -103,7 +104,7 @@ func TestDataMultiplyFactor(t *testing.T) { t.Errorf("Expected: \n%v, \nreceived: \n%v", expectedCdr, rtCdr) } cdrRow = []string{"*voice", "1"} - expectedCdr = &utils.StoredCdr{ + expectedCdr = &engine.StoredCdr{ CgrId: utils.Sha1("", sTime.String()), TOR: cdrRow[0], CdrHost: "0.0.0.0", @@ -125,8 +126,8 @@ func TestDnTdmCdrs(t *testing.T) { 49497361022,0049LM0409005226,N_MO_MTMB_00-RW-Mobile,02.07.2014 15:24:41,02.07.2014 15:24:41,1,43,Peak,0.021050,49MTMB ` cgrConfig, _ := config.NewDefaultCGRConfig() - eCdrs := []*utils.StoredCdr{ - &utils.StoredCdr{ + eCdrs := []*engine.StoredCdr{ + &engine.StoredCdr{ CgrId: utils.Sha1("49773280254", time.Date(2014, 7, 2, 15, 24, 40, 0, time.UTC).String()), TOR: utils.VOICE, AccId: "49773280254", @@ -144,7 +145,7 @@ func TestDnTdmCdrs(t *testing.T) { Usage: time.Duration(25) * time.Second, Cost: -1, }, - &utils.StoredCdr{ + &engine.StoredCdr{ CgrId: utils.Sha1("49893252121", time.Date(2014, 7, 2, 15, 24, 41, 0, time.UTC).String()), TOR: utils.VOICE, AccId: "49893252121", @@ -162,7 +163,7 @@ func TestDnTdmCdrs(t *testing.T) { Usage: time.Duration(8) * time.Second, Cost: -1, }, - &utils.StoredCdr{ + &engine.StoredCdr{ CgrId: utils.Sha1("49497361022", time.Date(2014, 7, 2, 15, 24, 41, 0, time.UTC).String()), TOR: utils.VOICE, AccId: "49497361022", @@ -207,7 +208,7 @@ func TestDnTdmCdrs(t *testing.T) { cgrConfig.CdrcCdrFields, new(cdrs.CDRS), nil} cdrsContent := bytes.NewReader([]byte(tdmCdrs)) csvReader := csv.NewReader(cdrsContent) - cdrs := make([]*utils.StoredCdr, 0) + cdrs := make([]*engine.StoredCdr, 0) for { cdrCsv, err := csvReader.Read() if err != nil && err == io.EOF { diff --git a/cdre/cdrexporter.go b/cdre/cdrexporter.go index de3017c81..952ba0203 100644 --- a/cdre/cdrexporter.go +++ b/cdre/cdrexporter.go @@ -50,7 +50,7 @@ const ( var err error -func NewCdrExporter(cdrs []*utils.StoredCdr, logDb engine.LogStorage, exportTpl *config.CdreConfig, cdrFormat string, fieldSeparator rune, exportId string, +func NewCdrExporter(cdrs []*engine.StoredCdr, logDb engine.LogStorage, exportTpl *config.CdreConfig, cdrFormat string, fieldSeparator rune, exportId string, dataUsageMultiplyFactor, smsUsageMultiplyFactor, costMultiplyFactor float64, costShiftDigits, roundDecimals, cgrPrecision int, maskDestId string, maskLen int, httpSkipTlsCheck bool) (*CdrExporter, error) { if len(cdrs) == 0 { // Nothing to export return nil, nil @@ -80,7 +80,7 @@ func NewCdrExporter(cdrs []*utils.StoredCdr, logDb engine.LogStorage, exportTpl } type CdrExporter struct { - cdrs []*utils.StoredCdr + cdrs []*engine.StoredCdr logDb engine.LogStorage // Used to extract cost_details if these are requested exportTemplate *config.CdreConfig cdrFormat string // csv, fwv @@ -118,7 +118,7 @@ func (cdre *CdrExporter) getCdrCostDetails(cgrId, runId string) (string, error) return string(ccJson), nil } -func (cdre *CdrExporter) getCombimedCdrFieldVal(processedCdr *utils.StoredCdr, cfgCdrFld *config.CfgCdrField) (string, error) { +func (cdre *CdrExporter) getCombimedCdrFieldVal(processedCdr *engine.StoredCdr, cfgCdrFld *config.CfgCdrField) (string, error) { var combinedVal string // Will result as combination of the field values, filters must match for _, filterRule := range cfgCdrFld.FieldFilter { fltrPass, ftrPassValue := processedCdr.PassesFieldFilter(filterRule) @@ -147,7 +147,7 @@ func (cdre *CdrExporter) maskedDestination(destination string) bool { return false } -func (cdre *CdrExporter) getDateTimeFieldVal(cdr *utils.StoredCdr, cfgCdrFld *config.CfgCdrField) (string, error) { +func (cdre *CdrExporter) getDateTimeFieldVal(cdr *engine.StoredCdr, cfgCdrFld *config.CfgCdrField) (string, error) { if len(cfgCdrFld.Value) == 0 { return "", nil } @@ -168,7 +168,7 @@ func (cdre *CdrExporter) getDateTimeFieldVal(cdr *utils.StoredCdr, cfgCdrFld *co } // Extracts the value specified by cfgHdr out of cdr -func (cdre *CdrExporter) cdrFieldValue(cdr *utils.StoredCdr, cfgCdrFld *config.CfgCdrField) (string, error) { +func (cdre *CdrExporter) cdrFieldValue(cdr *engine.StoredCdr, cfgCdrFld *config.CfgCdrField) (string, error) { for _, fltrRl := range cfgCdrFld.FieldFilter { if fltrPass, _ := cdr.PassesFieldFilter(fltrRl); !fltrPass { return "", fmt.Errorf("Field: %s not matching filter rule %v", fltrRl.Id, fltrRl) @@ -223,13 +223,13 @@ func (cdre *CdrExporter) metaHandler(tag, arg string) (string, error) { case META_NRCDRS: return strconv.Itoa(cdre.numberOfRecords), nil case META_DURCDRS: - emulatedCdr := &utils.StoredCdr{TOR: utils.VOICE, Usage: cdre.totalDuration} + emulatedCdr := &engine.StoredCdr{TOR: utils.VOICE, Usage: cdre.totalDuration} return emulatedCdr.FormatUsage(arg), nil case META_SMSUSAGE: - emulatedCdr := &utils.StoredCdr{TOR: utils.SMS, Usage: cdre.totalSmsUsage} + emulatedCdr := &engine.StoredCdr{TOR: utils.SMS, Usage: cdre.totalSmsUsage} return emulatedCdr.FormatUsage(arg), nil case META_DATAUSAGE: - emulatedCdr := &utils.StoredCdr{TOR: utils.DATA, Usage: cdre.totalDataUsage} + emulatedCdr := &engine.StoredCdr{TOR: utils.DATA, Usage: cdre.totalDataUsage} return emulatedCdr.FormatUsage(arg), nil case META_COSTCDRS: return strconv.FormatFloat(utils.Round(cdre.totalCost, cdre.roundDecimals, utils.ROUNDING_MIDDLE), 'f', -1, 64), nil @@ -302,7 +302,7 @@ func (cdre *CdrExporter) composeTrailer() error { } // Write individual cdr into content buffer, build stats -func (cdre *CdrExporter) processCdr(cdr *utils.StoredCdr) error { +func (cdre *CdrExporter) processCdr(cdr *engine.StoredCdr) error { if cdr == nil || len(cdr.CgrId) == 0 { // We do not export empty CDRs return nil } diff --git a/cdre/cdrexporter_test.go b/cdre/cdrexporter_test.go index f49dd0100..caf3604dd 100644 --- a/cdre/cdrexporter_test.go +++ b/cdre/cdrexporter_test.go @@ -30,24 +30,24 @@ import ( func TestCdreGetCombimedCdrFieldVal(t *testing.T) { logDb, _ := engine.NewMapStorage() cfg, _ := config.NewDefaultCGRConfig() - cdrs := []*utils.StoredCdr{ - &utils.StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Unix(1383813745, 0).UTC().String()), TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", + cdrs := []*engine.StoredCdr{ + &engine.StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Unix(1383813745, 0).UTC().String()), TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", ReqType: utils.META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Unix(1383813745, 0).UTC(), AnswerTime: time.Unix(1383813746, 0).UTC(), Usage: time.Duration(10) * time.Second, MediationRunId: "RUN_RTL", Cost: 1.01}, - &utils.StoredCdr{CgrId: utils.Sha1("dsafdsaf2", time.Unix(1383813745, 0).UTC().String()), TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", + &engine.StoredCdr{CgrId: utils.Sha1("dsafdsaf2", time.Unix(1383813745, 0).UTC().String()), TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", ReqType: utils.META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Unix(1383813745, 0).UTC(), AnswerTime: time.Unix(1383813746, 0).UTC(), Usage: time.Duration(10) * time.Second, MediationRunId: "CUSTOMER1", Cost: 2.01}, - &utils.StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Unix(1383813745, 0).UTC().String()), TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", + &engine.StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Unix(1383813745, 0).UTC().String()), TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", ReqType: utils.META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Unix(1383813745, 0).UTC(), AnswerTime: time.Unix(1383813746, 0).UTC(), Usage: time.Duration(10) * time.Second, MediationRunId: "CUSTOMER1", Cost: 3.01}, - &utils.StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Unix(1383813745, 0).UTC().String()), TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", + &engine.StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Unix(1383813745, 0).UTC().String()), TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", ReqType: utils.META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Unix(1383813745, 0).UTC(), AnswerTime: time.Unix(1383813746, 0).UTC(), Usage: time.Duration(10) * time.Second, MediationRunId: utils.DEFAULT_RUNID, Cost: 4.01}, - &utils.StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Unix(1383813745, 0).UTC().String()), TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", + &engine.StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Unix(1383813745, 0).UTC().String()), TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", ReqType: utils.META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1000", Subject: "1001", Destination: "1002", SetupTime: time.Unix(1383813745, 0).UTC(), AnswerTime: time.Unix(1383813746, 0).UTC(), Usage: time.Duration(10) * time.Second, MediationRunId: "RETAIL1", Cost: 5.01}, @@ -77,7 +77,7 @@ func TestCdreGetCombimedCdrFieldVal(t *testing.T) { func TestGetDateTimeFieldVal(t *testing.T) { cdreTst := new(CdrExporter) - cdrTst := &utils.StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Unix(1383813745, 0).UTC().String()), TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", + cdrTst := &engine.StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Unix(1383813745, 0).UTC().String()), TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", ReqType: utils.META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Unix(1383813745, 0).UTC(), AnswerTime: time.Unix(1383813746, 0).UTC(), Usage: time.Duration(10) * time.Second, MediationRunId: utils.DEFAULT_RUNID, Cost: 1.01, @@ -106,7 +106,7 @@ func TestGetDateTimeFieldVal(t *testing.T) { func TestCdreCdrFieldValue(t *testing.T) { cdre := new(CdrExporter) - cdr := &utils.StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Unix(1383813745, 0).UTC().String()), TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", + cdr := &engine.StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Unix(1383813745, 0).UTC().String()), TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", ReqType: utils.META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Unix(1383813745, 0).UTC(), AnswerTime: time.Unix(1383813746, 0).UTC(), Usage: time.Duration(10) * time.Second, MediationRunId: utils.DEFAULT_RUNID, Cost: 1.01} diff --git a/cdre/csv_test.go b/cdre/csv_test.go index fe0407c8b..b309d4152 100644 --- a/cdre/csv_test.go +++ b/cdre/csv_test.go @@ -34,13 +34,13 @@ func TestCsvCdrWriter(t *testing.T) { writer := &bytes.Buffer{} cfg, _ := config.NewDefaultCGRConfig() logDb, _ := engine.NewMapStorage() - storedCdr1 := &utils.StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Unix(1383813745, 0).UTC().String()), TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", + storedCdr1 := &engine.StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Unix(1383813745, 0).UTC().String()), TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", ReqType: utils.META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Unix(1383813745, 0).UTC(), AnswerTime: time.Unix(1383813746, 0).UTC(), Usage: time.Duration(10) * time.Second, MediationRunId: utils.DEFAULT_RUNID, ExtraFields: map[string]string{"extra1": "val_extra1", "extra2": "val_extra2", "extra3": "val_extra3"}, Cost: 1.01, } - cdre, err := NewCdrExporter([]*utils.StoredCdr{storedCdr1}, logDb, cfg.CdreProfiles["*default"], utils.CSV, ',', "firstexport", 0.0, 0.0, 0.0, 0, 4, + cdre, err := NewCdrExporter([]*engine.StoredCdr{storedCdr1}, logDb, cfg.CdreProfiles["*default"], utils.CSV, ',', "firstexport", 0.0, 0.0, 0.0, 0, 4, cfg.RoundingDecimals, "", 0, cfg.HttpSkipTlsVerify) if err != nil { t.Error("Unexpected error received: ", err) @@ -63,13 +63,13 @@ func TestAlternativeFieldSeparator(t *testing.T) { writer := &bytes.Buffer{} cfg, _ := config.NewDefaultCGRConfig() logDb, _ := engine.NewMapStorage() - storedCdr1 := &utils.StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Unix(1383813745, 0).UTC().String()), TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", + storedCdr1 := &engine.StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Unix(1383813745, 0).UTC().String()), TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", ReqType: utils.META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Unix(1383813745, 0).UTC(), AnswerTime: time.Unix(1383813746, 0).UTC(), Usage: time.Duration(10) * time.Second, MediationRunId: utils.DEFAULT_RUNID, ExtraFields: map[string]string{"extra1": "val_extra1", "extra2": "val_extra2", "extra3": "val_extra3"}, Cost: 1.01, } - cdre, err := NewCdrExporter([]*utils.StoredCdr{storedCdr1}, logDb, cfg.CdreProfiles["*default"], utils.CSV, '|', "firstexport", 0.0, 0.0, 0.0, 0, 4, cfg.RoundingDecimals, "", 0, cfg.HttpSkipTlsVerify) + cdre, err := NewCdrExporter([]*engine.StoredCdr{storedCdr1}, logDb, cfg.CdreProfiles["*default"], utils.CSV, '|', "firstexport", 0.0, 0.0, 0.0, 0, 4, cfg.RoundingDecimals, "", 0, cfg.HttpSkipTlsVerify) if err != nil { t.Error("Unexpected error received: ", err) } diff --git a/cdre/fixedwidth_test.go b/cdre/fixedwidth_test.go index 835163334..4336ceb4b 100644 --- a/cdre/fixedwidth_test.go +++ b/cdre/fixedwidth_test.go @@ -119,7 +119,7 @@ func TestWriteCdr(t *testing.T) { ContentFields: contentCfgFlds, TrailerFields: trailerCfgFlds, } - cdr := &utils.StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC).String()), + cdr := &engine.StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC).String()), TOR: utils.VOICE, OrderId: 1, AccId: "dsafdsaf", CdrHost: "192.168.1.1", ReqType: utils.META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", @@ -128,7 +128,7 @@ func TestWriteCdr(t *testing.T) { Usage: time.Duration(10) * time.Second, MediationRunId: utils.DEFAULT_RUNID, Cost: 2.34567, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, } - cdre, err := NewCdrExporter([]*utils.StoredCdr{cdr}, logDb, cdreCfg, utils.CDRE_FIXED_WIDTH, ',', "fwv_1", 0.0, 0.0, 0.0, 0, 4, cfg.RoundingDecimals, "", -1, cfg.HttpSkipTlsVerify) + cdre, err := NewCdrExporter([]*engine.StoredCdr{cdr}, logDb, cdreCfg, utils.CDRE_FIXED_WIDTH, ',', "fwv_1", 0.0, 0.0, 0.0, 0, 4, cfg.RoundingDecimals, "", -1, cfg.HttpSkipTlsVerify) if err != nil { t.Error(err) } @@ -177,7 +177,7 @@ func TestWriteCdrs(t *testing.T) { ContentFields: contentCfgFlds, TrailerFields: trailerCfgFlds, } - cdr1 := &utils.StoredCdr{CgrId: utils.Sha1("aaa1", time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC).String()), + cdr1 := &engine.StoredCdr{CgrId: utils.Sha1("aaa1", time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC).String()), TOR: utils.VOICE, OrderId: 2, AccId: "aaa1", CdrHost: "192.168.1.1", ReqType: utils.META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1010", SetupTime: time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC), @@ -185,7 +185,7 @@ func TestWriteCdrs(t *testing.T) { Usage: time.Duration(10) * time.Second, MediationRunId: utils.DEFAULT_RUNID, Cost: 2.25, ExtraFields: map[string]string{"productnumber": "12341", "fieldextr2": "valextr2"}, } - cdr2 := &utils.StoredCdr{CgrId: utils.Sha1("aaa2", time.Date(2013, 11, 7, 7, 42, 20, 0, time.UTC).String()), + cdr2 := &engine.StoredCdr{CgrId: utils.Sha1("aaa2", time.Date(2013, 11, 7, 7, 42, 20, 0, time.UTC).String()), TOR: utils.VOICE, OrderId: 4, AccId: "aaa2", CdrHost: "192.168.1.2", ReqType: utils.META_PREPAID, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1002", Subject: "1002", Destination: "1011", SetupTime: time.Date(2013, 11, 7, 7, 42, 20, 0, time.UTC), @@ -193,8 +193,8 @@ func TestWriteCdrs(t *testing.T) { Usage: time.Duration(5) * time.Minute, MediationRunId: utils.DEFAULT_RUNID, Cost: 1.40001, ExtraFields: map[string]string{"productnumber": "12342", "fieldextr2": "valextr2"}, } - cdr3 := &utils.StoredCdr{} - cdr4 := &utils.StoredCdr{CgrId: utils.Sha1("aaa3", time.Date(2013, 11, 7, 9, 42, 18, 0, time.UTC).String()), + cdr3 := &engine.StoredCdr{} + cdr4 := &engine.StoredCdr{CgrId: utils.Sha1("aaa3", time.Date(2013, 11, 7, 9, 42, 18, 0, time.UTC).String()), TOR: utils.VOICE, OrderId: 3, AccId: "aaa4", CdrHost: "192.168.1.4", ReqType: utils.META_POSTPAID, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1004", Subject: "1004", Destination: "1013", SetupTime: time.Date(2013, 11, 7, 9, 42, 18, 0, time.UTC), @@ -203,7 +203,7 @@ func TestWriteCdrs(t *testing.T) { ExtraFields: map[string]string{"productnumber": "12344", "fieldextr2": "valextr2"}, } cfg, _ := config.NewDefaultCGRConfig() - cdre, err := NewCdrExporter([]*utils.StoredCdr{cdr1, cdr2, cdr3, cdr4}, logDb, cdreCfg, utils.CDRE_FIXED_WIDTH, ',', + cdre, err := NewCdrExporter([]*engine.StoredCdr{cdr1, cdr2, cdr3, cdr4}, logDb, cdreCfg, utils.CDRE_FIXED_WIDTH, ',', "fwv_1", 0.0, 0.0, 0.0, 0, 4, cfg.RoundingDecimals, "", -1, cfg.HttpSkipTlsVerify) if err != nil { t.Error(err) diff --git a/engine/cdrs.go b/engine/cdrs.go index c1e0ceef7..b4a6142d6 100644 --- a/engine/cdrs.go +++ b/engine/cdrs.go @@ -35,14 +35,14 @@ var ( ) // Returns error if not able to properly store the CDR, mediation is async since we can always recover offline -func storeAndMediate(storedCdr *utils.StoredCdr) error { +func storeAndMediate(storedCdr *StoredCdr) error { if !cfg.CDRSStoreDisable { if err := storage.SetCdr(storedCdr); err != nil { return err } } if stats != nil { - go func(storedCdr *utils.StoredCdr) { + go func(storedCdr *StoredCdr) { if err := stats.AppendCDR(storedCdr, nil); err != nil { Logger.Err(fmt.Sprintf(" Could not append cdr to stats: %s", err.Error())) } @@ -52,7 +52,7 @@ func storeAndMediate(storedCdr *utils.StoredCdr) error { replicateCdr(storedCdr, cfg.CDRSCdrReplication) } if cfg.CDRSMediator == utils.INTERNAL { - go func(storedCdr *utils.StoredCdr) { + go func(storedCdr *StoredCdr) { if err := medi.RateCdr(storedCdr, true); err != nil { Logger.Err(fmt.Sprintf(" Could not run mediation on CDR: %s", err.Error())) } @@ -62,13 +62,13 @@ func storeAndMediate(storedCdr *utils.StoredCdr) error { } // ToDo: Add websocket support -func replicateCdr(cdr *utils.StoredCdr, replCfgs []*config.CdrReplicationCfg) error { +func replicateCdr(cdr *StoredCdr, replCfgs []*config.CdrReplicationCfg) error { for _, rplCfg := range replCfgs { switch rplCfg.Transport { case utils.META_HTTP_POST: httpClient := new(http.Client) errChan := make(chan error) - go func(cdr *utils.StoredCdr, rplCfg *config.CdrReplicationCfg, errChan chan error) { + go func(cdr *StoredCdr, rplCfg *config.CdrReplicationCfg, errChan chan error) { if _, err := httpClient.PostForm(fmt.Sprintf("http://%s/cdr_post", rplCfg.Server), cdr.AsHttpForm()); err != nil { Logger.Err(fmt.Sprintf(" Replicating CDR: %+v, got error: %s", cdr, err.Error())) errChan <- err @@ -85,7 +85,7 @@ func replicateCdr(cdr *utils.StoredCdr, replCfgs []*config.CdrReplicationCfg) er // Handler for generic cgr cdr http func cgrCdrHandler(w http.ResponseWriter, r *http.Request) { - cgrCdr, err := utils.NewCgrCdrFromHttpReq(r) + cgrCdr, err := NewCgrCdrFromHttpReq(r) if err != nil { Logger.Err(fmt.Sprintf(" Could not create CDR entry: %s", err.Error())) } @@ -134,6 +134,6 @@ func (cdrs *CDRS) RegisterHanlersToServer(server *Server) { } // Used to internally process CDR -func (cdrs *CDRS) ProcessCdr(cdr *utils.StoredCdr) error { +func (cdrs *CDRS) ProcessCdr(cdr *StoredCdr) error { return storeAndMediate(cdr) } diff --git a/engine/cdrs_local_test.go b/engine/cdrs_local_test.go index 621fea3ff..b407ea0ef 100644 --- a/engine/cdrs_local_test.go +++ b/engine/cdrs_local_test.go @@ -90,7 +90,7 @@ func TestCdrsHttpJsonRpcCdrReplication(t *testing.T) { if err != nil { t.Fatal("Could not connect to rater: ", err.Error()) } - testCdr1 := &utils.StoredCdr{CgrId: utils.Sha1("httpjsonrpc1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String()), + testCdr1 := &StoredCdr{CgrId: utils.Sha1("httpjsonrpc1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String()), TOR: utils.VOICE, AccId: "httpjsonrpc1", CdrHost: "192.168.1.1", CdrSource: "UNKNOWN", ReqType: utils.META_PSEUDOPREPAID, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC), @@ -102,7 +102,7 @@ func TestCdrsHttpJsonRpcCdrReplication(t *testing.T) { } else if reply != utils.OK { t.Error("Unexpected reply received: ", reply) } - var rcvedCdrs []*utils.CgrExtCdr + var rcvedCdrs []*CgrExtCdr if err := cdrsHttpJsonRpc.Call("ApierV2.GetCdrs", utils.RpcCdrsFilter{CgrIds: []string{testCdr1.CgrId}}, &rcvedCdrs); err != nil { t.Error("Unexpected error: ", err.Error()) } else if len(rcvedCdrs) != 1 { @@ -111,7 +111,7 @@ func TestCdrsHttpJsonRpcCdrReplication(t *testing.T) { } /* -&utils.StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", +&StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", CdrSource: "test", ReqType: utils.META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), MediationRunId: utils.DEFAULT_RUNID, Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, diff --git a/engine/cdrstats.go b/engine/cdrstats.go index 8fef5d420..469abd9e9 100644 --- a/engine/cdrstats.go +++ b/engine/cdrstats.go @@ -75,7 +75,7 @@ type CdrStats struct { Triggers ActionTriggerPriotityList } -func (cs *CdrStats) AcceptCdr(cdr *utils.StoredCdr) bool { +func (cs *CdrStats) AcceptCdr(cdr *StoredCdr) bool { if cdr == nil { return false } diff --git a/utils/cgrcdr.go b/engine/cgrcdr.go similarity index 60% rename from utils/cgrcdr.go rename to engine/cgrcdr.go index 4126ab328..c49973c18 100644 --- a/utils/cgrcdr.go +++ b/engine/cgrcdr.go @@ -16,9 +16,10 @@ You should have received a copy of the GNU General Public License along with this program. If not, see */ -package utils +package engine import ( + "github.com/cgrates/cgrates/utils" "net/http" ) @@ -29,7 +30,7 @@ func NewCgrCdrFromHttpReq(req *http.Request) (CgrCdr, error) { } } cgrCdr := make(CgrCdr) - cgrCdr[CDRHOST] = req.RemoteAddr + cgrCdr[utils.CDRHOST] = req.RemoteAddr for k, vals := range req.Form { cgrCdr[k] = vals[0] // We only support the first value for now, if more are provided it is considered remote's fault } @@ -39,14 +40,14 @@ func NewCgrCdrFromHttpReq(req *http.Request) (CgrCdr, error) { type CgrCdr map[string]string func (cgrCdr CgrCdr) getCgrId() string { - setupTime, _ := ParseTimeDetectLayout(cgrCdr[SETUP_TIME]) - return Sha1(cgrCdr[ACCID], setupTime.UTC().String()) + setupTime, _ := utils.ParseTimeDetectLayout(cgrCdr[utils.SETUP_TIME]) + return utils.Sha1(cgrCdr[utils.ACCID], setupTime.UTC().String()) } func (cgrCdr CgrCdr) getExtraFields() map[string]string { extraFields := make(map[string]string) for k, v := range cgrCdr { - if !IsSliceMember(PrimaryCdrFields, k) { + if !utils.IsSliceMember(utils.PrimaryCdrFields, k) { extraFields[k] = v } } @@ -56,20 +57,20 @@ func (cgrCdr CgrCdr) getExtraFields() map[string]string { func (cgrCdr CgrCdr) AsStoredCdr() *StoredCdr { storCdr := new(StoredCdr) storCdr.CgrId = cgrCdr.getCgrId() - storCdr.TOR = cgrCdr[TOR] - storCdr.AccId = cgrCdr[ACCID] - storCdr.CdrHost = cgrCdr[CDRHOST] - storCdr.CdrSource = cgrCdr[CDRSOURCE] - storCdr.ReqType = cgrCdr[REQTYPE] + storCdr.TOR = cgrCdr[utils.TOR] + storCdr.AccId = cgrCdr[utils.ACCID] + storCdr.CdrHost = cgrCdr[utils.CDRHOST] + storCdr.CdrSource = cgrCdr[utils.CDRSOURCE] + storCdr.ReqType = cgrCdr[utils.REQTYPE] storCdr.Direction = "*out" - storCdr.Tenant = cgrCdr[TENANT] - storCdr.Category = cgrCdr[CATEGORY] - storCdr.Account = cgrCdr[ACCOUNT] - storCdr.Subject = cgrCdr[SUBJECT] - storCdr.Destination = cgrCdr[DESTINATION] - storCdr.SetupTime, _ = ParseTimeDetectLayout(cgrCdr[SETUP_TIME]) // Not interested to process errors, should do them if necessary in a previous step - storCdr.AnswerTime, _ = ParseTimeDetectLayout(cgrCdr[ANSWER_TIME]) - storCdr.Usage, _ = ParseDurationWithSecs(cgrCdr[USAGE]) + storCdr.Tenant = cgrCdr[utils.TENANT] + storCdr.Category = cgrCdr[utils.CATEGORY] + storCdr.Account = cgrCdr[utils.ACCOUNT] + storCdr.Subject = cgrCdr[utils.SUBJECT] + storCdr.Destination = cgrCdr[utils.DESTINATION] + storCdr.SetupTime, _ = utils.ParseTimeDetectLayout(cgrCdr[utils.SETUP_TIME]) // Not interested to process errors, should do them if necessary in a previous step + storCdr.AnswerTime, _ = utils.ParseTimeDetectLayout(cgrCdr[utils.ANSWER_TIME]) + storCdr.Usage, _ = utils.ParseDurationWithSecs(cgrCdr[utils.USAGE]) storCdr.ExtraFields = cgrCdr.getExtraFields() storCdr.Cost = -1 return storCdr diff --git a/utils/cgrcdr_test.go b/engine/cgrcdr_test.go similarity index 60% rename from utils/cgrcdr_test.go rename to engine/cgrcdr_test.go index 35dfea533..fda8cfcfa 100644 --- a/utils/cgrcdr_test.go +++ b/engine/cgrcdr_test.go @@ -16,9 +16,10 @@ You should have received a copy of the GNU General Public License along with this program. If not, see */ -package utils +package engine import ( + "github.com/cgrates/cgrates/utils" "reflect" "testing" "time" @@ -33,13 +34,18 @@ func TestCgrCdrInterfaces(t *testing.T) { } func TestCgrCdrAsStoredCdr(t *testing.T) { - cgrCdr := CgrCdr{TOR: VOICE, ACCID: "dsafdsaf", CDRHOST: "192.168.1.1", CDRSOURCE: "internal_test", REQTYPE: META_RATED, DIRECTION: "*out", TENANT: "cgrates.org", CATEGORY: "call", - ACCOUNT: "1001", SUBJECT: "1001", DESTINATION: "1002", SETUP_TIME: "2013-11-07T08:42:20Z", ANSWER_TIME: "2013-11-07T08:42:26Z", USAGE: "10", + cgrCdr := CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "dsafdsaf", utils.CDRHOST: "192.168.1.1", utils.CDRSOURCE: "internal_test", utils.REQTYPE: utils.META_RATED, + utils.DIRECTION: utils.OUT, + utils.TENANT: "cgrates.org", utils.CATEGORY: "call", + utils.ACCOUNT: "1001", utils.SUBJECT: "1001", utils.DESTINATION: "1002", utils.SETUP_TIME: "2013-11-07T08:42:20Z", utils.ANSWER_TIME: "2013-11-07T08:42:26Z", + utils.USAGE: "10", "field_extr1": "val_extr1", "fieldextr2": "valextr2"} - setupTime, _ := ParseTimeDetectLayout(cgrCdr["setup_time"]) - expctRtCdr := &StoredCdr{CgrId: Sha1(cgrCdr["accid"], setupTime.String()), TOR: VOICE, AccId: cgrCdr["accid"], CdrHost: cgrCdr["cdrhost"], CdrSource: cgrCdr["cdrsource"], ReqType: cgrCdr["reqtype"], - Direction: cgrCdr[DIRECTION], Tenant: cgrCdr["tenant"], Category: cgrCdr[CATEGORY], Account: cgrCdr["account"], Subject: cgrCdr["subject"], - Destination: cgrCdr["destination"], SetupTime: time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), Usage: time.Duration(10) * time.Second, + setupTime, _ := utils.ParseTimeDetectLayout(cgrCdr["setup_time"]) + expctRtCdr := &StoredCdr{CgrId: utils.Sha1(cgrCdr["accid"], setupTime.String()), TOR: utils.VOICE, AccId: cgrCdr["accid"], CdrHost: cgrCdr["cdrhost"], CdrSource: cgrCdr["cdrsource"], + ReqType: cgrCdr["reqtype"], + Direction: cgrCdr[utils.DIRECTION], Tenant: cgrCdr["tenant"], Category: cgrCdr[utils.CATEGORY], Account: cgrCdr["account"], Subject: cgrCdr["subject"], + Destination: cgrCdr["destination"], SetupTime: time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), + Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: -1} if storedCdr := cgrCdr.AsStoredCdr(); !reflect.DeepEqual(expctRtCdr, storedCdr) { t.Errorf("Expecting %v, received: %v", expctRtCdr, storedCdr) diff --git a/utils/event.go b/engine/event.go similarity index 91% rename from utils/event.go rename to engine/event.go index db39888c9..a4748067a 100644 --- a/utils/event.go +++ b/engine/event.go @@ -16,9 +16,10 @@ You should have received a copy of the GNU General Public License along with this program. If not, see */ -package utils +package engine import ( + "github.com/cgrates/cgrates/utils" "time" ) @@ -42,8 +43,8 @@ type Event interface { GetOriginatorIP(string) string GetExtraFields() map[string]string MissingParameter() bool - ParseEventValue(*RSRField) string - PassesFieldFilter(*RSRField) (bool, string) + ParseEventValue(*utils.RSRField) string + PassesFieldFilter(*utils.RSRField) (bool, string) AsStoredCdr() *StoredCdr String() string AsEvent(string) Event diff --git a/engine/fscdr.go b/engine/fscdr.go index 9fb118569..f15e4df3e 100644 --- a/engine/fscdr.go +++ b/engine/fscdr.go @@ -120,8 +120,8 @@ func (fsCdr FSCdr) searchExtraField(field string, body map[string]interface{}) ( return } -func (fsCdr FSCdr) AsStoredCdr() *utils.StoredCdr { - storCdr := new(utils.StoredCdr) +func (fsCdr FSCdr) AsStoredCdr() *StoredCdr { + storCdr := new(StoredCdr) storCdr.CgrId = fsCdr.getCgrId() storCdr.TOR = utils.VOICE storCdr.AccId = fsCdr.vars[FS_UUID] diff --git a/engine/fscdr_test.go b/engine/fscdr_test.go index 58d28356f..535c31cef 100644 --- a/engine/fscdr_test.go +++ b/engine/fscdr_test.go @@ -31,7 +31,7 @@ import ( var body = []byte(`{"core-uuid":"844715f9-d8a1-44d6-a4bf-358bec5e10b8","channel_data":{"state":"CS_REPORTING","direction":"inbound","state_number":"11","flags":"0=1;1=1;3=1;19=1;23=1;36=1;37=1;39=1;42=1;47=1;52=1","caps":"1=1;2=1;3=1;4=1;5=1;6=1"},"variables":{"direction":"inbound","uuid":"01df56f4-d99a-4ef6-b7fe-b924b2415b7f","session_id":"33","sip_from_user":"dan","sip_from_uri":"dan@ipbx.itsyscom.com","sip_from_host":"ipbx.itsyscom.com","channel_name":"sofia/ipbxas/dan@ipbx.itsyscom.com","sip_local_network_addr":"127.0.0.1","sip_network_ip":"2.3.4.5","sip_network_port":"5060","sip_received_ip":"2.3.4.5","sip_received_port":"5060","sip_via_protocol":"udp","sip_from_user_stripped":"dan","sofia_profile_name":"ipbxas","recovery_profile_name":"ipbxas","sip_invite_record_route":"","sip_req_user":"+4986517174963","sip_req_port":"5080","sip_req_uri":"+4986517174963@127.0.0.1:5080","sip_req_host":"127.0.0.1","sip_to_user":"+4986517174963","sip_to_uri":"+4986517174963@ipbx.itsyscom.com","sip_to_host":"ipbx.itsyscom.com","sip_contact_params":"alias=1.2.3.4~5060~1;transport=udp;registering_acc=ipbx_itsyscom_com","sip_contact_user":"dan","sip_contact_port":"5060","sip_contact_uri":"dan@10.10.10.154:5060","sip_contact_host":"10.10.10.154","sip_user_agent":"Jitsi2.2.4603.9615Linux","sip_via_host":"2.3.4.5","presence_id":"dan@ipbx.itsyscom.com","sip_h_X-AuthType":"SUA","sip_h_X-AuthUser":"dan","sip_h_X-AuthDomain":"ipbx.itsyscom.com","sip_h_X-BalancerIP":"2.3.4.5","switch_r_sdp":"v=0\r\no=dan 0 0 IN IP4 10.10.10.154\r\ns=-\r\nc=IN IP4 10.10.10.154\r\nt=0 0\r\nm=audio 5004 RTP/AVP 96 8 0\r\na=rtpmap:96 opus/48000\r\na=fmtp:96 usedtx=1\r\na=rtpmap:8 PCMA/8000\r\na=rtpmap:0 PCMU/8000\r\na=extmap:1 urn:ietf:params:rtp-hdrext:csrc-audio-level\r\nm=video 5006 RTP/AVP 97 99\r\na=rtpmap:97 H264/90000\r\na=fmtp:97 profile-level-id=4DE01f;packetization-mode=1\r\na=rtpmap:99 H264/90000\r\na=fmtp:99 profile-level-id=4DE01f\r\na=recvonly\r\na=imageattr:97 send [x=[0-640],y=[0-480]] recv [x=[0-1280],y=[0-800]]\r\na=imageattr:99 send [x=[0-640],y=[0-480]] recv [x=[0-1280],y=[0-800]]\r\n","ep_codec_string":"PCMA@8000h@20i@64000b,PCMU@8000h@20i@64000b,H264@90000h","effective_caller_id_number":"+4986517174960","hangup_after_bridge":"true","continue_on_fail":"true","cgr_tenant":"ipbx.itsyscom.com","cgr_tor":"call","cgr_account":"dan","cgr_subject":"dan","cgr_destination":"+4986517174963","sip_redirect_contact_0":";q=1","sip_redirected_to":";q=1","sip_redirect_contact_user_0":"dan","sip_redirect_contact_host_0":"10.10.10.141","sip_redirect_contact_params_0":"alias=1.2.3.4~3072~1;line=x81npwse;rcv=sip:1.2.3.4:3072","sip_redirect_dialstring_0":"sofia/ipbxas/sip:dan@10.10.10.141:3072;alias=1.2.3.4~3072~1;line=x81npwse;rcv=sip:1.2.3.4:3072","sip_redirect_contact_1":"","sip_redirect_contact_user_1":"dan","sip_redirect_contact_host_1":"10.10.10.154","sip_redirect_contact_params_1":"alias=1.2.3.4~5060~1;transport=udp;registering_acc=ipbx_itsyscom_com;rcv=sip:1.2.3.4:5060","sip_redirect_dialstring_1":"sofia/ipbxas/sip:dan@10.10.10.154:5060;alias=1.2.3.4~5060~1;transport=udp;registering_acc=ipbx_itsyscom_com;rcv=sip:1.2.3.4:5060","sip_redirect_dialstring":"sofia/ipbxas/sip:dan@10.10.10.141:3072;alias=1.2.3.4~3072~1;line=x81npwse;rcv=sip:1.2.3.4:3072,sofia/ipbxas/sip:dan@10.10.10.154:5060;alias=1.2.3.4~5060~1;transport=udp;registering_acc=ipbx_itsyscom_com;rcv=sip:1.2.3.4:5060","max_forwards":"15","transfer_history":"1375609854:d2300128-6724-471c-a495-a3f7a985a2b6:bl_xfer:dan/redirected/XML","transfer_source":"1375609854:d2300128-6724-471c-a495-a3f7a985a2b6:bl_xfer:dan/redirected/XML","call_uuid":"01df56f4-d99a-4ef6-b7fe-b924b2415b7f","current_application_data":"sofia/ipbxas/sip:dan@10.10.10.154:5060;alias=1.2.3.4~5060~1;transport=udp;registering_acc=ipbx_itsyscom_com;rcv=sip:1.2.3.4:5060;fs_path=sip:2.3.4.5,sofia/ipbxas/sip:dan@10.10.10.141:3072;alias=1.2.3.4~3072~1;line=x81npwse;rcv=sip:1.2.3.4:3072;fs_path=sip:2.3.4.5","current_application":"bridge","originated_legs":"ARRAY::e377c077-0f1f-4b7d-b036-1aeef13eff32;Outbound Call;dan|:8f7c860f-0619-4d3c-9515-cc23b0fa3997;Outbound Call;dan","switch_m_sdp":"v=0\r\no=root 975388641 975388642 IN IP4 10.10.10.141\r\ns=call\r\nc=IN IP4 10.10.10.141\r\nt=0 0\r\nm=audio 59976 RTP/AVP 8 0 9 3 101\r\na=rtpmap:8 pcma/8000\r\na=rtpmap:0 pcmu/8000\r\na=rtpmap:9 g722/8000\r\na=rtpmap:3 gsm/8000\r\na=rtpmap:101 telephone-event/8000\r\na=fmtp:101 0-16\r\na=ptime:20\r\nm=video 0 RTP/AVP 98 99\r\na=rtpmap:98 H264/90000\r\na=fmtp:98 profile-level-id=4DE01f\r\na=rtpmap:99 H264/90000\r\na=fmtp:99 profile-level-id=4DE01f\r\n","rtp_use_codec_string":"G722,G722.1,G729,PCMU,PCMA,GSM,H264","sip_audio_recv_pt":"0","sip_use_codec_name":"PCMU","sip_use_codec_rate":"8000","sip_use_codec_ptime":"20","read_codec":"PCMU","read_rate":"8000","write_codec":"PCMU","write_rate":"8000","dtmf_type":"info","video_possible":"true","remote_video_ip":"10.10.10.154","remote_video_port":"5006","sip_video_fmtp":"profile-level-id=4DE01f;packetization-mode=1","sip_video_pt":"97","sip_video_recv_pt":"97","video_read_codec":"H264","video_read_rate":"90000","video_write_codec":"H264","video_write_rate":"90000","sip_use_video_codec_name":"H264","sip_use_video_codec_fmtp":"profile-level-id=4DE01f;packetization-mode=1","sip_use_video_codec_rate":"90000","sip_use_video_codec_ptime":"0","local_media_ip":"2.3.4.5","local_media_port":"29452","advertised_media_ip":"2.3.4.5","sip_use_pt":"0","rtp_use_ssrc":"1408273224","local_video_ip":"2.3.4.5","local_video_port":"22648","sip_use_video_pt":"97","rtp_use_video_ssrc":"1408273224","sip_local_sdp_str":"v=0\no=iPBXCell 1375580404 1375580405 IN IP4 2.3.4.5\ns=iPBXCell\nc=IN IP4 2.3.4.5\nt=0 0\nm=audio 29452 RTP/AVP 0\na=rtpmap:0 PCMU/8000\na=silenceSupp:off - - - -\na=ptime:20\na=sendrecv\nm=video 22648 RTP/AVP 97\na=rtpmap:97 H264/90000\n","endpoint_disposition":"ANSWER","originate_disposition":"SUCCESS","DIALSTATUS":"SUCCESS","originate_causes":"ARRAY::e377c077-0f1f-4b7d-b036-1aeef13eff32;LOSE_RACE|:8f7c860f-0619-4d3c-9515-cc23b0fa3997;NONE","last_bridge_to":"8f7c860f-0619-4d3c-9515-cc23b0fa3997","bridge_channel":"sofia/ipbxas/sip:dan@10.10.10.141:3072","bridge_uuid":"8f7c860f-0619-4d3c-9515-cc23b0fa3997","signal_bond":"8f7c860f-0619-4d3c-9515-cc23b0fa3997","sip_to_tag":"4X345vQvQyetD","sip_from_tag":"9f90cc40","sip_cseq":"2","sip_call_id":"ca9c5e20caeaa6596be8cf66261f13e5@0:0:0:0:0:0:0:0","sip_full_via":"SIP/2.0/UDP 2.3.4.5;branch=z9hG4bKcydzigwkX,SIP/2.0/UDP 10.10.10.154:5060;rport=5060;received=1.2.3.4;branch=z9hG4bK-313937-b78ce2a1daafe532fc34b1b3735727ac","sip_from_display":"dan","sip_full_from":"\"dan\" ;tag=9f90cc40","sip_full_to":";tag=4X345vQvQyetD","last_sent_callee_id_name":"Outbound Call","last_sent_callee_id_number":"dan","remote_media_ip_reported":"10.10.10.154","remote_media_ip":"1.2.3.4","remote_media_port_reported":"5004","remote_media_port":"5004","rtp_auto_adjust":"true","sip_hangup_phrase":"OK","last_bridge_hangup_cause":"NORMAL_CLEARING","last_bridge_proto_specific_hangup_cause":"sip:200","bridge_hangup_cause":"NORMAL_CLEARING","hangup_cause":"NORMAL_CLEARING","hangup_cause_q850":"16","digits_dialed":"none","start_stamp":"2013-08-04 11:50:54","profile_start_stamp":"2013-08-04 11:50:54","answer_stamp":"2013-08-04 11:50:56","bridge_stamp":"2013-08-04 11:50:56","progress_stamp":"2013-08-04 11:50:54","progress_media_stamp":"2013-08-04 11:50:56","end_stamp":"2013-08-04 11:51:00","start_epoch":"1375609854","start_uepoch":"1375609854385581","profile_start_epoch":"1375609854","profile_start_uepoch":"1375609854385581","answer_epoch":"1375609856","answer_uepoch":"1375609856285587","bridge_epoch":"1375609856","bridge_uepoch":"1375609856285587","last_hold_epoch":"0","last_hold_uepoch":"0","hold_accum_seconds":"0","hold_accum_usec":"0","hold_accum_ms":"0","resurrect_epoch":"0","resurrect_uepoch":"0","progress_epoch":"1375609854","progress_uepoch":"1375609854505584","progress_media_epoch":"1375609856","progress_media_uepoch":"1375609856285587","end_epoch":"1375609860","end_uepoch":"1375609860205563","last_app":"bridge","last_arg":"sofia/ipbxas/sip:dan@10.10.10.154:5060;alias=1.2.3.4~5060~1;transport=udp;registering_acc=ipbx_itsyscom_com;rcv=sip:1.2.3.4:5060;fs_path=sip:2.3.4.5,sofia/ipbxas/sip:dan@10.10.10.141:3072;alias=1.2.3.4~3072~1;line=x81npwse;rcv=sip:1.2.3.4:3072;fs_path=sip:2.3.4.5","caller_id":"\"dan\" ","duration":"6","billsec":"4","progresssec":"0","answersec":"2","waitsec":"2","progress_mediasec":"2","flow_billsec":"6","mduration":"5820","billmsec":"3920","progressmsec":"120","answermsec":"1900","waitmsec":"1900","progress_mediamsec":"1900","flow_billmsec":"5820","uduration":"5819982","billusec":"3919976","progressusec":"120003","answerusec":"1900006","waitusec":"1900006","progress_mediausec":"1900006","flow_billusec":"5819982","sip_hangup_disposition":"send_bye","rtp_audio_in_raw_bytes":"32968","rtp_audio_in_media_bytes":"32960","rtp_audio_in_packet_count":"207","rtp_audio_in_media_packet_count":"205","rtp_audio_in_skip_packet_count":"6","rtp_audio_in_jb_packet_count":"0","rtp_audio_in_dtmf_packet_count":"0","rtp_audio_in_cng_packet_count":"0","rtp_audio_in_flush_packet_count":"2","rtp_audio_in_largest_jb_size":"0","rtp_audio_out_raw_bytes":"31648","rtp_audio_out_media_bytes":"31648","rtp_audio_out_packet_count":"184","rtp_audio_out_media_packet_count":"184","rtp_audio_out_skip_packet_count":"0","rtp_audio_out_dtmf_packet_count":"0","rtp_audio_out_cng_packet_count":"0","rtp_audio_rtcp_packet_count":"0","rtp_audio_rtcp_octet_count":"0","rtp_video_in_raw_bytes":"0","rtp_video_in_media_bytes":"0","rtp_video_in_packet_count":"0","rtp_video_in_media_packet_count":"0","rtp_video_in_skip_packet_count":"0","rtp_video_in_jb_packet_count":"0","rtp_video_in_dtmf_packet_count":"0","rtp_video_in_cng_packet_count":"0","rtp_video_in_flush_packet_count":"0","rtp_video_in_largest_jb_size":"0","rtp_video_out_raw_bytes":"0","rtp_video_out_media_bytes":"0","rtp_video_out_packet_count":"0","rtp_video_out_media_packet_count":"0","rtp_video_out_skip_packet_count":"0","rtp_video_out_dtmf_packet_count":"0","rtp_video_out_cng_packet_count":"0","rtp_video_rtcp_packet_count":"0","rtp_video_rtcp_octet_count":"0"},"app_log":{"applications":[{"app_name":"set","app_data":"effective_caller_id_number=+4986517174960"},{"app_name":"set","app_data":"hangup_after_bridge=true"},{"app_name":"set","app_data":"continue_on_fail=true"},{"app_name":"set","app_data":"cgr_tenant=ipbx.itsyscom.com"},{"app_name":"set","app_data":"cgr_tor=call"},{"app_name":"set","app_data":"cgr_account=dan"},{"app_name":"set","app_data":"cgr_subject=dan"},{"app_name":"set","app_data":"cgr_destination=+4986517174963"},{"app_name":"bridge","app_data":"{presence_id=dan@ipbx.itsyscom.com,sip_redirect_fork=true}sofia/ipbxas/dan@ipbx.itsyscom.com;fs_path=sip:2.3.4.5"},{"app_name":"bridge","app_data":"sofia/ipbxas/sip:dan@10.10.10.154:5060;alias=1.2.3.4~5060~1;transport=udp;registering_acc=ipbx_itsyscom_com;rcv=sip:1.2.3.4:5060;fs_path=sip:2.3.4.5,sofia/ipbxas/sip:dan@10.10.10.141:3072;alias=1.2.3.4~3072~1;line=x81npwse;rcv=sip:1.2.3.4:3072;fs_path=sip:2.3.4.5"}]},"callflow":{"dialplan":"XML","profile_index":"2","extension":{"name":"Redirected call","number":"dan","applications":[{"app_name":"bridge","app_data":"sofia/ipbxas/sip:dan@10.10.10.154:5060;alias=1.2.3.4~5060~1;transport=udp;registering_acc=ipbx_itsyscom_com;rcv=sip:1.2.3.4:5060;fs_path=sip:2.3.4.5,sofia/ipbxas/sip:dan@10.10.10.141:3072;alias=1.2.3.4~3072~1;line=x81npwse;rcv=sip:1.2.3.4:3072;fs_path=sip:2.3.4.5"}]},"caller_profile":{"username":"dan","dialplan":"XML","caller_id_name":"dan","ani":"dan","aniii":"","caller_id_number":"dan","network_addr":"2.3.4.5","rdnis":"+4986517174963","destination_number":"dan","uuid":"01df56f4-d99a-4ef6-b7fe-b924b2415b7f","source":"mod_sofia","context":"redirected","chan_name":"sofia/ipbxas/dan@ipbx.itsyscom.com","originatee":{"originatee_caller_profiles":[{"username":"dan","dialplan":"XML","caller_id_name":"dan","ani":"dan","aniii":"","caller_id_number":"+4986517174960","network_addr":"2.3.4.5","rdnis":"+4986517174963","destination_number":"dan","uuid":"8f7c860f-0619-4d3c-9515-cc23b0fa3997","source":"mod_sofia","context":"redirected","chan_name":"sofia/ipbxas/sip:dan@10.10.10.141:3072"}]}},"times":{"created_time":"1375609854385581","profile_created_time":"1375609854385581","progress_time":"1375609854505584","progress_media_time":"1375609856285587","answered_time":"1375609856285587","hangup_time":"1375609860205563","resurrect_time":"0","transfer_time":"0"}},"callflow":{"dialplan":"XML","profile_index":"1","extension":{"name":"OnNet Call","number":"+4986517174963","applications":[{"app_name":"set","app_data":"effective_caller_id_number=+4986517174960"},{"app_name":"set","app_data":"hangup_after_bridge=true"},{"app_name":"set","app_data":"continue_on_fail=true"},{"app_name":"set","app_data":"cgr_tenant=ipbx.itsyscom.com"},{"app_name":"set","app_data":"cgr_tor=call"},{"app_name":"set","app_data":"cgr_account=dan"},{"app_name":"set","app_data":"cgr_subject=dan"},{"app_name":"set","app_data":"cgr_destination=+4986517174963"},{"app_name":"bridge","app_data":"{presence_id=dan@ipbx.itsyscom.com,sip_redirect_fork=true}sofia/ipbxas/dan@ipbx.itsyscom.com;fs_path=sip:2.3.4.5"}]},"caller_profile":{"username":"dan","dialplan":"XML","caller_id_name":"dan","ani":"dan","aniii":"","caller_id_number":"dan","network_addr":"2.3.4.5","rdnis":"","destination_number":"+4986517174963","uuid":"01df56f4-d99a-4ef6-b7fe-b924b2415b7f","source":"mod_sofia","context":"ipbxas","chan_name":"sofia/ipbxas/dan@ipbx.itsyscom.com"},"times":{"created_time":"1375609854385581","profile_created_time":"1375609854385581","progress_time":"0","progress_media_time":"0","answered_time":"0","hangup_time":"0","resurrect_time":"0","transfer_time":"1375609854385581"}}}`) func TestFsCdrInterfaces(t *testing.T) { - var _ utils.RawCdr = new(FSCdr) + var _ RawCdr = new(FSCdr) } func TestFirstNonEmpty(t *testing.T) { @@ -57,7 +57,7 @@ func TestCDRFields(t *testing.T) { } setupTime, _ := utils.ParseTimeDetectLayout(fsCdr.vars[FS_SETUP_TIME]) answerTime, _ := utils.ParseTimeDetectLayout(fsCdr.vars[FS_ANSWER_TIME]) - expctStoredCdr := &utils.StoredCdr{CgrId: utils.Sha1("01df56f4-d99a-4ef6-b7fe-b924b2415b7f", setupTime.UTC().String()), TOR: utils.VOICE, AccId: "01df56f4-d99a-4ef6-b7fe-b924b2415b7f", + expctStoredCdr := &StoredCdr{CgrId: utils.Sha1("01df56f4-d99a-4ef6-b7fe-b924b2415b7f", setupTime.UTC().String()), TOR: utils.VOICE, AccId: "01df56f4-d99a-4ef6-b7fe-b924b2415b7f", CdrHost: "127.0.0.1", CdrSource: "freeswitch_json", Direction: "*out", Category: "call", ReqType: utils.META_RATED, Tenant: "ipbx.itsyscom.com", Account: "dan", Subject: "dan", Destination: "+4986517174963", SetupTime: setupTime, AnswerTime: answerTime, Usage: time.Duration(4) * time.Second, ExtraFields: map[string]string{"sip_user_agent": "Jitsi2.2.4603.9615Linux"}, Cost: -1} diff --git a/engine/loader_local_test.go b/engine/loader_local_test.go index 1308d7622..e209b75c1 100644 --- a/engine/loader_local_test.go +++ b/engine/loader_local_test.go @@ -47,9 +47,6 @@ var accountDbCsv, accountDbStor, accountDbApier AccountingStorage // Each rating var storDb LoadStorage var lCfg *config.CGRConfig -// Arguments received via test command -var testLocal = flag.Bool("local", false, "Perform the tests only on local test environment, not by default.") // This flag will be passed here via "go test -local" args -var dataDir = flag.String("data_dir", "/usr/share/cgrates", "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 ratingDb diff --git a/engine/mediator.go b/engine/mediator.go index 27524ee86..7010c75c6 100644 --- a/engine/mediator.go +++ b/engine/mediator.go @@ -71,7 +71,7 @@ func (self *Mediator) getCostsFromDB(cgrid, runId string) (cc *CallCost, err err } // Retrive the cost from engine -func (self *Mediator) getCostFromRater(storedCdr *utils.StoredCdr) (*CallCost, error) { +func (self *Mediator) getCostFromRater(storedCdr *StoredCdr) (*CallCost, error) { cc := &CallCost{} var err error if storedCdr.Usage == time.Duration(0) { // failed call, returning empty callcost, no error @@ -103,7 +103,7 @@ func (self *Mediator) getCostFromRater(storedCdr *utils.StoredCdr) (*CallCost, e return cc, err } -func (self *Mediator) rateCDR(storedCdr *utils.StoredCdr) error { +func (self *Mediator) rateCDR(storedCdr *StoredCdr) error { var qryCC *CallCost var errCost error if utils.IsSliceMember([]string{utils.META_PREPAID, utils.PREPAID}, storedCdr.ReqType) { // ToDo: Get rid of PREPAID as soon as we don't want to support it backwards @@ -121,9 +121,9 @@ func (self *Mediator) rateCDR(storedCdr *utils.StoredCdr) error { return nil } -func (self *Mediator) RateCdr(storedCdr *utils.StoredCdr, sendToStats bool) error { +func (self *Mediator) RateCdr(storedCdr *StoredCdr, sendToStats bool) error { storedCdr.MediationRunId = utils.META_DEFAULT - cdrRuns := []*utils.StoredCdr{storedCdr} // Start with initial storCdr, will add here all to be mediated + cdrRuns := []*StoredCdr{storedCdr} // Start with initial storCdr, will add here all to be mediated attrsDC := utils.AttrDerivedChargers{Tenant: storedCdr.Tenant, Category: storedCdr.Category, Direction: storedCdr.Direction, Account: storedCdr.Account, Subject: storedCdr.Subject} var dcs utils.DerivedChargers @@ -157,7 +157,7 @@ func (self *Mediator) RateCdr(storedCdr *utils.StoredCdr, sendToStats bool) erro forkedCdr, err := storedCdr.ForkCdr(dc.RunId, dcReqTypeFld, dcDirFld, dcTenantFld, dcCategoryFld, dcAcntFld, dcSubjFld, dcDstFld, dcSTimeFld, dcATimeFld, dcDurFld, []*utils.RSRField{}, true) if err != nil { // Errors on fork, cannot calculate further, write that into db for later analysis - self.cdrDb.SetRatedCdr(&utils.StoredCdr{CgrId: storedCdr.CgrId, CdrSource: utils.FORKED_CDR, MediationRunId: dc.RunId, Cost: -1}, + self.cdrDb.SetRatedCdr(&StoredCdr{CgrId: storedCdr.CgrId, CdrSource: utils.FORKED_CDR, MediationRunId: dc.RunId, Cost: -1}, err.Error()) // Cannot fork CDR, important just runid and error continue } @@ -178,7 +178,7 @@ func (self *Mediator) RateCdr(storedCdr *utils.StoredCdr, sendToStats bool) erro } } if sendToStats && self.stats != nil { // We send to stats only after saving to db since there are chances we cannot store and then no way to reproduce stats offline - go func(cdr *utils.StoredCdr) { // Pass it by value since the variable will be overwritten by for + go func(cdr *StoredCdr) { // Pass it by value since the variable will be overwritten by for if err := self.stats.AppendCDR(cdr, nil); err != nil { Logger.Err(fmt.Sprintf(" Could not append cdr to stats: %s", err.Error())) } diff --git a/engine/mediator_local_test.go b/engine/mediator_local_test.go index 33502a158..54bab0d6f 100644 --- a/engine/mediator_local_test.go +++ b/engine/mediator_local_test.go @@ -174,13 +174,13 @@ func TestMediInjectCdrs(t *testing.T) { if !*testLocal { return } - cgrCdr1 := utils.CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaaaadsafdsaf", "cdrsource": TEST_SQL, utils.CDRHOST: "192.168.1.1", utils.REQTYPE: utils.META_RATED, utils.DIRECTION: "*out", + cgrCdr1 := CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaaaadsafdsaf", "cdrsource": TEST_SQL, utils.CDRHOST: "192.168.1.1", utils.REQTYPE: utils.META_RATED, utils.DIRECTION: "*out", utils.TENANT: "cgrates.org", utils.CATEGORY: "call", utils.ACCOUNT: "dan", utils.SUBJECT: "dan", utils.DESTINATION: "+4986517174963", utils.ANSWER_TIME: "2013-11-07T08:42:26Z", utils.USAGE: "10"} - cgrCdr2 := utils.CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "baaaadsafdsaf", "cdrsource": TEST_SQL, utils.CDRHOST: "192.168.1.1", utils.REQTYPE: utils.META_RATED, utils.DIRECTION: "*out", + cgrCdr2 := CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "baaaadsafdsaf", "cdrsource": TEST_SQL, utils.CDRHOST: "192.168.1.1", utils.REQTYPE: utils.META_RATED, utils.DIRECTION: "*out", utils.TENANT: "cgrates.org", utils.CATEGORY: "call", utils.ACCOUNT: "dan", utils.SUBJECT: "dan", utils.DESTINATION: "+4986517173964", utils.ANSWER_TIME: "2013-11-07T09:42:26Z", utils.USAGE: "20"} - for _, cdr := range []utils.CgrCdr{cgrCdr1, cgrCdr2} { + for _, cdr := range []CgrCdr{cgrCdr1, cgrCdr2} { if err := cdrStor.SetCdr(cdr.AsStoredCdr()); err != nil { t.Error(err) } diff --git a/utils/rawcdr.go b/engine/rawcdr.go similarity index 98% rename from utils/rawcdr.go rename to engine/rawcdr.go index 1380207d0..518b34f56 100644 --- a/utils/rawcdr.go +++ b/engine/rawcdr.go @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see */ -package utils +package engine // RawCDR is the original CDR received from external sources (eg: FreeSWITCH) type RawCdr interface { diff --git a/engine/responder.go b/engine/responder.go index 5b4f68792..889109ed2 100644 --- a/engine/responder.go +++ b/engine/responder.go @@ -126,7 +126,7 @@ func (rs *Responder) GetMaxSessionTime(arg CallDescriptor, reply *float64) (err } // Returns MaxSessionTime for an event received in SessionManager, considering DerivedCharging for it -func (rs *Responder) GetDerivedMaxSessionTime(ev utils.StoredCdr, reply *float64) error { +func (rs *Responder) GetDerivedMaxSessionTime(ev StoredCdr, reply *float64) error { if rs.Bal != nil { return errors.New("Unsupported method on the balancer") } @@ -184,7 +184,7 @@ func (rs *Responder) GetDerivedMaxSessionTime(ev utils.StoredCdr, reply *float64 } // Used by SM to get all the prepaid CallDescriptors attached to a session -func (rs *Responder) GetSessionRuns(ev utils.StoredCdr, sRuns *[]*SessionRun) error { +func (rs *Responder) GetSessionRuns(ev StoredCdr, sRuns *[]*SessionRun) error { if rs.Bal != nil { return errors.New("Unsupported method on the balancer") } @@ -230,7 +230,7 @@ func (rs *Responder) GetDerivedChargers(attrs utils.AttrDerivedChargers, dcs *ut return nil } -func (rs *Responder) ProcessCdr(cdr *utils.StoredCdr, reply *string) error { +func (rs *Responder) ProcessCdr(cdr *StoredCdr, reply *string) error { if rs.CdrSrv == nil { return errors.New("CDR_SERVER_NOT_RUNNING") } @@ -397,9 +397,9 @@ type Connector interface { RefundIncrements(CallDescriptor, *float64) error GetMaxSessionTime(CallDescriptor, *float64) error GetDerivedChargers(utils.AttrDerivedChargers, *utils.DerivedChargers) error - GetDerivedMaxSessionTime(utils.StoredCdr, *float64) error - GetSessionRuns(utils.StoredCdr, *[]*SessionRun) error - ProcessCdr(*utils.StoredCdr, *string) error + GetDerivedMaxSessionTime(StoredCdr, *float64) error + GetSessionRuns(StoredCdr, *[]*SessionRun) error + ProcessCdr(*StoredCdr, *string) error } type RPCClientConnector struct { @@ -426,11 +426,11 @@ func (rcc *RPCClientConnector) GetMaxSessionTime(cd CallDescriptor, resp *float6 return rcc.Client.Call("Responder.GetMaxSessionTime", cd, resp) } -func (rcc *RPCClientConnector) GetDerivedMaxSessionTime(ev utils.StoredCdr, reply *float64) error { +func (rcc *RPCClientConnector) GetDerivedMaxSessionTime(ev StoredCdr, reply *float64) error { return rcc.Client.Call("Responder.GetDerivedMaxSessionTime", ev, reply) } -func (rcc *RPCClientConnector) GetSessionRuns(ev utils.StoredCdr, sRuns *[]*SessionRun) error { +func (rcc *RPCClientConnector) GetSessionRuns(ev StoredCdr, sRuns *[]*SessionRun) error { return rcc.Client.Call("Responder.GetSessionRuns", ev, sRuns) } @@ -438,6 +438,6 @@ func (rcc *RPCClientConnector) GetDerivedChargers(attrs utils.AttrDerivedCharger return rcc.Client.Call("ApierV1.GetDerivedChargers", attrs, dcs) } -func (rcc *RPCClientConnector) ProcessCdr(cdr *utils.StoredCdr, reply *string) error { +func (rcc *RPCClientConnector) ProcessCdr(cdr *StoredCdr, reply *string) error { return rcc.Client.Call("CDRSV1.ProcessCdr", cdr, reply) } diff --git a/engine/responder_test.go b/engine/responder_test.go index 66c26dcdd..66397961b 100644 --- a/engine/responder_test.go +++ b/engine/responder_test.go @@ -56,7 +56,7 @@ func TestResponderGetDerivedChargers(t *testing.T) { func TestGetDerivedMaxSessionTime(t *testing.T) { testTenant := "vdf" - cdr := utils.StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", + cdr := StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", CdrSource: "test", ReqType: utils.META_RATED, Direction: "*out", Tenant: testTenant, Category: "call", Account: "dan", Subject: "dan", Destination: "1002", SetupTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), MediationRunId: utils.DEFAULT_RUNID, Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, @@ -123,7 +123,7 @@ func TestGetDerivedMaxSessionTime(t *testing.T) { func TestGetSessionRuns(t *testing.T) { testTenant := "vdf" - cdr := utils.StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", + cdr := StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", CdrSource: "test", ReqType: utils.META_PREPAID, Direction: "*out", Tenant: testTenant, Category: "call", Account: "dan2", Subject: "dan2", Destination: "1002", SetupTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), MediationRunId: utils.DEFAULT_RUNID, Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, diff --git a/engine/stats.go b/engine/stats.go index 6ebac272b..f5f9b416f 100644 --- a/engine/stats.go +++ b/engine/stats.go @@ -30,7 +30,7 @@ import ( type StatsInterface interface { GetValues(string, *map[string]float64) error GetQueueIds(int, *[]string) error - AppendCDR(*utils.StoredCdr, *int) error + AppendCDR(*StoredCdr, *int) error AddQueue(*CdrStats, *int) error ReloadQueues([]string, *int) error ResetQueues([]string, *int) error @@ -163,7 +163,7 @@ func (s *Stats) UpdateQueues(css []*CdrStats, out *int) error { return nil } -func (s *Stats) AppendCDR(cdr *utils.StoredCdr, out *int) error { +func (s *Stats) AppendCDR(cdr *StoredCdr, out *int) error { s.mux.RLock() defer s.mux.RUnlock() for _, sq := range s.queues { @@ -189,7 +189,7 @@ func (ps *ProxyStats) GetValues(sqID string, values *map[string]float64) error { return ps.Client.Call("Stats.GetValues", sqID, values) } -func (ps *ProxyStats) AppendCDR(cdr *utils.StoredCdr, out *int) error { +func (ps *ProxyStats) AppendCDR(cdr *StoredCdr, out *int) error { return ps.Client.Call("Stats.AppendCDR", cdr, out) } diff --git a/engine/stats_queue.go b/engine/stats_queue.go index c2776c719..46d9665fd 100644 --- a/engine/stats_queue.go +++ b/engine/stats_queue.go @@ -22,8 +22,6 @@ import ( "strings" "sync" "time" - - "github.com/cgrates/cgrates/utils" ) type StatsQueue struct { @@ -72,7 +70,7 @@ func (sq *StatsQueue) UpdateConf(conf *CdrStats) { } } -func (sq *StatsQueue) AppendCDR(cdr *utils.StoredCdr) { +func (sq *StatsQueue) AppendCDR(cdr *StoredCdr) { sq.mux.Lock() defer sq.mux.Unlock() if sq.conf.AcceptCdr(cdr) { @@ -117,7 +115,7 @@ func (sq *StatsQueue) removeFromMetrics(cdr *QCdr) { } } -func (sq *StatsQueue) simplifyCdr(cdr *utils.StoredCdr) *QCdr { +func (sq *StatsQueue) simplifyCdr(cdr *StoredCdr) *QCdr { return &QCdr{ SetupTime: cdr.SetupTime, AnswerTime: cdr.AnswerTime, diff --git a/engine/stats_test.go b/engine/stats_test.go index 797e857f3..1f85f6816 100644 --- a/engine/stats_test.go +++ b/engine/stats_test.go @@ -34,7 +34,7 @@ func TestStatsQueueInit(t *testing.T) { func TestStatsValue(t *testing.T) { sq := NewStatsQueue(&CdrStats{Metrics: []string{ASR, ACD, ACC}}) - cdr := &utils.StoredCdr{ + cdr := &StoredCdr{ AnswerTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), Usage: 10 * time.Second, Cost: 1, @@ -53,7 +53,7 @@ func TestStatsValue(t *testing.T) { } func TestStatsSimplifyCDR(t *testing.T) { - cdr := &utils.StoredCdr{ + cdr := &StoredCdr{ TOR: "tor", AccId: "accid", CdrHost: "cdrhost", @@ -82,7 +82,7 @@ func TestStatsSimplifyCDR(t *testing.T) { func TestAcceptCdr(t *testing.T) { sq := NewStatsQueue(nil) - cdr := &utils.StoredCdr{ + cdr := &StoredCdr{ TOR: "tor", AccId: "accid", CdrHost: "cdrhost", @@ -196,7 +196,7 @@ func TestStatsQueueIds(t *testing.T) { func TestStatsAppendCdr(t *testing.T) { cdrStats := NewStats(dataStorage) - cdr := &utils.StoredCdr{ + cdr := &StoredCdr{ Tenant: "cgrates.org", Category: "call", AnswerTime: time.Now(), @@ -216,7 +216,7 @@ func TestStatsAppendCdr(t *testing.T) { func TestStatsGetValues(t *testing.T) { cdrStats := NewStats(dataStorage) - cdr := &utils.StoredCdr{ + cdr := &StoredCdr{ Tenant: "cgrates.org", Category: "call", AnswerTime: time.Now(), @@ -225,7 +225,7 @@ func TestStatsGetValues(t *testing.T) { Cost: 10, } cdrStats.AppendCDR(cdr, nil) - cdr = &utils.StoredCdr{ + cdr = &StoredCdr{ Tenant: "cgrates.org", Category: "call", AnswerTime: time.Now(), @@ -245,7 +245,7 @@ func TestStatsGetValues(t *testing.T) { func TestStatsReloadQueues(t *testing.T) { cdrStats := NewStats(dataStorage) - cdr := &utils.StoredCdr{ + cdr := &StoredCdr{ Tenant: "cgrates.org", Category: "call", AnswerTime: time.Now(), @@ -280,7 +280,7 @@ func TestStatsReloadQueuesWithDefault(t *testing.T) { cdrStats.AddQueue(&CdrStats{ Id: utils.META_DEFAULT, }, nil) - cdr := &utils.StoredCdr{ + cdr := &StoredCdr{ Tenant: "cgrates.org", Category: "call", AnswerTime: time.Now(), @@ -313,7 +313,7 @@ func TestStatsReloadQueuesWithDefault(t *testing.T) { func TestStatsReloadQueuesWithIds(t *testing.T) { cdrStats := NewStats(dataStorage) - cdr := &utils.StoredCdr{ + cdr := &StoredCdr{ Tenant: "cgrates.org", Category: "call", AnswerTime: time.Now(), @@ -345,7 +345,7 @@ func TestStatsReloadQueuesWithIds(t *testing.T) { func TestStatsResetQueues(t *testing.T) { cdrStats := NewStats(dataStorage) - cdr := &utils.StoredCdr{ + cdr := &StoredCdr{ Tenant: "cgrates.org", Category: "call", AnswerTime: time.Now(), @@ -377,7 +377,7 @@ func TestStatsResetQueues(t *testing.T) { func TestStatsResetQueuesWithIds(t *testing.T) { cdrStats := NewStats(dataStorage) - cdr := &utils.StoredCdr{ + cdr := &StoredCdr{ Tenant: "cgrates.org", Category: "call", AnswerTime: time.Now(), diff --git a/engine/storage_interface.go b/engine/storage_interface.go index 002df2adf..783218695 100644 --- a/engine/storage_interface.go +++ b/engine/storage_interface.go @@ -112,9 +112,9 @@ type AccountingStorage interface { type CdrStorage interface { Storage - SetCdr(*utils.StoredCdr) error - SetRatedCdr(*utils.StoredCdr, string) error - GetStoredCdrs(*utils.CdrsFilter) ([]*utils.StoredCdr, int64, error) + SetCdr(*StoredCdr) error + SetRatedCdr(*StoredCdr, string) error + GetStoredCdrs(*utils.CdrsFilter) ([]*StoredCdr, int64, error) RemStoredCdrs([]string) error } diff --git a/engine/storage_mysql.go b/engine/storage_mysql.go index 98c3db90a..05b79c9c9 100644 --- a/engine/storage_mysql.go +++ b/engine/storage_mysql.go @@ -103,7 +103,7 @@ func (self *MySQLStorage) LogCallCost(cgrid, source, runid string, cc *CallCost) return nil } -func (self *MySQLStorage) SetRatedCdr(storedCdr *utils.StoredCdr, extraInfo string) (err error) { +func (self *MySQLStorage) SetRatedCdr(storedCdr *StoredCdr, extraInfo string) (err error) { _, err = self.Db.Exec(fmt.Sprintf("INSERT INTO %s (cgrid,runid,reqtype,direction,tenant,category,account,subject,destination,setup_time,answer_time,`usage`,cost,extra_info,created_at) VALUES ('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s',%v,%f,'%s','%s') ON DUPLICATE KEY UPDATE reqtype=values(reqtype),direction=values(direction),tenant=values(tenant),category=values(category),account=values(account),subject=values(subject),destination=values(destination),setup_time=values(setup_time),answer_time=values(answer_time),`usage`=values(`usage`),cost=values(cost),extra_info=values(extra_info), updated_at='%s'", utils.TBL_RATED_CDRS, storedCdr.CgrId, diff --git a/engine/storage_mysql_local_test.go b/engine/storage_mysql_local_test.go index 72c3b05b5..ec00d2169 100644 --- a/engine/storage_mysql_local_test.go +++ b/engine/storage_mysql_local_test.go @@ -431,50 +431,50 @@ func TestMySQLSetCdr(t *testing.T) { if !*testLocal { return } - cgrCdr1 := &utils.CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa1", utils.CDRHOST: "192.168.1.1", utils.REQTYPE: utils.META_RATED, utils.DIRECTION: "*out", utils.TENANT: "cgrates.org", + cgrCdr1 := &CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa1", utils.CDRHOST: "192.168.1.1", utils.REQTYPE: utils.META_RATED, utils.DIRECTION: "*out", utils.TENANT: "cgrates.org", utils.CATEGORY: "call", utils.ACCOUNT: "1001", utils.SUBJECT: "1001", utils.DESTINATION: "1002", utils.SETUP_TIME: "2013-11-08T08:42:20Z", utils.ANSWER_TIME: "2013-11-08T08:42:26Z", utils.USAGE: "10s", "field_extr1": "val_extr1", "fieldextr2": "valextr2", utils.CDRSOURCE: TEST_SQL} - cgrCdr2 := &utils.CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa2", utils.CDRHOST: "192.168.1.1", utils.REQTYPE: utils.META_PREPAID, utils.DIRECTION: "*out", utils.TENANT: "cgrates.org", + cgrCdr2 := &CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa2", utils.CDRHOST: "192.168.1.1", utils.REQTYPE: utils.META_PREPAID, utils.DIRECTION: "*out", utils.TENANT: "cgrates.org", utils.CATEGORY: "call", utils.ACCOUNT: "1001", utils.SUBJECT: "1001", utils.DESTINATION: "1002", utils.SETUP_TIME: "2013-11-08T08:42:22Z", utils.ANSWER_TIME: "2013-11-08T08:42:26Z", utils.USAGE: "20", "field_extr1": "val_extr1", "fieldextr2": "valextr2", "cdrsource": TEST_SQL} - cgrCdr3 := &utils.CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa3", utils.CDRHOST: "192.168.1.1", utils.REQTYPE: utils.META_RATED, utils.DIRECTION: "*out", utils.TENANT: "cgrates.org", + cgrCdr3 := &CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa3", utils.CDRHOST: "192.168.1.1", utils.REQTYPE: utils.META_RATED, utils.DIRECTION: "*out", utils.TENANT: "cgrates.org", utils.CATEGORY: "premium_call", utils.ACCOUNT: "1002", utils.SUBJECT: "1002", utils.DESTINATION: "1001", utils.SETUP_TIME: "2013-11-07T08:42:24Z", utils.ANSWER_TIME: "2013-11-07T08:42:26Z", utils.USAGE: "60s", "field_extr1": "val_extr1", "fieldextr2": "valextr2", "cdrsource": TEST_SQL} - cgrCdr4 := &utils.CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa4", utils.CDRHOST: "192.168.1.2", utils.REQTYPE: utils.META_PSEUDOPREPAID, utils.DIRECTION: "*out", utils.TENANT: "itsyscom.com", + cgrCdr4 := &CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa4", utils.CDRHOST: "192.168.1.2", utils.REQTYPE: utils.META_PSEUDOPREPAID, utils.DIRECTION: "*out", utils.TENANT: "itsyscom.com", utils.CATEGORY: "call", utils.ACCOUNT: "1001", utils.SUBJECT: "1001", utils.DESTINATION: "+4986517174964", utils.SETUP_TIME: "2013-11-07T08:42:21Z", utils.ANSWER_TIME: "2013-11-07T08:42:26Z", utils.USAGE: "1m2s", "field_extr1": "val_extr1", "fieldextr2": "valextr2", "cdrsource": TEST_SQL} - cgrCdr5 := &utils.CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa5", utils.CDRHOST: "192.168.1.2", utils.REQTYPE: utils.META_POSTPAID, utils.DIRECTION: "*out", utils.TENANT: "itsyscom.com", + cgrCdr5 := &CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa5", utils.CDRHOST: "192.168.1.2", utils.REQTYPE: utils.META_POSTPAID, utils.DIRECTION: "*out", utils.TENANT: "itsyscom.com", utils.CATEGORY: "call", utils.ACCOUNT: "1002", utils.SUBJECT: "1002", utils.DESTINATION: "+4986517174963", utils.SETUP_TIME: "2013-11-07T08:42:25Z", utils.ANSWER_TIME: "2013-11-07T08:42:26Z", utils.USAGE: "15s", "field_extr1": "val_extr1", "fieldextr2": "valextr2", "cdrsource": TEST_SQL} - for _, cdr := range []*utils.CgrCdr{cgrCdr1, cgrCdr2, cgrCdr3, cgrCdr4, cgrCdr5} { + for _, cdr := range []*CgrCdr{cgrCdr1, cgrCdr2, cgrCdr3, cgrCdr4, cgrCdr5} { if err := mysqlDb.SetCdr(cdr.AsStoredCdr()); err != nil { t.Error(err.Error()) } } - strCdr1 := &utils.StoredCdr{TOR: utils.VOICE, AccId: "bbb1", CdrHost: "192.168.1.1", CdrSource: "UNKNOWN", ReqType: utils.META_RATED, + strCdr1 := &StoredCdr{TOR: utils.VOICE, AccId: "bbb1", CdrHost: "192.168.1.1", CdrSource: "UNKNOWN", ReqType: utils.META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC), Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, MediationRunId: utils.DEFAULT_RUNID, Cost: 1.201} strCdr1.CgrId = utils.Sha1(strCdr1.AccId, strCdr1.SetupTime.String()) - strCdr2 := &utils.StoredCdr{TOR: utils.VOICE, AccId: "bbb2", CdrHost: "192.168.1.2", CdrSource: "UNKNOWN2", ReqType: utils.META_PREPAID, + strCdr2 := &StoredCdr{TOR: utils.VOICE, AccId: "bbb2", CdrHost: "192.168.1.2", CdrSource: "UNKNOWN2", ReqType: utils.META_PREPAID, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC), Usage: time.Duration(12) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, MediationRunId: utils.DEFAULT_RUNID, Cost: 0.201} strCdr2.CgrId = utils.Sha1(strCdr2.AccId, strCdr2.SetupTime.String()) - strCdr3 := &utils.StoredCdr{TOR: utils.VOICE, AccId: "bbb3", CdrHost: "192.168.1.1", CdrSource: TEST_SQL, ReqType: utils.META_RATED, + strCdr3 := &StoredCdr{TOR: utils.VOICE, AccId: "bbb3", CdrHost: "192.168.1.1", CdrSource: TEST_SQL, ReqType: utils.META_RATED, Direction: "*out", Tenant: "itsyscom.com", Category: "call", Account: "1002", Subject: "1000", Destination: "+4986517174963", SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC), Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, MediationRunId: utils.DEFAULT_RUNID, Cost: 1.201} strCdr3.CgrId = utils.Sha1(strCdr3.AccId, strCdr3.SetupTime.String()) - for _, cdr := range []*utils.StoredCdr{strCdr1, strCdr2, strCdr3} { + for _, cdr := range []*StoredCdr{strCdr1, strCdr2, strCdr3} { if err := mysqlDb.SetCdr(cdr); err != nil { t.Error(err.Error()) } @@ -485,26 +485,26 @@ func TestMySQLSetRatedCdr(t *testing.T) { if !*testLocal { return } - strCdr1 := &utils.StoredCdr{TOR: utils.VOICE, AccId: "bbb1", CdrHost: "192.168.1.1", CdrSource: "UNKNOWN", ReqType: utils.META_RATED, + strCdr1 := &StoredCdr{TOR: utils.VOICE, AccId: "bbb1", CdrHost: "192.168.1.1", CdrSource: "UNKNOWN", ReqType: utils.META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC), Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, MediationRunId: utils.DEFAULT_RUNID, Cost: 1.201} strCdr1.CgrId = utils.Sha1(strCdr1.AccId, strCdr1.SetupTime.String()) - strCdr2 := &utils.StoredCdr{TOR: utils.VOICE, AccId: "bbb2", CdrHost: "192.168.1.2", CdrSource: "UNKNOWN", ReqType: utils.META_PREPAID, + strCdr2 := &StoredCdr{TOR: utils.VOICE, AccId: "bbb2", CdrHost: "192.168.1.2", CdrSource: "UNKNOWN", ReqType: utils.META_PREPAID, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC), Usage: time.Duration(12) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, MediationRunId: utils.DEFAULT_RUNID, Cost: 0.201} strCdr2.CgrId = utils.Sha1(strCdr2.AccId, strCdr2.SetupTime.String()) - strCdr3 := &utils.StoredCdr{TOR: utils.VOICE, AccId: "bbb3", CdrHost: "192.168.1.1", CdrSource: TEST_SQL, ReqType: utils.META_RATED, + strCdr3 := &StoredCdr{TOR: utils.VOICE, AccId: "bbb3", CdrHost: "192.168.1.1", CdrSource: TEST_SQL, ReqType: utils.META_RATED, Direction: "*out", Tenant: "itsyscom.com", Category: "call", Account: "1002", Subject: "1002", Destination: "+4986517174964", SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC), Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, MediationRunId: "wholesale_run", Cost: 1.201} strCdr3.CgrId = utils.Sha1(strCdr3.AccId, strCdr3.SetupTime.String()) - for _, cdr := range []*utils.StoredCdr{strCdr1, strCdr2, strCdr3} { + for _, cdr := range []*StoredCdr{strCdr1, strCdr2, strCdr3} { if err := mysqlDb.SetRatedCdr(cdr, ""); err != nil { t.Error(err.Error()) } diff --git a/engine/storage_postgres.go b/engine/storage_postgres.go index f035e98af..324fd34eb 100644 --- a/engine/storage_postgres.go +++ b/engine/storage_postgres.go @@ -120,7 +120,7 @@ func (self *PostgresStorage) LogCallCost(cgrid, source, runid string, cc *CallCo return nil } -func (self *PostgresStorage) SetRatedCdr(cdr *utils.StoredCdr, extraInfo string) (err error) { +func (self *PostgresStorage) SetRatedCdr(cdr *StoredCdr, extraInfo string) (err error) { tx := self.db.Begin() saved := tx.Save(&TblRatedCdr{ Cgrid: cdr.CgrId, diff --git a/engine/storage_psql_local_test.go b/engine/storage_psql_local_test.go index 5c8ae1f08..daf7cad99 100644 --- a/engine/storage_psql_local_test.go +++ b/engine/storage_psql_local_test.go @@ -433,50 +433,50 @@ func TestPSQLSetCdr(t *testing.T) { if !*testLocal { return } - cgrCdr1 := &utils.CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa1", utils.CDRHOST: "192.168.1.1", utils.REQTYPE: utils.META_RATED, utils.DIRECTION: "*out", utils.TENANT: "cgrates.org", + cgrCdr1 := &CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa1", utils.CDRHOST: "192.168.1.1", utils.REQTYPE: utils.META_RATED, utils.DIRECTION: "*out", utils.TENANT: "cgrates.org", utils.CATEGORY: "call", utils.ACCOUNT: "1001", utils.SUBJECT: "1001", utils.DESTINATION: "1002", utils.SETUP_TIME: "2013-11-08T08:42:20Z", utils.ANSWER_TIME: "2013-11-08T08:42:26Z", utils.USAGE: "10s", "field_extr1": "val_extr1", "fieldextr2": "valextr2", utils.CDRSOURCE: TEST_SQL} - cgrCdr2 := &utils.CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa2", utils.CDRHOST: "192.168.1.1", utils.REQTYPE: utils.META_PREPAID, utils.DIRECTION: "*out", utils.TENANT: "cgrates.org", + cgrCdr2 := &CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa2", utils.CDRHOST: "192.168.1.1", utils.REQTYPE: utils.META_PREPAID, utils.DIRECTION: "*out", utils.TENANT: "cgrates.org", utils.CATEGORY: "call", utils.ACCOUNT: "1001", utils.SUBJECT: "1001", utils.DESTINATION: "1002", utils.SETUP_TIME: "2013-11-08T08:42:22Z", utils.ANSWER_TIME: "2013-11-08T08:42:26Z", utils.USAGE: "20", "field_extr1": "val_extr1", "fieldextr2": "valextr2", "cdrsource": TEST_SQL} - cgrCdr3 := &utils.CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa3", utils.CDRHOST: "192.168.1.1", utils.REQTYPE: utils.META_RATED, utils.DIRECTION: "*out", utils.TENANT: "cgrates.org", + cgrCdr3 := &CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa3", utils.CDRHOST: "192.168.1.1", utils.REQTYPE: utils.META_RATED, utils.DIRECTION: "*out", utils.TENANT: "cgrates.org", utils.CATEGORY: "premium_call", utils.ACCOUNT: "1002", utils.SUBJECT: "1002", utils.DESTINATION: "1001", utils.SETUP_TIME: "2013-11-07T08:42:24Z", utils.ANSWER_TIME: "2013-11-07T08:42:26Z", utils.USAGE: "60s", "field_extr1": "val_extr1", "fieldextr2": "valextr2", "cdrsource": TEST_SQL} - cgrCdr4 := &utils.CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa4", utils.CDRHOST: "192.168.1.2", utils.REQTYPE: utils.META_PSEUDOPREPAID, utils.DIRECTION: "*out", utils.TENANT: "itsyscom.com", + cgrCdr4 := &CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa4", utils.CDRHOST: "192.168.1.2", utils.REQTYPE: utils.META_PSEUDOPREPAID, utils.DIRECTION: "*out", utils.TENANT: "itsyscom.com", utils.CATEGORY: "call", utils.ACCOUNT: "1001", utils.SUBJECT: "1001", utils.DESTINATION: "+4986517174964", utils.SETUP_TIME: "2013-11-07T08:42:21Z", utils.ANSWER_TIME: "2013-11-07T08:42:26Z", utils.USAGE: "1m2s", "field_extr1": "val_extr1", "fieldextr2": "valextr2", "cdrsource": TEST_SQL} - cgrCdr5 := &utils.CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa5", utils.CDRHOST: "192.168.1.2", utils.REQTYPE: utils.META_POSTPAID, utils.DIRECTION: "*out", utils.TENANT: "itsyscom.com", + cgrCdr5 := &CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa5", utils.CDRHOST: "192.168.1.2", utils.REQTYPE: utils.META_POSTPAID, utils.DIRECTION: "*out", utils.TENANT: "itsyscom.com", utils.CATEGORY: "call", utils.ACCOUNT: "1002", utils.SUBJECT: "1002", utils.DESTINATION: "+4986517174963", utils.SETUP_TIME: "2013-11-07T08:42:25Z", utils.ANSWER_TIME: "2013-11-07T08:42:26Z", utils.USAGE: "15s", "field_extr1": "val_extr1", "fieldextr2": "valextr2", "cdrsource": TEST_SQL} - for _, cdr := range []*utils.CgrCdr{cgrCdr1, cgrCdr2, cgrCdr3, cgrCdr4, cgrCdr5} { + for _, cdr := range []*CgrCdr{cgrCdr1, cgrCdr2, cgrCdr3, cgrCdr4, cgrCdr5} { if err := psqlDb.SetCdr(cdr.AsStoredCdr()); err != nil { t.Error(err.Error()) } } - strCdr1 := &utils.StoredCdr{TOR: utils.VOICE, AccId: "bbb1", CdrHost: "192.168.1.1", CdrSource: "UNKNOWN", ReqType: utils.META_RATED, + strCdr1 := &StoredCdr{TOR: utils.VOICE, AccId: "bbb1", CdrHost: "192.168.1.1", CdrSource: "UNKNOWN", ReqType: utils.META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC), Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, MediationRunId: utils.DEFAULT_RUNID, Cost: 1.201} strCdr1.CgrId = utils.Sha1(strCdr1.AccId, strCdr1.SetupTime.String()) - strCdr2 := &utils.StoredCdr{TOR: utils.VOICE, AccId: "bbb2", CdrHost: "192.168.1.2", CdrSource: "UNKNOWN2", ReqType: utils.META_PREPAID, + strCdr2 := &StoredCdr{TOR: utils.VOICE, AccId: "bbb2", CdrHost: "192.168.1.2", CdrSource: "UNKNOWN2", ReqType: utils.META_PREPAID, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC), Usage: time.Duration(12) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, MediationRunId: utils.DEFAULT_RUNID, Cost: 0.201} strCdr2.CgrId = utils.Sha1(strCdr2.AccId, strCdr2.SetupTime.String()) - strCdr3 := &utils.StoredCdr{TOR: utils.VOICE, AccId: "bbb3", CdrHost: "192.168.1.1", CdrSource: TEST_SQL, ReqType: utils.META_RATED, + strCdr3 := &StoredCdr{TOR: utils.VOICE, AccId: "bbb3", CdrHost: "192.168.1.1", CdrSource: TEST_SQL, ReqType: utils.META_RATED, Direction: "*out", Tenant: "itsyscom.com", Category: "call", Account: "1002", Subject: "1000", Destination: "+4986517174963", SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC), Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, MediationRunId: utils.DEFAULT_RUNID, Cost: 1.201} strCdr3.CgrId = utils.Sha1(strCdr3.AccId, strCdr3.SetupTime.String()) - for _, cdr := range []*utils.StoredCdr{strCdr1, strCdr2, strCdr3} { + for _, cdr := range []*StoredCdr{strCdr1, strCdr2, strCdr3} { if err := psqlDb.SetCdr(cdr); err != nil { t.Error(err.Error()) } @@ -531,26 +531,26 @@ func TestPSQLSetRatedCdr(t *testing.T) { if !*testLocal { return } - strCdr1 := &utils.StoredCdr{TOR: utils.VOICE, AccId: "bbb1", CdrHost: "192.168.1.1", CdrSource: "UNKNOWN", ReqType: utils.META_RATED, + strCdr1 := &StoredCdr{TOR: utils.VOICE, AccId: "bbb1", CdrHost: "192.168.1.1", CdrSource: "UNKNOWN", ReqType: utils.META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC), Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, MediationRunId: utils.DEFAULT_RUNID, Cost: 1.201} strCdr1.CgrId = utils.Sha1(strCdr1.AccId, strCdr1.SetupTime.String()) - strCdr2 := &utils.StoredCdr{TOR: utils.VOICE, AccId: "bbb2", CdrHost: "192.168.1.2", CdrSource: "UNKNOWN", ReqType: utils.META_PREPAID, + strCdr2 := &StoredCdr{TOR: utils.VOICE, AccId: "bbb2", CdrHost: "192.168.1.2", CdrSource: "UNKNOWN", ReqType: utils.META_PREPAID, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC), Usage: time.Duration(12) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, MediationRunId: utils.DEFAULT_RUNID, Cost: 0.201} strCdr2.CgrId = utils.Sha1(strCdr2.AccId, strCdr2.SetupTime.String()) - strCdr3 := &utils.StoredCdr{TOR: utils.VOICE, AccId: "bbb3", CdrHost: "192.168.1.1", CdrSource: TEST_SQL, ReqType: utils.META_RATED, + strCdr3 := &StoredCdr{TOR: utils.VOICE, AccId: "bbb3", CdrHost: "192.168.1.1", CdrSource: TEST_SQL, ReqType: utils.META_RATED, Direction: "*out", Tenant: "itsyscom.com", Category: "call", Account: "1002", Subject: "1002", Destination: "+4986517174964", SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC), Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, MediationRunId: "wholesale_run", Cost: 1.201} strCdr3.CgrId = utils.Sha1(strCdr3.AccId, strCdr3.SetupTime.String()) - for _, cdr := range []*utils.StoredCdr{strCdr1, strCdr2, strCdr3} { + for _, cdr := range []*StoredCdr{strCdr1, strCdr2, strCdr3} { if err := psqlDb.SetRatedCdr(cdr, ""); err != nil { t.Error(err.Error()) } diff --git a/engine/storage_sql.go b/engine/storage_sql.go index fbb45703c..c900965f9 100644 --- a/engine/storage_sql.go +++ b/engine/storage_sql.go @@ -716,7 +716,7 @@ func (self *SQLStorage) LogActionTiming(source string, at *ActionTiming, as Acti } func (self *SQLStorage) LogError(uuid, source, runid, errstr string) (err error) { return } -func (self *SQLStorage) SetCdr(cdr *utils.StoredCdr) error { +func (self *SQLStorage) SetCdr(cdr *StoredCdr) error { extraFields, err := json.Marshal(cdr.ExtraFields) if err != nil { return err @@ -752,12 +752,12 @@ func (self *SQLStorage) SetCdr(cdr *utils.StoredCdr) error { return nil } -func (self *SQLStorage) SetRatedCdr(storedCdr *utils.StoredCdr, extraInfo string) error { +func (self *SQLStorage) SetRatedCdr(storedCdr *StoredCdr, extraInfo string) error { return errors.New(utils.ERR_NOT_IMPLEMENTED) } -func (self *SQLStorage) GetStoredCdrs(qryFltr *utils.CdrsFilter) ([]*utils.StoredCdr, int64, error) { - var cdrs []*utils.StoredCdr +func (self *SQLStorage) GetStoredCdrs(qryFltr *utils.CdrsFilter) ([]*StoredCdr, int64, error) { + var cdrs []*StoredCdr // Select string var selectStr string if qryFltr.IgnoreDerived { // We use different tables to query account data in case of derived @@ -999,7 +999,7 @@ func (self *SQLStorage) GetStoredCdrs(qryFltr *utils.CdrsFilter) ([]*utils.Store } } usageDur, _ := time.ParseDuration(strconv.FormatFloat(usage.Float64, 'f', -1, 64) + "s") - storCdr := &utils.StoredCdr{ + storCdr := &StoredCdr{ 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, diff --git a/utils/storedcdr.go b/engine/storedcdr.go similarity index 56% rename from utils/storedcdr.go rename to engine/storedcdr.go index f2c3e9121..e8203bdf3 100644 --- a/utils/storedcdr.go +++ b/engine/storedcdr.go @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see */ -package utils +package engine import ( "encoding/json" @@ -27,6 +27,8 @@ import ( "strconv" "strings" "time" + + "github.com/cgrates/cgrates/utils" ) // Kinda standard of internal CDR, complies to CDR interface also @@ -52,18 +54,18 @@ type StoredCdr struct { RatedAccount string // Populated out of rating data RatedSubject string Cost float64 - //CostDetails *CallCost - Rated bool // Mark the CDR as rated so we do not process it during mediation + CostDetails *CallCost // Attach the cost details to CDR when possible + Rated bool // Mark the CDR as rated so we do not process it during mediation } // Used to multiply usage on export func (storedCdr *StoredCdr) UsageMultiply(multiplyFactor float64, roundDecimals int) { - storedCdr.Usage = time.Duration(int(Round(float64(storedCdr.Usage.Nanoseconds())*multiplyFactor, roundDecimals, ROUNDING_MIDDLE))) // Rounding down could introduce a slight loss here but only at nanoseconds level + storedCdr.Usage = time.Duration(int(utils.Round(float64(storedCdr.Usage.Nanoseconds())*multiplyFactor, roundDecimals, utils.ROUNDING_MIDDLE))) // Rounding down could introduce a slight loss here but only at nanoseconds level } // Used to multiply cost on export func (storedCdr *StoredCdr) CostMultiply(multiplyFactor float64, roundDecimals int) { - storedCdr.Cost = Round(storedCdr.Cost*multiplyFactor, roundDecimals, ROUNDING_MIDDLE) + storedCdr.Cost = utils.Round(storedCdr.Cost*multiplyFactor, roundDecimals, utils.ROUNDING_MIDDLE) } // Format cost as string on export @@ -77,8 +79,8 @@ func (storedCdr *StoredCdr) FormatCost(shiftDecimals, roundDecimals int) string // Formats usage on export func (storedCdr *StoredCdr) FormatUsage(layout string) string { - if IsSliceMember([]string{DATA, SMS}, storedCdr.TOR) { - return strconv.FormatFloat(Round(storedCdr.Usage.Seconds(), 0, ROUNDING_MIDDLE), 'f', -1, 64) + if utils.IsSliceMember([]string{utils.DATA, utils.SMS}, storedCdr.TOR) { + return strconv.FormatFloat(utils.Round(storedCdr.Usage.Seconds(), 0, utils.ROUNDING_MIDDLE), 'f', -1, 64) } switch layout { default: @@ -87,64 +89,64 @@ func (storedCdr *StoredCdr) FormatUsage(layout string) string { } // Used to retrieve fields as string, primary fields are const labeled -func (storedCdr *StoredCdr) FieldAsString(rsrFld *RSRField) string { +func (storedCdr *StoredCdr) FieldAsString(rsrFld *utils.RSRField) string { switch rsrFld.Id { - case CGRID: + case utils.CGRID: return rsrFld.ParseValue(storedCdr.CgrId) - case ORDERID: + case utils.ORDERID: return rsrFld.ParseValue(strconv.FormatInt(storedCdr.OrderId, 10)) - case TOR: + case utils.TOR: return rsrFld.ParseValue(storedCdr.TOR) - case ACCID: + case utils.ACCID: return rsrFld.ParseValue(storedCdr.AccId) - case CDRHOST: + case utils.CDRHOST: return rsrFld.ParseValue(storedCdr.CdrHost) - case CDRSOURCE: + case utils.CDRSOURCE: return rsrFld.ParseValue(storedCdr.CdrSource) - case REQTYPE: + case utils.REQTYPE: return rsrFld.ParseValue(storedCdr.ReqType) - case DIRECTION: + case utils.DIRECTION: return rsrFld.ParseValue(storedCdr.Direction) - case TENANT: + case utils.TENANT: return rsrFld.ParseValue(storedCdr.Tenant) - case CATEGORY: + case utils.CATEGORY: return rsrFld.ParseValue(storedCdr.Category) - case ACCOUNT: + case utils.ACCOUNT: return rsrFld.ParseValue(storedCdr.Account) - case SUBJECT: + case utils.SUBJECT: return rsrFld.ParseValue(storedCdr.Subject) - case DESTINATION: + case utils.DESTINATION: return rsrFld.ParseValue(storedCdr.Destination) - case SETUP_TIME: + case utils.SETUP_TIME: return rsrFld.ParseValue(storedCdr.SetupTime.Format(time.RFC3339)) - case ANSWER_TIME: + case utils.ANSWER_TIME: return rsrFld.ParseValue(storedCdr.AnswerTime.Format(time.RFC3339)) - case USAGE: - return strconv.FormatFloat(Round(storedCdr.Usage.Seconds(), 0, ROUNDING_MIDDLE), 'f', -1, 64) - case MEDI_RUNID: + case utils.USAGE: + return strconv.FormatFloat(utils.Round(storedCdr.Usage.Seconds(), 0, utils.ROUNDING_MIDDLE), 'f', -1, 64) + case utils.MEDI_RUNID: return rsrFld.ParseValue(storedCdr.MediationRunId) - case RATED_ACCOUNT: + case utils.RATED_ACCOUNT: return rsrFld.ParseValue(storedCdr.RatedAccount) - case RATED_SUBJECT: + case utils.RATED_SUBJECT: return rsrFld.ParseValue(storedCdr.RatedSubject) - case COST: + case utils.COST: return rsrFld.ParseValue(strconv.FormatFloat(storedCdr.Cost, 'f', -1, 64)) // Recommended to use FormatCost default: return rsrFld.ParseValue(storedCdr.ExtraFields[rsrFld.Id]) } } -func (storedCdr *StoredCdr) PassesFieldFilter(fieldFilter *RSRField) (bool, string) { +func (storedCdr *StoredCdr) PassesFieldFilter(fieldFilter *utils.RSRField) (bool, string) { if fieldFilter == nil { return true, "" } - if fieldFilter.IsStatic() && storedCdr.FieldAsString(&RSRField{Id: fieldFilter.Id}) == storedCdr.FieldAsString(fieldFilter) { - return true, storedCdr.FieldAsString(&RSRField{Id: fieldFilter.Id}) + if fieldFilter.IsStatic() && storedCdr.FieldAsString(&utils.RSRField{Id: fieldFilter.Id}) == storedCdr.FieldAsString(fieldFilter) { + return true, storedCdr.FieldAsString(&utils.RSRField{Id: fieldFilter.Id}) } - preparedFilter := &RSRField{Id: fieldFilter.Id, RSRules: make([]*ReSearchReplace, len(fieldFilter.RSRules))} // Reset rules so they do not point towards same structures as original fieldFilter + preparedFilter := &utils.RSRField{Id: fieldFilter.Id, RSRules: make([]*utils.ReSearchReplace, len(fieldFilter.RSRules))} // Reset rules so they do not point towards same structures as original fieldFilter for idx := range fieldFilter.RSRules { // Hardcode the template with maximum of 5 groups ordered - preparedFilter.RSRules[idx] = &ReSearchReplace{SearchRegexp: fieldFilter.RSRules[idx].SearchRegexp, ReplaceTemplate: FILTER_REGEXP_TPL} + preparedFilter.RSRules[idx] = &utils.ReSearchReplace{SearchRegexp: fieldFilter.RSRules[idx].SearchRegexp, ReplaceTemplate: utils.FILTER_REGEXP_TPL} } preparedVal := storedCdr.FieldAsString(preparedFilter) filteredValue := storedCdr.FieldAsString(fieldFilter) @@ -164,85 +166,85 @@ func (storedCdr *StoredCdr) AsHttpForm() url.Values { for fld, val := range storedCdr.ExtraFields { v.Set(fld, val) } - v.Set(TOR, storedCdr.TOR) - v.Set(ACCID, storedCdr.AccId) - v.Set(CDRHOST, storedCdr.CdrHost) - v.Set(CDRSOURCE, storedCdr.CdrSource) - v.Set(REQTYPE, storedCdr.ReqType) - v.Set(DIRECTION, storedCdr.Direction) - v.Set(TENANT, storedCdr.Tenant) - v.Set(CATEGORY, storedCdr.Category) - v.Set(ACCOUNT, storedCdr.Account) - v.Set(SUBJECT, storedCdr.Subject) - v.Set(DESTINATION, storedCdr.Destination) - v.Set(SETUP_TIME, storedCdr.SetupTime.Format(time.RFC3339)) - v.Set(ANSWER_TIME, storedCdr.AnswerTime.Format(time.RFC3339)) - v.Set(USAGE, storedCdr.FormatUsage(SECONDS)) + v.Set(utils.TOR, storedCdr.TOR) + v.Set(utils.ACCID, storedCdr.AccId) + v.Set(utils.CDRHOST, storedCdr.CdrHost) + v.Set(utils.CDRSOURCE, storedCdr.CdrSource) + v.Set(utils.REQTYPE, storedCdr.ReqType) + v.Set(utils.DIRECTION, storedCdr.Direction) + v.Set(utils.TENANT, storedCdr.Tenant) + v.Set(utils.CATEGORY, storedCdr.Category) + v.Set(utils.ACCOUNT, storedCdr.Account) + v.Set(utils.SUBJECT, storedCdr.Subject) + v.Set(utils.DESTINATION, storedCdr.Destination) + v.Set(utils.SETUP_TIME, storedCdr.SetupTime.Format(time.RFC3339)) + v.Set(utils.ANSWER_TIME, storedCdr.AnswerTime.Format(time.RFC3339)) + v.Set(utils.USAGE, storedCdr.FormatUsage(utils.SECONDS)) return v } // Used in mediation, primaryMandatory marks whether missing field out of request represents error or can be ignored -func (storedCdr *StoredCdr) ForkCdr(runId string, reqTypeFld, directionFld, tenantFld, categFld, accountFld, subjectFld, destFld, setupTimeFld, answerTimeFld, durationFld *RSRField, - extraFlds []*RSRField, primaryMandatory bool) (*StoredCdr, error) { +func (storedCdr *StoredCdr) ForkCdr(runId string, reqTypeFld, directionFld, tenantFld, categFld, accountFld, subjectFld, destFld, setupTimeFld, answerTimeFld, durationFld *utils.RSRField, + extraFlds []*utils.RSRField, primaryMandatory bool) (*StoredCdr, error) { if reqTypeFld == nil { - reqTypeFld, _ = NewRSRField(META_DEFAULT) + reqTypeFld, _ = utils.NewRSRField(utils.META_DEFAULT) } - if reqTypeFld.Id == META_DEFAULT { - reqTypeFld.Id = REQTYPE + if reqTypeFld.Id == utils.META_DEFAULT { + reqTypeFld.Id = utils.REQTYPE } if directionFld == nil { - directionFld, _ = NewRSRField(META_DEFAULT) + directionFld, _ = utils.NewRSRField(utils.META_DEFAULT) } - if directionFld.Id == META_DEFAULT { - directionFld.Id = DIRECTION + if directionFld.Id == utils.META_DEFAULT { + directionFld.Id = utils.DIRECTION } if tenantFld == nil { - tenantFld, _ = NewRSRField(META_DEFAULT) + tenantFld, _ = utils.NewRSRField(utils.META_DEFAULT) } - if tenantFld.Id == META_DEFAULT { - tenantFld.Id = TENANT + if tenantFld.Id == utils.META_DEFAULT { + tenantFld.Id = utils.TENANT } if categFld == nil { - categFld, _ = NewRSRField(META_DEFAULT) + categFld, _ = utils.NewRSRField(utils.META_DEFAULT) } - if categFld.Id == META_DEFAULT { - categFld.Id = CATEGORY + if categFld.Id == utils.META_DEFAULT { + categFld.Id = utils.CATEGORY } if accountFld == nil { - accountFld, _ = NewRSRField(META_DEFAULT) + accountFld, _ = utils.NewRSRField(utils.META_DEFAULT) } - if accountFld.Id == META_DEFAULT { - accountFld.Id = ACCOUNT + if accountFld.Id == utils.META_DEFAULT { + accountFld.Id = utils.ACCOUNT } if subjectFld == nil { - subjectFld, _ = NewRSRField(META_DEFAULT) + subjectFld, _ = utils.NewRSRField(utils.META_DEFAULT) } - if subjectFld.Id == META_DEFAULT { - subjectFld.Id = SUBJECT + if subjectFld.Id == utils.META_DEFAULT { + subjectFld.Id = utils.SUBJECT } if destFld == nil { - destFld, _ = NewRSRField(META_DEFAULT) + destFld, _ = utils.NewRSRField(utils.META_DEFAULT) } - if destFld.Id == META_DEFAULT { - destFld.Id = DESTINATION + if destFld.Id == utils.META_DEFAULT { + destFld.Id = utils.DESTINATION } if setupTimeFld == nil { - setupTimeFld, _ = NewRSRField(META_DEFAULT) + setupTimeFld, _ = utils.NewRSRField(utils.META_DEFAULT) } - if setupTimeFld.Id == META_DEFAULT { - setupTimeFld.Id = SETUP_TIME + if setupTimeFld.Id == utils.META_DEFAULT { + setupTimeFld.Id = utils.SETUP_TIME } if answerTimeFld == nil { - answerTimeFld, _ = NewRSRField(META_DEFAULT) + answerTimeFld, _ = utils.NewRSRField(utils.META_DEFAULT) } - if answerTimeFld.Id == META_DEFAULT { - answerTimeFld.Id = ANSWER_TIME + if answerTimeFld.Id == utils.META_DEFAULT { + answerTimeFld.Id = utils.ANSWER_TIME } if durationFld == nil { - durationFld, _ = NewRSRField(META_DEFAULT) + durationFld, _ = utils.NewRSRField(utils.META_DEFAULT) } - if durationFld.Id == META_DEFAULT { - durationFld.Id = USAGE + if durationFld.Id == utils.META_DEFAULT { + durationFld.Id = utils.USAGE } var err error frkStorCdr := new(StoredCdr) @@ -255,48 +257,48 @@ func (storedCdr *StoredCdr) ForkCdr(runId string, reqTypeFld, directionFld, tena frkStorCdr.CdrSource = storedCdr.CdrSource frkStorCdr.ReqType = storedCdr.FieldAsString(reqTypeFld) if primaryMandatory && len(frkStorCdr.ReqType) == 0 { - return nil, errors.New(fmt.Sprintf("%s:%s:%s", ERR_MANDATORY_IE_MISSING, REQTYPE, reqTypeFld.Id)) + return nil, errors.New(fmt.Sprintf("%s:%s:%s", utils.ERR_MANDATORY_IE_MISSING, utils.REQTYPE, reqTypeFld.Id)) } frkStorCdr.Direction = storedCdr.FieldAsString(directionFld) if primaryMandatory && len(frkStorCdr.Direction) == 0 { - return nil, errors.New(fmt.Sprintf("%s:%s:%s", ERR_MANDATORY_IE_MISSING, DIRECTION, directionFld.Id)) + return nil, errors.New(fmt.Sprintf("%s:%s:%s", utils.ERR_MANDATORY_IE_MISSING, utils.DIRECTION, directionFld.Id)) } frkStorCdr.Tenant = storedCdr.FieldAsString(tenantFld) if primaryMandatory && len(frkStorCdr.Tenant) == 0 { - return nil, errors.New(fmt.Sprintf("%s:%s:%s", ERR_MANDATORY_IE_MISSING, TENANT, tenantFld.Id)) + return nil, errors.New(fmt.Sprintf("%s:%s:%s", utils.ERR_MANDATORY_IE_MISSING, utils.TENANT, tenantFld.Id)) } frkStorCdr.Category = storedCdr.FieldAsString(categFld) if primaryMandatory && len(frkStorCdr.Category) == 0 { - return nil, errors.New(fmt.Sprintf("%s:%s:%s", ERR_MANDATORY_IE_MISSING, CATEGORY, categFld.Id)) + return nil, errors.New(fmt.Sprintf("%s:%s:%s", utils.ERR_MANDATORY_IE_MISSING, utils.CATEGORY, categFld.Id)) } frkStorCdr.Account = storedCdr.FieldAsString(accountFld) if primaryMandatory && len(frkStorCdr.Account) == 0 { - return nil, errors.New(fmt.Sprintf("%s:%s:%s", ERR_MANDATORY_IE_MISSING, ACCOUNT, accountFld.Id)) + return nil, errors.New(fmt.Sprintf("%s:%s:%s", utils.ERR_MANDATORY_IE_MISSING, utils.ACCOUNT, accountFld.Id)) } frkStorCdr.Subject = storedCdr.FieldAsString(subjectFld) if primaryMandatory && len(frkStorCdr.Subject) == 0 { - return nil, errors.New(fmt.Sprintf("%s:%s:%s", ERR_MANDATORY_IE_MISSING, SUBJECT, subjectFld.Id)) + return nil, errors.New(fmt.Sprintf("%s:%s:%s", utils.ERR_MANDATORY_IE_MISSING, utils.SUBJECT, subjectFld.Id)) } frkStorCdr.Destination = storedCdr.FieldAsString(destFld) - if primaryMandatory && len(frkStorCdr.Destination) == 0 && frkStorCdr.TOR == VOICE { - return nil, errors.New(fmt.Sprintf("%s:%s:%s", ERR_MANDATORY_IE_MISSING, DESTINATION, destFld.Id)) + if primaryMandatory && len(frkStorCdr.Destination) == 0 && frkStorCdr.TOR == utils.VOICE { + return nil, errors.New(fmt.Sprintf("%s:%s:%s", utils.ERR_MANDATORY_IE_MISSING, utils.DESTINATION, destFld.Id)) } sTimeStr := storedCdr.FieldAsString(setupTimeFld) if primaryMandatory && len(sTimeStr) == 0 { - return nil, errors.New(fmt.Sprintf("%s:%s:%s", ERR_MANDATORY_IE_MISSING, SETUP_TIME, setupTimeFld.Id)) - } else if frkStorCdr.SetupTime, err = ParseTimeDetectLayout(sTimeStr); err != nil { + return nil, errors.New(fmt.Sprintf("%s:%s:%s", utils.ERR_MANDATORY_IE_MISSING, utils.SETUP_TIME, setupTimeFld.Id)) + } else if frkStorCdr.SetupTime, err = utils.ParseTimeDetectLayout(sTimeStr); err != nil { return nil, err } aTimeStr := storedCdr.FieldAsString(answerTimeFld) if primaryMandatory && len(aTimeStr) == 0 { - return nil, errors.New(fmt.Sprintf("%s:%s:%s", ERR_MANDATORY_IE_MISSING, ANSWER_TIME, answerTimeFld.Id)) - } else if frkStorCdr.AnswerTime, err = ParseTimeDetectLayout(aTimeStr); err != nil { + return nil, errors.New(fmt.Sprintf("%s:%s:%s", utils.ERR_MANDATORY_IE_MISSING, utils.ANSWER_TIME, answerTimeFld.Id)) + } else if frkStorCdr.AnswerTime, err = utils.ParseTimeDetectLayout(aTimeStr); err != nil { return nil, err } durStr := storedCdr.FieldAsString(durationFld) if primaryMandatory && len(durStr) == 0 { - return nil, errors.New(fmt.Sprintf("%s:%s:%s", ERR_MANDATORY_IE_MISSING, USAGE, durationFld.Id)) - } else if frkStorCdr.Usage, err = ParseDurationWithSecs(durStr); err != nil { + return nil, errors.New(fmt.Sprintf("%s:%s:%s", utils.ERR_MANDATORY_IE_MISSING, utils.USAGE, durationFld.Id)) + } else if frkStorCdr.Usage, err = utils.ParseDurationWithSecs(durStr); err != nil { return nil, err } frkStorCdr.ExtraFields = make(map[string]string, len(extraFlds)) @@ -322,7 +324,7 @@ func (storedCdr *StoredCdr) AsCgrExtCdr() *CgrExtCdr { Destination: storedCdr.Destination, SetupTime: storedCdr.SetupTime.Format(time.RFC3339), AnswerTime: storedCdr.AnswerTime.Format(time.RFC3339), - Usage: storedCdr.FormatUsage(SECONDS), + Usage: storedCdr.FormatUsage(utils.SECONDS), ExtraFields: storedCdr.ExtraFields, MediationRunId: storedCdr.MediationRunId, RatedAccount: storedCdr.RatedAccount, @@ -348,121 +350,121 @@ func (storedCdr *StoredCdr) GetSessionIds() []string { return []string{storedCdr.GetUUID()} } func (storedCdr *StoredCdr) GetDirection(fieldName string) string { - if IsSliceMember([]string{DIRECTION, META_DEFAULT}, fieldName) { + if utils.IsSliceMember([]string{utils.DIRECTION, utils.META_DEFAULT}, fieldName) { return storedCdr.Direction } - if strings.HasPrefix(fieldName, STATIC_VALUE_PREFIX) { // Static value - return fieldName[len(STATIC_VALUE_PREFIX):] + if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value + return fieldName[len(utils.STATIC_VALUE_PREFIX):] } - return storedCdr.FieldAsString(&RSRField{Id: fieldName}) + return storedCdr.FieldAsString(&utils.RSRField{Id: fieldName}) } func (storedCdr *StoredCdr) GetSubject(fieldName string) string { - if IsSliceMember([]string{SUBJECT, META_DEFAULT}, fieldName) { + if utils.IsSliceMember([]string{utils.SUBJECT, utils.META_DEFAULT}, fieldName) { return storedCdr.Subject } - if strings.HasPrefix(fieldName, STATIC_VALUE_PREFIX) { // Static value - return fieldName[len(STATIC_VALUE_PREFIX):] + if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value + return fieldName[len(utils.STATIC_VALUE_PREFIX):] } - return storedCdr.FieldAsString(&RSRField{Id: fieldName}) + return storedCdr.FieldAsString(&utils.RSRField{Id: fieldName}) } func (storedCdr *StoredCdr) GetAccount(fieldName string) string { - if IsSliceMember([]string{ACCOUNT, META_DEFAULT}, fieldName) { + if utils.IsSliceMember([]string{utils.ACCOUNT, utils.META_DEFAULT}, fieldName) { return storedCdr.Account } - if strings.HasPrefix(fieldName, STATIC_VALUE_PREFIX) { // Static value - return fieldName[len(STATIC_VALUE_PREFIX):] + if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value + return fieldName[len(utils.STATIC_VALUE_PREFIX):] } - return storedCdr.FieldAsString(&RSRField{Id: fieldName}) + return storedCdr.FieldAsString(&utils.RSRField{Id: fieldName}) } func (storedCdr *StoredCdr) GetDestination(fieldName string) string { - if IsSliceMember([]string{DESTINATION, META_DEFAULT}, fieldName) { + if utils.IsSliceMember([]string{utils.DESTINATION, utils.META_DEFAULT}, fieldName) { return storedCdr.Destination } - if strings.HasPrefix(fieldName, STATIC_VALUE_PREFIX) { // Static value - return fieldName[len(STATIC_VALUE_PREFIX):] + if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value + return fieldName[len(utils.STATIC_VALUE_PREFIX):] } - return storedCdr.FieldAsString(&RSRField{Id: fieldName}) + return storedCdr.FieldAsString(&utils.RSRField{Id: fieldName}) } func (storedCdr *StoredCdr) GetCallDestNr(fieldName string) string { - if IsSliceMember([]string{DESTINATION, META_DEFAULT}, fieldName) { + if utils.IsSliceMember([]string{utils.DESTINATION, utils.META_DEFAULT}, fieldName) { return storedCdr.Destination } - if strings.HasPrefix(fieldName, STATIC_VALUE_PREFIX) { // Static value - return fieldName[len(STATIC_VALUE_PREFIX):] + if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value + return fieldName[len(utils.STATIC_VALUE_PREFIX):] } - return storedCdr.FieldAsString(&RSRField{Id: fieldName}) + return storedCdr.FieldAsString(&utils.RSRField{Id: fieldName}) } func (storedCdr *StoredCdr) GetCategory(fieldName string) string { - if IsSliceMember([]string{CATEGORY, META_DEFAULT}, fieldName) { + if utils.IsSliceMember([]string{utils.CATEGORY, utils.META_DEFAULT}, fieldName) { return storedCdr.Category } - if strings.HasPrefix(fieldName, STATIC_VALUE_PREFIX) { // Static value - return fieldName[len(STATIC_VALUE_PREFIX):] + if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value + return fieldName[len(utils.STATIC_VALUE_PREFIX):] } - return storedCdr.FieldAsString(&RSRField{Id: fieldName}) + return storedCdr.FieldAsString(&utils.RSRField{Id: fieldName}) } func (storedCdr *StoredCdr) GetTenant(fieldName string) string { - if IsSliceMember([]string{TENANT, META_DEFAULT}, fieldName) { + if utils.IsSliceMember([]string{utils.TENANT, utils.META_DEFAULT}, fieldName) { return storedCdr.Tenant } - if strings.HasPrefix(fieldName, STATIC_VALUE_PREFIX) { // Static value - return fieldName[len(STATIC_VALUE_PREFIX):] + if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value + return fieldName[len(utils.STATIC_VALUE_PREFIX):] } - return storedCdr.FieldAsString(&RSRField{Id: fieldName}) + return storedCdr.FieldAsString(&utils.RSRField{Id: fieldName}) } func (storedCdr *StoredCdr) GetReqType(fieldName string) string { - if IsSliceMember([]string{REQTYPE, META_DEFAULT}, fieldName) { + if utils.IsSliceMember([]string{utils.REQTYPE, utils.META_DEFAULT}, fieldName) { return storedCdr.ReqType } - if strings.HasPrefix(fieldName, STATIC_VALUE_PREFIX) { // Static value - return fieldName[len(STATIC_VALUE_PREFIX):] + if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value + return fieldName[len(utils.STATIC_VALUE_PREFIX):] } - return storedCdr.FieldAsString(&RSRField{Id: fieldName}) + return storedCdr.FieldAsString(&utils.RSRField{Id: fieldName}) } func (storedCdr *StoredCdr) GetSetupTime(fieldName string) (time.Time, error) { - if IsSliceMember([]string{SETUP_TIME, META_DEFAULT}, fieldName) { + if utils.IsSliceMember([]string{utils.SETUP_TIME, utils.META_DEFAULT}, fieldName) { return storedCdr.SetupTime, nil } var sTimeVal string - if strings.HasPrefix(fieldName, STATIC_VALUE_PREFIX) { // Static value - sTimeVal = fieldName[len(STATIC_VALUE_PREFIX):] + if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value + sTimeVal = fieldName[len(utils.STATIC_VALUE_PREFIX):] } else { - sTimeVal = storedCdr.FieldAsString(&RSRField{Id: fieldName}) + sTimeVal = storedCdr.FieldAsString(&utils.RSRField{Id: fieldName}) } - return ParseTimeDetectLayout(sTimeVal) + return utils.ParseTimeDetectLayout(sTimeVal) } func (storedCdr *StoredCdr) GetAnswerTime(fieldName string) (time.Time, error) { - if IsSliceMember([]string{ANSWER_TIME, META_DEFAULT}, fieldName) { + if utils.IsSliceMember([]string{utils.ANSWER_TIME, utils.META_DEFAULT}, fieldName) { return storedCdr.AnswerTime, nil } var aTimeVal string - if strings.HasPrefix(fieldName, STATIC_VALUE_PREFIX) { // Static value - aTimeVal = fieldName[len(STATIC_VALUE_PREFIX):] + if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value + aTimeVal = fieldName[len(utils.STATIC_VALUE_PREFIX):] } else { - aTimeVal = storedCdr.FieldAsString(&RSRField{Id: fieldName}) + aTimeVal = storedCdr.FieldAsString(&utils.RSRField{Id: fieldName}) } - return ParseTimeDetectLayout(aTimeVal) + return utils.ParseTimeDetectLayout(aTimeVal) } func (storedCdr *StoredCdr) GetEndTime() (time.Time, error) { return storedCdr.AnswerTime.Add(storedCdr.Usage), nil } func (storedCdr *StoredCdr) GetDuration(fieldName string) (time.Duration, error) { - if IsSliceMember([]string{USAGE, META_DEFAULT}, fieldName) { + if utils.IsSliceMember([]string{utils.USAGE, utils.META_DEFAULT}, fieldName) { return storedCdr.Usage, nil } var durVal string - if strings.HasPrefix(fieldName, STATIC_VALUE_PREFIX) { // Static value - durVal = fieldName[len(STATIC_VALUE_PREFIX):] + if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value + durVal = fieldName[len(utils.STATIC_VALUE_PREFIX):] } else { - durVal = storedCdr.FieldAsString(&RSRField{Id: fieldName}) + durVal = storedCdr.FieldAsString(&utils.RSRField{Id: fieldName}) } - return ParseDurationWithSecs(durVal) + return utils.ParseDurationWithSecs(durVal) } func (storedCdr *StoredCdr) GetOriginatorIP(fieldName string) string { - if IsSliceMember([]string{CDRHOST, META_DEFAULT}, fieldName) { + if utils.IsSliceMember([]string{utils.CDRHOST, utils.META_DEFAULT}, fieldName) { return storedCdr.CdrHost } - return storedCdr.FieldAsString(&RSRField{Id: fieldName}) + return storedCdr.FieldAsString(&utils.RSRField{Id: fieldName}) } func (storedCdr *StoredCdr) GetExtraFields() map[string]string { return storedCdr.ExtraFields @@ -474,7 +476,7 @@ func (storedCdr *StoredCdr) MissingParameter() bool { len(storedCdr.Account) == 0 || len(storedCdr.Destination) == 0 } -func (storedCdr *StoredCdr) ParseEventValue(rsrFld *RSRField) string { +func (storedCdr *StoredCdr) ParseEventValue(rsrFld *utils.RSRField) string { return storedCdr.FieldAsString(rsrFld) } func (storedCdr *StoredCdr) String() string { diff --git a/utils/utils_local_test.go b/engine/storedcdr_local_test.go similarity index 56% rename from utils/utils_local_test.go rename to engine/storedcdr_local_test.go index 7a0b28b79..67726af4e 100644 --- a/utils/utils_local_test.go +++ b/engine/storedcdr_local_test.go @@ -16,27 +16,33 @@ You should have received a copy of the GNU General Public License along with this program. If not, see */ -package utils +package engine import ( "flag" + "github.com/cgrates/cgrates/utils" "testing" "time" ) +// Arguments received via test command var testLocal = flag.Bool("local", false, "Perform the tests only on local test environment, not by default.") // This flag will be passed here via "go test -local" args +var dataDir = flag.String("data_dir", "/usr/share/cgrates", "CGR data dir path here") // Sample HttpJsonPost, more for usage purposes func TestHttpJsonPost(t *testing.T) { if !*testLocal { return } - cdrOut := &CgrExtCdr{CgrId: Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC).String()), OrderId: 123, TOR: VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", - CdrSource: UNIT_TEST, ReqType: META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "account1", Subject: "tgooiscs0014", Destination: "1002", - SetupTime: time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC).String(), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String(), MediationRunId: DEFAULT_RUNID, - Usage: "0.00000001", ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, + cdrOut := &CgrExtCdr{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", + CdrHost: "192.168.1.1", + CdrSource: utils.UNIT_TEST, ReqType: utils.META_RATED, Direction: "*out", Tenant: "cgrates.org", + Category: "call", Account: "account1", Subject: "tgooiscs0014", Destination: "1002", + SetupTime: time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC).String(), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String(), + MediationRunId: utils.DEFAULT_RUNID, + Usage: "0.00000001", ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, } - if _, err := HttpJsonPost("http://localhost:8000", false, cdrOut); err == nil || err.Error() != "Post http://localhost:8000: dial tcp 127.0.0.1:8000: connection refused" { + if _, err := utils.HttpJsonPost("http://localhost:8000", false, cdrOut); err == nil || err.Error() != "Post http://localhost:8000: dial tcp 127.0.0.1:8000: connection refused" { t.Error(err) } } diff --git a/engine/storedcdr_test.go b/engine/storedcdr_test.go new file mode 100644 index 000000000..b7967acb5 --- /dev/null +++ b/engine/storedcdr_test.go @@ -0,0 +1,478 @@ +/* +Real-time Charging System for Telecom & ISP environments +Copyright (C) 2012-2015 ITsysCOM GmbH + +This program is free software: you can Storagetribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITH*out ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +package engine + +import ( + "github.com/cgrates/cgrates/utils" + "reflect" + "testing" + "time" +) + +func TestStoredCdrInterfaces(t *testing.T) { + storedCdr := new(StoredCdr) + var _ RawCdr = storedCdr + var _ Event = storedCdr +} + +func TestFieldAsString(t *testing.T) { + cdr := StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", + CdrHost: "192.168.1.1", CdrSource: "test", ReqType: utils.META_RATED, Direction: "*out", Tenant: "cgrates.org", + Category: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), + AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), MediationRunId: utils.DEFAULT_RUNID, + Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, + Cost: 1.01, RatedAccount: "dan", RatedSubject: "dans", + } + if cdr.FieldAsString(&utils.RSRField{Id: utils.CGRID}) != cdr.CgrId || + cdr.FieldAsString(&utils.RSRField{Id: utils.ORDERID}) != "123" || + cdr.FieldAsString(&utils.RSRField{Id: utils.TOR}) != utils.VOICE || + cdr.FieldAsString(&utils.RSRField{Id: utils.ACCID}) != cdr.AccId || + cdr.FieldAsString(&utils.RSRField{Id: utils.CDRHOST}) != cdr.CdrHost || + cdr.FieldAsString(&utils.RSRField{Id: utils.CDRSOURCE}) != cdr.CdrSource || + cdr.FieldAsString(&utils.RSRField{Id: utils.REQTYPE}) != cdr.ReqType || + cdr.FieldAsString(&utils.RSRField{Id: utils.DIRECTION}) != cdr.Direction || + cdr.FieldAsString(&utils.RSRField{Id: utils.CATEGORY}) != cdr.Category || + cdr.FieldAsString(&utils.RSRField{Id: utils.ACCOUNT}) != cdr.Account || + cdr.FieldAsString(&utils.RSRField{Id: utils.SUBJECT}) != cdr.Subject || + cdr.FieldAsString(&utils.RSRField{Id: utils.DESTINATION}) != cdr.Destination || + cdr.FieldAsString(&utils.RSRField{Id: utils.SETUP_TIME}) != cdr.SetupTime.Format(time.RFC3339) || + cdr.FieldAsString(&utils.RSRField{Id: utils.ANSWER_TIME}) != cdr.AnswerTime.Format(time.RFC3339) || + cdr.FieldAsString(&utils.RSRField{Id: utils.USAGE}) != "10" || + cdr.FieldAsString(&utils.RSRField{Id: utils.MEDI_RUNID}) != cdr.MediationRunId || + cdr.FieldAsString(&utils.RSRField{Id: utils.COST}) != "1.01" || + cdr.FieldAsString(&utils.RSRField{Id: utils.RATED_ACCOUNT}) != "dan" || + cdr.FieldAsString(&utils.RSRField{Id: utils.RATED_SUBJECT}) != "dans" || + cdr.FieldAsString(&utils.RSRField{Id: "field_extr1"}) != cdr.ExtraFields["field_extr1"] || + cdr.FieldAsString(&utils.RSRField{Id: "fieldextr2"}) != cdr.ExtraFields["fieldextr2"] || + cdr.FieldAsString(&utils.RSRField{Id: "dummy_field"}) != "" { + t.Error("Unexpected filed value received", + cdr.FieldAsString(&utils.RSRField{Id: utils.CGRID}) != cdr.CgrId, + cdr.FieldAsString(&utils.RSRField{Id: utils.ORDERID}) != "123", + cdr.FieldAsString(&utils.RSRField{Id: utils.TOR}) != utils.VOICE, + cdr.FieldAsString(&utils.RSRField{Id: utils.ACCID}) != cdr.AccId, + cdr.FieldAsString(&utils.RSRField{Id: utils.CDRHOST}) != cdr.CdrHost, + cdr.FieldAsString(&utils.RSRField{Id: utils.CDRSOURCE}) != cdr.CdrSource, + cdr.FieldAsString(&utils.RSRField{Id: utils.REQTYPE}) != cdr.ReqType, + cdr.FieldAsString(&utils.RSRField{Id: utils.DIRECTION}) != cdr.Direction, + cdr.FieldAsString(&utils.RSRField{Id: utils.CATEGORY}) != cdr.Category, + cdr.FieldAsString(&utils.RSRField{Id: utils.ACCOUNT}) != cdr.Account, + cdr.FieldAsString(&utils.RSRField{Id: utils.SUBJECT}) != cdr.Subject, + cdr.FieldAsString(&utils.RSRField{Id: utils.DESTINATION}) != cdr.Destination, + cdr.FieldAsString(&utils.RSRField{Id: utils.SETUP_TIME}) != cdr.SetupTime.Format(time.RFC3339), + cdr.FieldAsString(&utils.RSRField{Id: utils.ANSWER_TIME}) != cdr.AnswerTime.Format(time.RFC3339), + cdr.FieldAsString(&utils.RSRField{Id: utils.USAGE}) != "10", + cdr.FieldAsString(&utils.RSRField{Id: utils.MEDI_RUNID}) != cdr.MediationRunId, + cdr.FieldAsString(&utils.RSRField{Id: utils.RATED_ACCOUNT}) != "dan", + cdr.FieldAsString(&utils.RSRField{Id: utils.RATED_SUBJECT}) != "dans", + cdr.FieldAsString(&utils.RSRField{Id: utils.COST}) != "1.01", + cdr.FieldAsString(&utils.RSRField{Id: "field_extr1"}) != cdr.ExtraFields["field_extr1"], + cdr.FieldAsString(&utils.RSRField{Id: "fieldextr2"}) != cdr.ExtraFields["fieldextr2"], + cdr.FieldAsString(&utils.RSRField{Id: "dummy_field"}) != "") + } +} + +func TestPassesFieldFilter(t *testing.T) { + cdr := &StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", + CdrHost: "192.168.1.1", CdrSource: "test", ReqType: utils.META_RATED, Direction: "*out", Tenant: "cgrates.org", + Category: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), + AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), MediationRunId: utils.DEFAULT_RUNID, + Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, + } + if pass, _ := cdr.PassesFieldFilter(nil); !pass { + t.Error("Not passing filter") + } + acntPrefxFltr, _ := utils.NewRSRField(`~account:s/(.+)/1001/`) + if pass, _ := cdr.PassesFieldFilter(acntPrefxFltr); !pass { + t.Error("Not passing filter") + } + acntPrefxFltr, _ = utils.NewRSRField(`~account:s/^(10)\d\d$/10/`) + if pass, _ := cdr.PassesFieldFilter(acntPrefxFltr); !pass { + t.Error("Not passing valid filter") + } + acntPrefxFltr, _ = utils.NewRSRField(`~account:s/^\d(10)\d$/10/`) + if pass, _ := cdr.PassesFieldFilter(acntPrefxFltr); pass { + t.Error("Passing filter") + } + acntPrefxFltr, _ = utils.NewRSRField(`~account:s/^(10)\d\d$/010/`) + if pass, _ := cdr.PassesFieldFilter(acntPrefxFltr); pass { + t.Error("Passing filter") + } + acntPrefxFltr, _ = utils.NewRSRField(`~account:s/^1010$/1010/`) + if pass, _ := cdr.PassesFieldFilter(acntPrefxFltr); pass { + t.Error("Passing filter") + } + torFltr, _ := utils.NewRSRField(`^tor::*voice/`) + if pass, _ := cdr.PassesFieldFilter(torFltr); !pass { + t.Error("Not passing filter") + } + torFltr, _ = utils.NewRSRField(`^tor/*data/`) + if pass, _ := cdr.PassesFieldFilter(torFltr); pass { + t.Error("Passing filter") + } + inexistentFieldFltr, _ := utils.NewRSRField(`^fakefield/fakevalue/`) + if pass, _ := cdr.PassesFieldFilter(inexistentFieldFltr); pass { + t.Error("Passing filter") + } +} + +func TestPassesFieldFilterDn1(t *testing.T) { + cdr := &StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), Account: "futurem0005", + ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, + } + acntPrefxFltr, _ := utils.NewRSRField(`~account:s/^\w+[shmp]\d{4}$//`) + if pass, _ := cdr.PassesFieldFilter(acntPrefxFltr); !pass { + t.Error("Not passing valid filter") + } + + cdr = &StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), Account: "futurem00005", + ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, + } + if pass, _ := cdr.PassesFieldFilter(acntPrefxFltr); pass { + t.Error("Should not pass filter") + } + cdr = &StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), Account: "0402129281", + ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, + } + acntPrefxFltr, _ = utils.NewRSRField(`~account:s/^0\d{9}$//`) + if pass, _ := cdr.PassesFieldFilter(acntPrefxFltr); !pass { + t.Error("Not passing valid filter") + } + acntPrefxFltr, _ = utils.NewRSRField(`~account:s/^0(\d{9})$/placeholder/`) + if pass, _ := cdr.PassesFieldFilter(acntPrefxFltr); pass { + t.Error("Should not pass filter") + } + cdr = &StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), Account: "04021292812", + ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, + } + if pass, _ := cdr.PassesFieldFilter(acntPrefxFltr); pass { + t.Error("Should not pass filter") + } + cdr = &StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), Account: "0162447222", + ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, + } + if acntPrefxFltr, err := utils.NewRSRField(`~account:s/^0\d{9}$//`); err != nil { + t.Error("Unexpected parse error", err) + } else if acntPrefxFltr == nil { + t.Error("Failed parsing rule") + } else if pass, _ := cdr.PassesFieldFilter(acntPrefxFltr); !pass { + t.Error("Not passing valid filter") + } + if acntPrefxFltr, err := utils.NewRSRField(`~account:s/^\w+[shmp]\d{4}$//`); err != nil { + t.Error("Unexpected parse error", err) + } else if acntPrefxFltr == nil { + t.Error("Failed parsing rule") + } else if pass, _ := cdr.PassesFieldFilter(acntPrefxFltr); pass { + t.Error("Should not pass filter") + } +} + +func TestUsageMultiply(t *testing.T) { + cdr := StoredCdr{Usage: time.Duration(10) * time.Second} + if cdr.UsageMultiply(1024.0, 0); cdr.Usage != time.Duration(10240)*time.Second { + t.Errorf("Unexpected usage after multiply: %v", cdr.Usage.Nanoseconds()) + } + cdr = StoredCdr{Usage: time.Duration(10240) * time.Second} // Simulate conversion back, gives out a bit odd result but this can be rounded on export + expectDuration, _ := time.ParseDuration("10.000005120s") + if cdr.UsageMultiply(0.000976563, 0); cdr.Usage != expectDuration { + t.Errorf("Unexpected usage after multiply: %v", cdr.Usage.Nanoseconds()) + } +} + +func TestCostMultiply(t *testing.T) { + cdr := StoredCdr{Cost: 1.01} + if cdr.CostMultiply(1.19, 4); cdr.Cost != 1.2019 { + t.Errorf("Unexpected cost after multiply: %v", cdr.Cost) + } + cdr = StoredCdr{Cost: 1.01} + if cdr.CostMultiply(1000, 0); cdr.Cost != 1010 { + t.Errorf("Unexpected cost after multiply: %v", cdr.Cost) + } +} + +func TestFormatCost(t *testing.T) { + cdr := StoredCdr{Cost: 1.01} + if cdr.FormatCost(0, 4) != "1.0100" { + t.Error("Unexpected format of the cost: ", cdr.FormatCost(0, 4)) + } + cdr = StoredCdr{Cost: 1.01001} + if cdr.FormatCost(0, 4) != "1.0100" { + t.Error("Unexpected format of the cost: ", cdr.FormatCost(0, 4)) + } + if cdr.FormatCost(2, 0) != "101" { + t.Error("Unexpected format of the cost: ", cdr.FormatCost(2, 0)) + } + if cdr.FormatCost(1, 0) != "10" { + t.Error("Unexpected format of the cost: ", cdr.FormatCost(1, 0)) + } + if cdr.FormatCost(2, 3) != "101.001" { + t.Error("Unexpected format of the cost: ", cdr.FormatCost(2, 3)) + } +} + +func TestFormatUsage(t *testing.T) { + cdr := StoredCdr{Usage: time.Duration(10) * time.Second} + if cdr.FormatUsage(utils.SECONDS) != "10" { + t.Error("Wrong usage format: ", cdr.FormatUsage(utils.SECONDS)) + } + if cdr.FormatUsage("default") != "10" { + t.Error("Wrong usage format: ", cdr.FormatUsage("default")) + } + cdr = StoredCdr{TOR: DATA, Usage: time.Duration(1640113000000000)} + if cdr.FormatUsage("default") != "1640113" { + t.Error("Wrong usage format: ", cdr.FormatUsage("default")) + } + cdr = StoredCdr{Usage: time.Duration(2) * time.Millisecond} + if cdr.FormatUsage("default") != "0.002" { + t.Error("Wrong usage format: ", cdr.FormatUsage("default")) + } + cdr = StoredCdr{Usage: time.Duration(1002) * time.Millisecond} + if cdr.FormatUsage("default") != "1.002" { + t.Error("Wrong usage format: ", cdr.FormatUsage("default")) + } +} + +func TestStoredCdrAsHttpForm(t *testing.T) { + storCdr := StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", + CdrHost: "192.168.1.1", CdrSource: utils.UNIT_TEST, ReqType: utils.META_RATED, Direction: "*out", + Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", + SetupTime: time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), MediationRunId: utils.DEFAULT_RUNID, + Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, RatedSubject: "dans", Cost: 1.01, + } + cdrForm := storCdr.AsHttpForm() + if cdrForm.Get(utils.TOR) != utils.VOICE { + t.Errorf("Expected: %s, received: %s", utils.VOICE, cdrForm.Get(utils.TOR)) + } + if cdrForm.Get(utils.ACCID) != "dsafdsaf" { + t.Errorf("Expected: %s, received: %s", "dsafdsaf", cdrForm.Get(utils.ACCID)) + } + if cdrForm.Get(utils.CDRHOST) != "192.168.1.1" { + t.Errorf("Expected: %s, received: %s", "192.168.1.1", cdrForm.Get(utils.CDRHOST)) + } + if cdrForm.Get(utils.CDRSOURCE) != utils.UNIT_TEST { + t.Errorf("Expected: %s, received: %s", utils.UNIT_TEST, cdrForm.Get(utils.CDRSOURCE)) + } + if cdrForm.Get(utils.REQTYPE) != utils.META_RATED { + t.Errorf("Expected: %s, received: %s", utils.META_RATED, cdrForm.Get(utils.REQTYPE)) + } + if cdrForm.Get(utils.DIRECTION) != "*out" { + t.Errorf("Expected: %s, received: %s", "*out", cdrForm.Get(utils.DIRECTION)) + } + if cdrForm.Get(utils.TENANT) != "cgrates.org" { + t.Errorf("Expected: %s, received: %s", "cgrates.org", cdrForm.Get(utils.TENANT)) + } + if cdrForm.Get(utils.CATEGORY) != "call" { + t.Errorf("Expected: %s, received: %s", "call", cdrForm.Get(utils.CATEGORY)) + } + if cdrForm.Get(utils.ACCOUNT) != "1001" { + t.Errorf("Expected: %s, received: %s", "1001", cdrForm.Get(utils.ACCOUNT)) + } + if cdrForm.Get(utils.SUBJECT) != "1001" { + t.Errorf("Expected: %s, received: %s", "1001", cdrForm.Get(utils.SUBJECT)) + } + if cdrForm.Get(utils.DESTINATION) != "1002" { + t.Errorf("Expected: %s, received: %s", "1002", cdrForm.Get(utils.DESTINATION)) + } + if cdrForm.Get(utils.SETUP_TIME) != "2013-11-07T08:42:20Z" { + t.Errorf("Expected: %s, received: %s", "2013-11-07T08:42:20Z", cdrForm.Get(utils.SETUP_TIME)) + } + if cdrForm.Get(utils.ANSWER_TIME) != "2013-11-07T08:42:26Z" { + t.Errorf("Expected: %s, received: %s", "2013-11-07T08:42:26Z", cdrForm.Get(utils.ANSWER_TIME)) + } + if cdrForm.Get(utils.USAGE) != "10" { + t.Errorf("Expected: %s, received: %s", "10", cdrForm.Get(utils.USAGE)) + } + if cdrForm.Get("field_extr1") != "val_extr1" { + t.Errorf("Expected: %s, received: %s", "val_extr1", cdrForm.Get("field_extr1")) + } + if cdrForm.Get("fieldextr2") != "valextr2" { + t.Errorf("Expected: %s, received: %s", "valextr2", cdrForm.Get("fieldextr2")) + } +} + +func TestStoredCdrForkCdr(t *testing.T) { + storCdr := StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, + AccId: "dsafdsaf", CdrHost: "192.168.1.1", CdrSource: utils.UNIT_TEST, ReqType: utils.META_RATED, Direction: "*out", + Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", + SetupTime: time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), MediationRunId: utils.DEFAULT_RUNID, + Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "field_extr2": "valextr2"}, Cost: 1.01, RatedSubject: "dans", + } + rtSampleCdrOut, err := storCdr.ForkCdr("sample_run1", &utils.RSRField{Id: utils.REQTYPE}, &utils.RSRField{Id: utils.DIRECTION}, &utils.RSRField{Id: utils.TENANT}, + &utils.RSRField{Id: utils.CATEGORY}, &utils.RSRField{Id: utils.ACCOUNT}, &utils.RSRField{Id: utils.SUBJECT}, &utils.RSRField{Id: utils.DESTINATION}, + &utils.RSRField{Id: utils.SETUP_TIME}, &utils.RSRField{Id: utils.ANSWER_TIME}, &utils.RSRField{Id: utils.USAGE}, + []*utils.RSRField{&utils.RSRField{Id: "field_extr1"}, &utils.RSRField{Id: "field_extr2"}}, true) + if err != nil { + t.Error("Unexpected error received", err) + } + expctSplRatedCdr := &StoredCdr{CgrId: storCdr.CgrId, TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", CdrSource: utils.UNIT_TEST, ReqType: utils.META_RATED, + Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", + SetupTime: time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), + Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "field_extr2": "valextr2"}, MediationRunId: "sample_run1", Cost: -1} + if !reflect.DeepEqual(expctSplRatedCdr, rtSampleCdrOut) { + t.Errorf("Expected: %v, received: %v", expctSplRatedCdr, rtSampleCdrOut) + } +} + +func TestStoredCdrForkCdrStaticVals(t *testing.T) { + storCdr := StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", + CdrHost: "192.168.1.1", CdrSource: utils.UNIT_TEST, ReqType: utils.META_RATED, Direction: "*out", + Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", + SetupTime: time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), MediationRunId: utils.DEFAULT_RUNID, + Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, + } + rsrStPostpaid, _ := utils.NewRSRField("^" + utils.META_POSTPAID) + rsrStIn, _ := utils.NewRSRField("^*in") + rsrStCgr, _ := utils.NewRSRField("^cgrates.com") + rsrStPC, _ := utils.NewRSRField("^premium_call") + rsrStFA, _ := utils.NewRSRField("^first_account") + rsrStFS, _ := utils.NewRSRField("^first_subject") + rsrStST, _ := utils.NewRSRField("^2013-12-07T08:42:24Z") + rsrStAT, _ := utils.NewRSRField("^2013-12-07T08:42:26Z") + rsrStDur, _ := utils.NewRSRField("^12s") + rtCdrOut2, err := storCdr.ForkCdr("wholesale_run", rsrStPostpaid, rsrStIn, rsrStCgr, rsrStPC, rsrStFA, rsrStFS, &utils.RSRField{Id: "destination"}, rsrStST, rsrStAT, rsrStDur, + []*utils.RSRField{}, true) + + if err != nil { + t.Error("Unexpected error received", err) + } + expctRatedCdr2 := &StoredCdr{CgrId: storCdr.CgrId, TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", CdrSource: utils.UNIT_TEST, ReqType: utils.META_POSTPAID, + Direction: "*in", Tenant: "cgrates.com", Category: "premium_call", Account: "first_account", Subject: "first_subject", Destination: "1002", + SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), + AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC), Usage: time.Duration(12) * time.Second, + ExtraFields: map[string]string{}, MediationRunId: "wholesale_run", Cost: -1} + if !reflect.DeepEqual(rtCdrOut2, expctRatedCdr2) { + t.Errorf("Received: %v, expected: %v", rtCdrOut2, expctRatedCdr2) + } + _, err = storCdr.ForkCdr("wholesale_run", &utils.RSRField{Id: "dummy_header"}, &utils.RSRField{Id: "direction"}, &utils.RSRField{Id: "tenant"}, &utils.RSRField{Id: "tor"}, &utils.RSRField{Id: "account"}, + &utils.RSRField{Id: "subject"}, &utils.RSRField{Id: "destination"}, &utils.RSRField{Id: "setup_time"}, &utils.RSRField{Id: "answer_time"}, &utils.RSRField{Id: "duration"}, + []*utils.RSRField{}, true) + if err == nil { + t.Error("Failed to detect missing header") + } +} + +func TestStoredCdrForkCdrFromMetaDefaults(t *testing.T) { + storCdr := StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", + CdrHost: "192.168.1.1", CdrSource: utils.UNIT_TEST, ReqType: utils.META_RATED, Direction: "*out", Tenant: "cgrates.org", + Category: "call", Account: "1001", Subject: "1001", Destination: "1002", + SetupTime: time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), MediationRunId: utils.DEFAULT_RUNID, + Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, + } + expctCdr := &StoredCdr{CgrId: storCdr.CgrId, TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", CdrSource: utils.UNIT_TEST, ReqType: utils.META_RATED, + Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", + SetupTime: time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), + Usage: time.Duration(10) * time.Second, + ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, MediationRunId: "wholesale_run", Cost: -1} + cdrOut, err := storCdr.ForkCdr("wholesale_run", &utils.RSRField{Id: utils.META_DEFAULT}, &utils.RSRField{Id: utils.META_DEFAULT}, &utils.RSRField{Id: utils.META_DEFAULT}, &utils.RSRField{Id: utils.META_DEFAULT}, + &utils.RSRField{Id: utils.META_DEFAULT}, &utils.RSRField{Id: utils.META_DEFAULT}, &utils.RSRField{Id: utils.META_DEFAULT}, + &utils.RSRField{Id: utils.META_DEFAULT}, &utils.RSRField{Id: utils.META_DEFAULT}, &utils.RSRField{Id: utils.META_DEFAULT}, []*utils.RSRField{&utils.RSRField{Id: "field_extr1"}, &utils.RSRField{Id: "fieldextr2"}}, true) + if err != nil { + t.Fatal("Unexpected error received", err) + } + + if !reflect.DeepEqual(expctCdr, cdrOut) { + t.Errorf("Expected: %v, received: %v", expctCdr, cdrOut) + } + // Should also accept nil as defaults + if cdrOut, err := storCdr.ForkCdr("wholesale_run", nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + []*utils.RSRField{&utils.RSRField{Id: "field_extr1"}, &utils.RSRField{Id: "fieldextr2"}}, true); err != nil { + t.Fatal("Unexpected error received", err) + } else if !reflect.DeepEqual(expctCdr, cdrOut) { + t.Errorf("Expected: %v, received: %v", expctCdr, cdrOut) + } +} + +func TestStoredCdrAsCgrExtCdr(t *testing.T) { + storCdr := StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, + AccId: "dsafdsaf", CdrHost: "192.168.1.1", CdrSource: utils.UNIT_TEST, ReqType: utils.META_RATED, Direction: "*out", + Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", + SetupTime: time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), MediationRunId: utils.DEFAULT_RUNID, + Usage: time.Duration(10), ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, RatedAccount: "dan", RatedSubject: "dans", + } + expectOutCdr := &CgrExtCdr{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, + AccId: "dsafdsaf", CdrHost: "192.168.1.1", CdrSource: utils.UNIT_TEST, ReqType: utils.META_RATED, Direction: "*out", + Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", + SetupTime: "2013-11-07T08:42:20Z", AnswerTime: "2013-11-07T08:42:26Z", MediationRunId: utils.DEFAULT_RUNID, + Usage: "0.00000001", ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, RatedAccount: "dan", RatedSubject: "dans", + } + if cdrOut := storCdr.AsCgrExtCdr(); !reflect.DeepEqual(expectOutCdr, cdrOut) { + t.Errorf("Expected: %+v, received: %+v", expectOutCdr, cdrOut) + } +} + +func TestStoredCdrEventFields(t *testing.T) { + cdr := &StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", + CdrHost: "192.168.1.1", CdrSource: "test", ReqType: utils.META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "dan", Subject: "dans", + Destination: "1002", SetupTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 27, 0, time.UTC), + MediationRunId: utils.DEFAULT_RUNID, Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, + Cost: 1.01, RatedAccount: "dan", RatedSubject: "dan"} + if ev := cdr.AsEvent(""); ev != Event(cdr) { + t.Error("Received: ", ev) + } + if res := cdr.GetName(); res != "test" { + t.Error("Received: ", res) + } + if res := cdr.GetCgrId(); res != utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()) { + t.Error("Received: ", res) + } + if res := cdr.GetUUID(); res != "dsafdsaf" { + t.Error("Received: ", res) + } + if res := cdr.GetDirection(utils.META_DEFAULT); res != "*out" { + t.Error("Received: ", res) + } + if res := cdr.GetSubject(utils.META_DEFAULT); res != "dans" { + t.Error("Received: ", res) + } + if res := cdr.GetAccount(utils.META_DEFAULT); res != "dan" { + t.Error("Received: ", res) + } + if res := cdr.GetDestination(utils.META_DEFAULT); res != "1002" { + t.Error("Received: ", res) + } + if res := cdr.GetCallDestNr(utils.META_DEFAULT); res != "1002" { + t.Error("Received: ", res) + } + if res := cdr.GetCategory(utils.META_DEFAULT); res != "call" { + t.Error("Received: ", res) + } + if res := cdr.GetTenant(utils.META_DEFAULT); res != "cgrates.org" { + t.Error("Received: ", res) + } + if res := cdr.GetReqType(utils.META_DEFAULT); res != utils.META_RATED { + t.Error("Received: ", res) + } + if st, _ := cdr.GetSetupTime(utils.META_DEFAULT); st != time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC) { + t.Error("Received: ", st) + } + if at, _ := cdr.GetAnswerTime(utils.META_DEFAULT); at != time.Date(2013, 11, 7, 8, 42, 27, 0, time.UTC) { + t.Error("Received: ", at) + } + if et, _ := cdr.GetEndTime(); et != time.Date(2013, 11, 7, 8, 42, 37, 0, time.UTC) { + t.Error("Received: ", et) + } + if dur, _ := cdr.GetDuration(utils.META_DEFAULT); dur != cdr.Usage { + t.Error("Received: ", dur) + } + if res := cdr.GetOriginatorIP(utils.META_DEFAULT); res != cdr.CdrHost { + t.Error("Received: ", res) + } + if extraFlds := cdr.GetExtraFields(); !reflect.DeepEqual(cdr.ExtraFields, extraFlds) { + t.Error("Received: ", extraFlds) + } +} diff --git a/general_tests/tutorial_fs_calls_test.go b/general_tests/tutorial_fs_calls_test.go index 120979b97..91c9dc5b3 100644 --- a/general_tests/tutorial_fs_calls_test.go +++ b/general_tests/tutorial_fs_calls_test.go @@ -163,7 +163,7 @@ func TestTutFsCallsCdrs1001(t *testing.T) { if !*testCalls { return } - var reply []*utils.CgrExtCdr + var reply []*engine.CgrExtCdr req := utils.RpcCdrsFilter{Accounts: []string{"1001"}, RunIds: []string{utils.META_DEFAULT}} if err := tutFsCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { t.Error("Unexpected error: ", err.Error()) diff --git a/local_test.sh b/local_test.sh index 97ad18201..b102597e5 100755 --- a/local_test.sh +++ b/local_test.sh @@ -18,8 +18,6 @@ echo 'go test github.com/cgrates/cgrates/config -local' go test github.com/cgrates/cgrates/config -local cfg=$? echo 'go test github.com/cgrates/cgrates/utils -local' -go test github.com/cgrates/cgrates/utils -local -utl=$? echo 'go test github.com/cgrates/cgrates/general_tests -local' go test github.com/cgrates/cgrates/general_tests -local gnr=$? @@ -29,5 +27,5 @@ gnr=$? -exit $gen && $ap1 && $ap2 && $en && $cdrc && $cfg && $utl && $gnr +exit $gen && $ap1 && $ap2 && $en && $cdrc && $cfg && $gnr diff --git a/sessionmanager/fsevent.go b/sessionmanager/fsevent.go index 8803831f8..47afd52f8 100644 --- a/sessionmanager/fsevent.go +++ b/sessionmanager/fsevent.go @@ -25,6 +25,7 @@ import ( "time" "github.com/cgrates/cgrates/config" + "github.com/cgrates/cgrates/engine" "github.com/cgrates/cgrates/utils" "github.com/cgrates/fsock" ) @@ -76,7 +77,7 @@ func (fsev FSEvent) String() (result string) { // Loads the new event data from a body of text containing the key value proprieties. // It stores the parsed proprieties in the internal map. -func (fsev FSEvent) AsEvent(body string) utils.Event { +func (fsev FSEvent) AsEvent(body string) engine.Event { fsev = fsock.FSEventStrToMap(body, nil) return fsev } @@ -292,8 +293,8 @@ func (fsev FSEvent) PassesFieldFilter(fieldFilter *utils.RSRField) (bool, string return false, "" } -func (fsev FSEvent) AsStoredCdr() *utils.StoredCdr { - storCdr := new(utils.StoredCdr) +func (fsev FSEvent) AsStoredCdr() *engine.StoredCdr { + storCdr := new(engine.StoredCdr) storCdr.CgrId = fsev.GetCgrId() storCdr.TOR = utils.VOICE storCdr.AccId = fsev.GetUUID() diff --git a/sessionmanager/fsevent_test.go b/sessionmanager/fsevent_test.go index 7c24c6547..91b848579 100644 --- a/sessionmanager/fsevent_test.go +++ b/sessionmanager/fsevent_test.go @@ -24,6 +24,7 @@ import ( "time" "github.com/cgrates/cgrates/config" + "github.com/cgrates/cgrates/engine" "github.com/cgrates/cgrates/utils" ) @@ -618,7 +619,7 @@ func TestFsEvAsStoredCdr(t *testing.T) { ev := new(FSEvent).AsEvent(hangupEv) setupTime, _ := utils.ParseTimeDetectLayout("1398442107") aTime, _ := utils.ParseTimeDetectLayout("1398442120") - eStoredCdr := &utils.StoredCdr{CgrId: utils.Sha1("37e9b766-5256-4e4b-b1ed-3767b930fec8", setupTime.UTC().String()), + eStoredCdr := &engine.StoredCdr{CgrId: utils.Sha1("37e9b766-5256-4e4b-b1ed-3767b930fec8", setupTime.UTC().String()), TOR: utils.VOICE, AccId: "37e9b766-5256-4e4b-b1ed-3767b930fec8", CdrHost: "10.0.2.15", CdrSource: "FS_CHANNEL_HANGUP_COMPLETE", ReqType: utils.META_PSEUDOPREPAID, Direction: utils.OUT, Tenant: "cgrates.org", Category: "call", Account: "1003", Subject: "1003", Destination: "1002", SetupTime: setupTime, AnswerTime: aTime, diff --git a/sessionmanager/fssessionmanager.go b/sessionmanager/fssessionmanager.go index 074440547..38e3252d5 100644 --- a/sessionmanager/fssessionmanager.go +++ b/sessionmanager/fssessionmanager.go @@ -101,7 +101,7 @@ func (sm *FSSessionManager) GetSession(uuid string) *Session { } // Disconnects a session by sending hangup command to freeswitch -func (sm *FSSessionManager) DisconnectSession(ev utils.Event, connId, notify string) { +func (sm *FSSessionManager) DisconnectSession(ev engine.Event, connId, notify string) { if _, err := sm.conns[connId].SendApiCmd(fmt.Sprintf("uuid_setvar %s cgr_notify %s\n\n", ev.GetUUID(), notify)); err != nil { engine.Logger.Err(fmt.Sprintf(" Could not send disconect api notification to freeswitch, error: <%s>, connId: %s", err.Error(), connId)) } @@ -156,7 +156,7 @@ func (sm *FSSessionManager) unparkCall(uuid, connId, call_dest_nb, notify string } } -func (sm *FSSessionManager) onChannelPark(ev utils.Event, connId string) { +func (sm *FSSessionManager) onChannelPark(ev engine.Event, connId string) { var maxCallDuration float64 // This will be the maximum duration this channel will be allowed to last if err := sm.rater.GetDerivedMaxSessionTime(*ev.AsStoredCdr(), &maxCallDuration); err != nil { engine.Logger.Err(fmt.Sprintf(" Could not get max session time for %s, error: %s", ev.GetUUID(), err.Error())) @@ -171,7 +171,7 @@ func (sm *FSSessionManager) onChannelPark(ev utils.Event, connId string) { sm.unparkCall(ev.GetUUID(), connId, ev.GetCallDestNr(utils.META_DEFAULT), AUTH_OK) } -func (sm *FSSessionManager) onChannelAnswer(ev utils.Event, connId string) { +func (sm *FSSessionManager) onChannelAnswer(ev engine.Event, connId string) { if ev.MissingParameter() { sm.DisconnectSession(ev, connId, MISSING_PARAMETER) } @@ -181,7 +181,7 @@ func (sm *FSSessionManager) onChannelAnswer(ev utils.Event, connId string) { } } -func (sm *FSSessionManager) onChannelHangupComplete(ev utils.Event) { +func (sm *FSSessionManager) onChannelHangupComplete(ev engine.Event) { go sm.ProcessCdr(ev.AsStoredCdr()) var s *Session for i := 0; i < 2; i++ { // Protect us against concurrency, wait a couple of seconds for the answer to be populated before we process hangup @@ -200,7 +200,7 @@ func (sm *FSSessionManager) onChannelHangupComplete(ev utils.Event) { } } -func (sm *FSSessionManager) ProcessCdr(storedCdr *utils.StoredCdr) error { +func (sm *FSSessionManager) ProcessCdr(storedCdr *engine.StoredCdr) error { if sm.cdrs != nil { var reply string if err := sm.cdrs.ProcessCdr(storedCdr, &reply); err != nil { diff --git a/sessionmanager/kamailiosm.go b/sessionmanager/kamailiosm.go index bf65e277d..f912b950a 100644 --- a/sessionmanager/kamailiosm.go +++ b/sessionmanager/kamailiosm.go @@ -125,7 +125,7 @@ func (self *KamailioSessionManager) Connect() error { return err } -func (self *KamailioSessionManager) DisconnectSession(ev utils.Event, connId, notify string) { +func (self *KamailioSessionManager) DisconnectSession(ev engine.Event, connId, notify string) { sessionIds := ev.GetSessionIds() disconnectEv := &KamSessionDisconnect{Event: CGR_SESSION_DISCONNECT, HashEntry: sessionIds[0], HashId: sessionIds[1], Reason: notify} if err := self.conns[connId].Send(disconnectEv.String()); err != nil { @@ -161,7 +161,7 @@ func (self *KamailioSessionManager) Rater() engine.Connector { return self.rater } -func (self *KamailioSessionManager) ProcessCdr(cdr *utils.StoredCdr) error { +func (self *KamailioSessionManager) ProcessCdr(cdr *engine.StoredCdr) error { if self.cdrsrv == nil { return nil } diff --git a/sessionmanager/kamevent.go b/sessionmanager/kamevent.go index 01a12be5e..c3f81fbd2 100644 --- a/sessionmanager/kamevent.go +++ b/sessionmanager/kamevent.go @@ -26,6 +26,7 @@ import ( "time" "github.com/cgrates/cgrates/config" + "github.com/cgrates/cgrates/engine" "github.com/cgrates/cgrates/utils" ) @@ -86,8 +87,8 @@ func NewKamEvent(kamEvData []byte) (KamEvent, error) { type KamEvent map[string]string // Backwards compatibility, should be AsEvent -func (kev KamEvent) AsEvent(ignored string) utils.Event { - return utils.Event(kev) +func (kev KamEvent) AsEvent(ignored string) engine.Event { + return engine.Event(kev) } func (kev KamEvent) GetName() string { @@ -263,8 +264,8 @@ func (kev KamEvent) PassesFieldFilter(*utils.RSRField) (bool, string) { return false, "" } -func (kev KamEvent) AsStoredCdr() *utils.StoredCdr { - storCdr := new(utils.StoredCdr) +func (kev KamEvent) AsStoredCdr() *engine.StoredCdr { + storCdr := new(engine.StoredCdr) storCdr.CgrId = kev.GetCgrId() storCdr.TOR = utils.VOICE storCdr.AccId = kev.GetUUID() diff --git a/sessionmanager/kamevent_test.go b/sessionmanager/kamevent_test.go index 48d693b5d..2a2835ce3 100644 --- a/sessionmanager/kamevent_test.go +++ b/sessionmanager/kamevent_test.go @@ -22,6 +22,7 @@ import ( "reflect" "testing" + "github.com/cgrates/cgrates/engine" "github.com/cgrates/cgrates/utils" ) @@ -30,7 +31,7 @@ var kamEv = KamEvent{KAM_TR_INDEX: "29223", KAM_TR_LABEL: "698469260", "callid": "cgr_duration": "20", "extra1": "val1", "extra2": "val2"} func TestKamailioEventInterface(t *testing.T) { - var _ utils.Event = utils.Event(kamEv) + var _ engine.Event = engine.Event(kamEv) } func TestNewKamEvent(t *testing.T) { diff --git a/sessionmanager/osipsevent.go b/sessionmanager/osipsevent.go index 6c61f2f0f..d9bb3f2b1 100644 --- a/sessionmanager/osipsevent.go +++ b/sessionmanager/osipsevent.go @@ -24,6 +24,7 @@ import ( "time" "github.com/cgrates/cgrates/config" + "github.com/cgrates/cgrates/engine" "github.com/cgrates/cgrates/utils" "github.com/cgrates/osipsdagram" ) @@ -58,7 +59,7 @@ type OsipsEvent struct { osipsEvent *osipsdagram.OsipsEvent } -func (osipsev *OsipsEvent) AsEvent(evStr string) utils.Event { +func (osipsev *OsipsEvent) AsEvent(evStr string) engine.Event { return osipsev } @@ -202,8 +203,8 @@ func (osipsev *OsipsEvent) GetExtraFields() map[string]string { return extraFields } -func (osipsEv *OsipsEvent) AsStoredCdr() *utils.StoredCdr { - storCdr := new(utils.StoredCdr) +func (osipsEv *OsipsEvent) AsStoredCdr() *engine.StoredCdr { + storCdr := new(engine.StoredCdr) storCdr.CgrId = osipsEv.GetCgrId() storCdr.TOR = utils.VOICE storCdr.AccId = osipsEv.GetUUID() diff --git a/sessionmanager/osipsevent_test.go b/sessionmanager/osipsevent_test.go index 72f068f3c..0b6b39733 100644 --- a/sessionmanager/osipsevent_test.go +++ b/sessionmanager/osipsevent_test.go @@ -25,6 +25,7 @@ import ( "time" "github.com/cgrates/cgrates/config" + "github.com/cgrates/cgrates/engine" "github.com/cgrates/cgrates/utils" "github.com/cgrates/osipsdagram" ) @@ -36,7 +37,7 @@ var osipsEv = &OsipsEvent{osipsEvent: &osipsdagram.OsipsEvent{Name: "E_ACC_CDR", "duration": "20", "from_tag": "eb082607", "extra1": "val1", "extra2": "val2"}, OriginatorAddress: addr}} func TestOsipsEventInterface(t *testing.T) { - var _ utils.Event = utils.Event(osipsEv) + var _ engine.Event = engine.Event(osipsEv) } func TestOsipsEventParseStatic(t *testing.T) { @@ -128,7 +129,7 @@ func TestOsipsEventMissingParameter(t *testing.T) { func TestOsipsEventAsStoredCdr(t *testing.T) { setupTime, _ := utils.ParseTimeDetectLayout("1406370492") answerTime, _ := utils.ParseTimeDetectLayout("1406370499") - eStoredCdr := &utils.StoredCdr{CgrId: utils.Sha1("ODVkMDI2Mzc2MDY5N2EzODhjNTAzNTdlODhiZjRlYWQ;eb082607;4ea9687f", setupTime.UTC().String()), + eStoredCdr := &engine.StoredCdr{CgrId: utils.Sha1("ODVkMDI2Mzc2MDY5N2EzODhjNTAzNTdlODhiZjRlYWQ;eb082607;4ea9687f", setupTime.UTC().String()), TOR: utils.VOICE, AccId: "ODVkMDI2Mzc2MDY5N2EzODhjNTAzNTdlODhiZjRlYWQ;eb082607;4ea9687f", CdrHost: "172.16.254.77", CdrSource: "OSIPS_E_ACC_CDR", ReqType: utils.META_PREPAID, Direction: utils.OUT, Tenant: "itsyscom.com", Category: "call", Account: "dan", Subject: "dan", Destination: "+4986517174963", SetupTime: setupTime, AnswerTime: answerTime, diff --git a/sessionmanager/osipssm.go b/sessionmanager/osipssm.go index e14f8495c..ef045dd53 100644 --- a/sessionmanager/osipssm.go +++ b/sessionmanager/osipssm.go @@ -70,7 +70,7 @@ func (osm *OsipsSessionManager) Connect() (err error) { return errors.New(" Stopped reading events") } -func (osm *OsipsSessionManager) DisconnectSession(ev utils.Event, cgrId, notify string) { +func (osm *OsipsSessionManager) DisconnectSession(ev engine.Event, cgrId, notify string) { return } func (osm *OsipsSessionManager) RemoveSession(uuid string) { @@ -154,7 +154,7 @@ func (osm *OsipsSessionManager) onCdr(cdrDagram *osipsdagram.OsipsEvent) { } -func (osm *OsipsSessionManager) ProcessCdr(storedCdr *utils.StoredCdr) error { +func (osm *OsipsSessionManager) ProcessCdr(storedCdr *engine.StoredCdr) error { var reply string return osm.cdrsrv.ProcessCdr(storedCdr, &reply) } diff --git a/sessionmanager/session.go b/sessionmanager/session.go index b9201e82e..6eba60805 100644 --- a/sessionmanager/session.go +++ b/sessionmanager/session.go @@ -24,14 +24,13 @@ import ( "time" "github.com/cgrates/cgrates/engine" - "github.com/cgrates/cgrates/utils" ) // Session type holding the call information fields, a session delegate for specific // actions and a channel to signal end of the debit loop. type Session struct { - eventStart utils.Event // Store the original event who started this session so we can use it's info later (eg: disconnect, cgrid) - stopDebit chan bool // Channel to communicate with debit loops when closing the session + eventStart engine.Event // Store the original event who started this session so we can use it's info later (eg: disconnect, cgrid) + stopDebit chan bool // Channel to communicate with debit loops when closing the session sessionManager SessionManager connId string // Reference towards connection id on the session manager side. warnMinDur time.Duration @@ -52,7 +51,7 @@ func (s *Session) SessionRuns() []*engine.SessionRun { } // Creates a new session and in case of prepaid starts the debit loop for each of the session runs individually -func NewSession(ev utils.Event, connId string, sm SessionManager) *Session { +func NewSession(ev engine.Event, connId string, sm SessionManager) *Session { s := &Session{eventStart: ev, stopDebit: make(chan bool), sessionManager: sm, @@ -108,7 +107,7 @@ func (s *Session) debitLoop(runIdx int) { } // Stops the debit loop -func (s *Session) Close(ev utils.Event) error { +func (s *Session) Close(ev engine.Event) error { close(s.stopDebit) // Close the channel so all the sessionRuns listening will be notified if _, err := ev.GetEndTime(); err != nil { engine.Logger.Err("Error parsing answer event stop time.") diff --git a/sessionmanager/sessionmanager.go b/sessionmanager/sessionmanager.go index 95f9d9462..7b82e4733 100644 --- a/sessionmanager/sessionmanager.go +++ b/sessionmanager/sessionmanager.go @@ -22,7 +22,6 @@ import ( "time" "github.com/cgrates/cgrates/engine" - "github.com/cgrates/cgrates/utils" ) type SessionManager interface { @@ -30,9 +29,9 @@ type SessionManager interface { Rater() engine.Connector DebitInterval() time.Duration Connect() error - DisconnectSession(utils.Event, string, string) + DisconnectSession(engine.Event, string, string) WarnSessionMinDuration(string, string) RemoveSession(string) - ProcessCdr(*utils.StoredCdr) error + ProcessCdr(*engine.StoredCdr) error Shutdown() error } diff --git a/utils/storedcdr_test.go b/utils/storedcdr_test.go deleted file mode 100644 index da99e021d..000000000 --- a/utils/storedcdr_test.go +++ /dev/null @@ -1,467 +0,0 @@ -/* -Real-time Charging System for Telecom & ISP environments -Copyright (C) 2012-2015 ITsysCOM GmbH - -This program is free software: you can Storagetribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITH*out ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see -*/ - -package utils - -import ( - "reflect" - "testing" - "time" -) - -func TestStoredCdrInterfaces(t *testing.T) { - storedCdr := new(StoredCdr) - var _ RawCdr = storedCdr - var _ Event = storedCdr -} - -func TestFieldAsString(t *testing.T) { - cdr := 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: "test", ReqType: META_RATED, Direction: "*out", Tenant: "cgrates.org", - Category: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), MediationRunId: DEFAULT_RUNID, - Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, RatedAccount: "dan", RatedSubject: "dans", - } - if cdr.FieldAsString(&RSRField{Id: CGRID}) != cdr.CgrId || - cdr.FieldAsString(&RSRField{Id: ORDERID}) != "123" || - cdr.FieldAsString(&RSRField{Id: TOR}) != VOICE || - cdr.FieldAsString(&RSRField{Id: ACCID}) != cdr.AccId || - cdr.FieldAsString(&RSRField{Id: CDRHOST}) != cdr.CdrHost || - cdr.FieldAsString(&RSRField{Id: CDRSOURCE}) != cdr.CdrSource || - cdr.FieldAsString(&RSRField{Id: REQTYPE}) != cdr.ReqType || - cdr.FieldAsString(&RSRField{Id: DIRECTION}) != cdr.Direction || - cdr.FieldAsString(&RSRField{Id: CATEGORY}) != cdr.Category || - cdr.FieldAsString(&RSRField{Id: ACCOUNT}) != cdr.Account || - cdr.FieldAsString(&RSRField{Id: SUBJECT}) != cdr.Subject || - cdr.FieldAsString(&RSRField{Id: DESTINATION}) != cdr.Destination || - cdr.FieldAsString(&RSRField{Id: SETUP_TIME}) != cdr.SetupTime.Format(time.RFC3339) || - cdr.FieldAsString(&RSRField{Id: ANSWER_TIME}) != cdr.AnswerTime.Format(time.RFC3339) || - cdr.FieldAsString(&RSRField{Id: USAGE}) != "10" || - cdr.FieldAsString(&RSRField{Id: MEDI_RUNID}) != cdr.MediationRunId || - cdr.FieldAsString(&RSRField{Id: COST}) != "1.01" || - cdr.FieldAsString(&RSRField{Id: RATED_ACCOUNT}) != "dan" || - cdr.FieldAsString(&RSRField{Id: RATED_SUBJECT}) != "dans" || - cdr.FieldAsString(&RSRField{Id: "field_extr1"}) != cdr.ExtraFields["field_extr1"] || - cdr.FieldAsString(&RSRField{Id: "fieldextr2"}) != cdr.ExtraFields["fieldextr2"] || - cdr.FieldAsString(&RSRField{Id: "dummy_field"}) != "" { - t.Error("Unexpected filed value received", - cdr.FieldAsString(&RSRField{Id: CGRID}) != cdr.CgrId, - cdr.FieldAsString(&RSRField{Id: ORDERID}) != "123", - cdr.FieldAsString(&RSRField{Id: TOR}) != VOICE, - cdr.FieldAsString(&RSRField{Id: ACCID}) != cdr.AccId, - cdr.FieldAsString(&RSRField{Id: CDRHOST}) != cdr.CdrHost, - cdr.FieldAsString(&RSRField{Id: CDRSOURCE}) != cdr.CdrSource, - cdr.FieldAsString(&RSRField{Id: REQTYPE}) != cdr.ReqType, - cdr.FieldAsString(&RSRField{Id: DIRECTION}) != cdr.Direction, - cdr.FieldAsString(&RSRField{Id: CATEGORY}) != cdr.Category, - cdr.FieldAsString(&RSRField{Id: ACCOUNT}) != cdr.Account, - cdr.FieldAsString(&RSRField{Id: SUBJECT}) != cdr.Subject, - cdr.FieldAsString(&RSRField{Id: DESTINATION}) != cdr.Destination, - cdr.FieldAsString(&RSRField{Id: SETUP_TIME}) != cdr.SetupTime.Format(time.RFC3339), - cdr.FieldAsString(&RSRField{Id: ANSWER_TIME}) != cdr.AnswerTime.Format(time.RFC3339), - cdr.FieldAsString(&RSRField{Id: USAGE}) != "10", - cdr.FieldAsString(&RSRField{Id: MEDI_RUNID}) != cdr.MediationRunId, - cdr.FieldAsString(&RSRField{Id: RATED_ACCOUNT}) != "dan", - cdr.FieldAsString(&RSRField{Id: RATED_SUBJECT}) != "dans", - cdr.FieldAsString(&RSRField{Id: COST}) != "1.01", - cdr.FieldAsString(&RSRField{Id: "field_extr1"}) != cdr.ExtraFields["field_extr1"], - cdr.FieldAsString(&RSRField{Id: "fieldextr2"}) != cdr.ExtraFields["fieldextr2"], - cdr.FieldAsString(&RSRField{Id: "dummy_field"}) != "") - } -} - -func TestPassesFieldFilter(t *testing.T) { - cdr := &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: "test", ReqType: META_RATED, Direction: "*out", Tenant: "cgrates.org", - Category: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), - AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), MediationRunId: DEFAULT_RUNID, - Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, - } - if pass, _ := cdr.PassesFieldFilter(nil); !pass { - t.Error("Not passing filter") - } - acntPrefxFltr, _ := NewRSRField(`~account:s/(.+)/1001/`) - if pass, _ := cdr.PassesFieldFilter(acntPrefxFltr); !pass { - t.Error("Not passing filter") - } - acntPrefxFltr, _ = NewRSRField(`~account:s/^(10)\d\d$/10/`) - if pass, _ := cdr.PassesFieldFilter(acntPrefxFltr); !pass { - t.Error("Not passing valid filter") - } - acntPrefxFltr, _ = NewRSRField(`~account:s/^\d(10)\d$/10/`) - if pass, _ := cdr.PassesFieldFilter(acntPrefxFltr); pass { - t.Error("Passing filter") - } - acntPrefxFltr, _ = NewRSRField(`~account:s/^(10)\d\d$/010/`) - if pass, _ := cdr.PassesFieldFilter(acntPrefxFltr); pass { - t.Error("Passing filter") - } - acntPrefxFltr, _ = NewRSRField(`~account:s/^1010$/1010/`) - if pass, _ := cdr.PassesFieldFilter(acntPrefxFltr); pass { - t.Error("Passing filter") - } - torFltr, _ := NewRSRField(`^tor::*voice/`) - if pass, _ := cdr.PassesFieldFilter(torFltr); !pass { - t.Error("Not passing filter") - } - torFltr, _ = NewRSRField(`^tor/*data/`) - if pass, _ := cdr.PassesFieldFilter(torFltr); pass { - t.Error("Passing filter") - } - inexistentFieldFltr, _ := NewRSRField(`^fakefield/fakevalue/`) - if pass, _ := cdr.PassesFieldFilter(inexistentFieldFltr); pass { - t.Error("Passing filter") - } -} - -func TestPassesFieldFilterDn1(t *testing.T) { - cdr := &StoredCdr{CgrId: Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), Account: "futurem0005", - ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, - } - acntPrefxFltr, _ := NewRSRField(`~account:s/^\w+[shmp]\d{4}$//`) - if pass, _ := cdr.PassesFieldFilter(acntPrefxFltr); !pass { - t.Error("Not passing valid filter") - } - - cdr = &StoredCdr{CgrId: Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), Account: "futurem00005", - ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, - } - if pass, _ := cdr.PassesFieldFilter(acntPrefxFltr); pass { - t.Error("Should not pass filter") - } - cdr = &StoredCdr{CgrId: Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), Account: "0402129281", - ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, - } - acntPrefxFltr, _ = NewRSRField(`~account:s/^0\d{9}$//`) - if pass, _ := cdr.PassesFieldFilter(acntPrefxFltr); !pass { - t.Error("Not passing valid filter") - } - acntPrefxFltr, _ = NewRSRField(`~account:s/^0(\d{9})$/placeholder/`) - if pass, _ := cdr.PassesFieldFilter(acntPrefxFltr); pass { - t.Error("Should not pass filter") - } - cdr = &StoredCdr{CgrId: Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), Account: "04021292812", - ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, - } - if pass, _ := cdr.PassesFieldFilter(acntPrefxFltr); pass { - t.Error("Should not pass filter") - } - cdr = &StoredCdr{CgrId: Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), Account: "0162447222", - ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, - } - if acntPrefxFltr, err := NewRSRField(`~account:s/^0\d{9}$//`); err != nil { - t.Error("Unexpected parse error", err) - } else if acntPrefxFltr == nil { - t.Error("Failed parsing rule") - } else if pass, _ := cdr.PassesFieldFilter(acntPrefxFltr); !pass { - t.Error("Not passing valid filter") - } - if acntPrefxFltr, err := NewRSRField(`~account:s/^\w+[shmp]\d{4}$//`); err != nil { - t.Error("Unexpected parse error", err) - } else if acntPrefxFltr == nil { - t.Error("Failed parsing rule") - } else if pass, _ := cdr.PassesFieldFilter(acntPrefxFltr); pass { - t.Error("Should not pass filter") - } -} - -func TestUsageMultiply(t *testing.T) { - cdr := StoredCdr{Usage: time.Duration(10) * time.Second} - if cdr.UsageMultiply(1024.0, 0); cdr.Usage != time.Duration(10240)*time.Second { - t.Errorf("Unexpected usage after multiply: %v", cdr.Usage.Nanoseconds()) - } - cdr = StoredCdr{Usage: time.Duration(10240) * time.Second} // Simulate conversion back, gives out a bit odd result but this can be rounded on export - expectDuration, _ := time.ParseDuration("10.000005120s") - if cdr.UsageMultiply(0.000976563, 0); cdr.Usage != expectDuration { - t.Errorf("Unexpected usage after multiply: %v", cdr.Usage.Nanoseconds()) - } -} - -func TestCostMultiply(t *testing.T) { - cdr := StoredCdr{Cost: 1.01} - if cdr.CostMultiply(1.19, 4); cdr.Cost != 1.2019 { - t.Errorf("Unexpected cost after multiply: %v", cdr.Cost) - } - cdr = StoredCdr{Cost: 1.01} - if cdr.CostMultiply(1000, 0); cdr.Cost != 1010 { - t.Errorf("Unexpected cost after multiply: %v", cdr.Cost) - } -} - -func TestFormatCost(t *testing.T) { - cdr := StoredCdr{Cost: 1.01} - if cdr.FormatCost(0, 4) != "1.0100" { - t.Error("Unexpected format of the cost: ", cdr.FormatCost(0, 4)) - } - cdr = StoredCdr{Cost: 1.01001} - if cdr.FormatCost(0, 4) != "1.0100" { - t.Error("Unexpected format of the cost: ", cdr.FormatCost(0, 4)) - } - if cdr.FormatCost(2, 0) != "101" { - t.Error("Unexpected format of the cost: ", cdr.FormatCost(2, 0)) - } - if cdr.FormatCost(1, 0) != "10" { - t.Error("Unexpected format of the cost: ", cdr.FormatCost(1, 0)) - } - if cdr.FormatCost(2, 3) != "101.001" { - t.Error("Unexpected format of the cost: ", cdr.FormatCost(2, 3)) - } -} - -func TestFormatUsage(t *testing.T) { - cdr := StoredCdr{Usage: time.Duration(10) * time.Second} - if cdr.FormatUsage(SECONDS) != "10" { - t.Error("Wrong usage format: ", cdr.FormatUsage(SECONDS)) - } - if cdr.FormatUsage("default") != "10" { - t.Error("Wrong usage format: ", cdr.FormatUsage("default")) - } - cdr = StoredCdr{TOR: DATA, Usage: time.Duration(1640113000000000)} - if cdr.FormatUsage("default") != "1640113" { - t.Error("Wrong usage format: ", cdr.FormatUsage("default")) - } - cdr = StoredCdr{Usage: time.Duration(2) * time.Millisecond} - if cdr.FormatUsage("default") != "0.002" { - t.Error("Wrong usage format: ", cdr.FormatUsage("default")) - } - cdr = StoredCdr{Usage: time.Duration(1002) * time.Millisecond} - if cdr.FormatUsage("default") != "1.002" { - t.Error("Wrong usage format: ", cdr.FormatUsage("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: META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", - SetupTime: time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), MediationRunId: DEFAULT_RUNID, - Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, RatedSubject: "dans", Cost: 1.01, - } - cdrForm := storCdr.AsHttpForm() - if cdrForm.Get(TOR) != VOICE { - t.Errorf("Expected: %s, received: %s", VOICE, cdrForm.Get(TOR)) - } - if cdrForm.Get(ACCID) != "dsafdsaf" { - t.Errorf("Expected: %s, received: %s", "dsafdsaf", cdrForm.Get(ACCID)) - } - if cdrForm.Get(CDRHOST) != "192.168.1.1" { - t.Errorf("Expected: %s, received: %s", "192.168.1.1", cdrForm.Get(CDRHOST)) - } - if cdrForm.Get(CDRSOURCE) != UNIT_TEST { - t.Errorf("Expected: %s, received: %s", UNIT_TEST, cdrForm.Get(CDRSOURCE)) - } - if cdrForm.Get(REQTYPE) != META_RATED { - t.Errorf("Expected: %s, received: %s", META_RATED, cdrForm.Get(REQTYPE)) - } - if cdrForm.Get(DIRECTION) != "*out" { - t.Errorf("Expected: %s, received: %s", "*out", cdrForm.Get(DIRECTION)) - } - if cdrForm.Get(TENANT) != "cgrates.org" { - t.Errorf("Expected: %s, received: %s", "cgrates.org", cdrForm.Get(TENANT)) - } - if cdrForm.Get(CATEGORY) != "call" { - t.Errorf("Expected: %s, received: %s", "call", cdrForm.Get(CATEGORY)) - } - if cdrForm.Get(ACCOUNT) != "1001" { - t.Errorf("Expected: %s, received: %s", "1001", cdrForm.Get(ACCOUNT)) - } - if cdrForm.Get(SUBJECT) != "1001" { - t.Errorf("Expected: %s, received: %s", "1001", cdrForm.Get(SUBJECT)) - } - if cdrForm.Get(DESTINATION) != "1002" { - t.Errorf("Expected: %s, received: %s", "1002", cdrForm.Get(DESTINATION)) - } - if cdrForm.Get(SETUP_TIME) != "2013-11-07T08:42:20Z" { - t.Errorf("Expected: %s, received: %s", "2013-11-07T08:42:20Z", cdrForm.Get(SETUP_TIME)) - } - if cdrForm.Get(ANSWER_TIME) != "2013-11-07T08:42:26Z" { - t.Errorf("Expected: %s, received: %s", "2013-11-07T08:42:26Z", cdrForm.Get(ANSWER_TIME)) - } - if cdrForm.Get(USAGE) != "10" { - t.Errorf("Expected: %s, received: %s", "10", cdrForm.Get(USAGE)) - } - if cdrForm.Get("field_extr1") != "val_extr1" { - t.Errorf("Expected: %s, received: %s", "val_extr1", cdrForm.Get("field_extr1")) - } - if cdrForm.Get("fieldextr2") != "valextr2" { - t.Errorf("Expected: %s, received: %s", "valextr2", cdrForm.Get("fieldextr2")) - } -} - -func TestStoredCdrForkCdr(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: META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", - SetupTime: time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), MediationRunId: DEFAULT_RUNID, - Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "field_extr2": "valextr2"}, Cost: 1.01, RatedSubject: "dans", - } - rtSampleCdrOut, err := storCdr.ForkCdr("sample_run1", &RSRField{Id: REQTYPE}, &RSRField{Id: DIRECTION}, &RSRField{Id: TENANT}, &RSRField{Id: CATEGORY}, - &RSRField{Id: ACCOUNT}, &RSRField{Id: SUBJECT}, &RSRField{Id: DESTINATION}, &RSRField{Id: SETUP_TIME}, &RSRField{Id: ANSWER_TIME}, &RSRField{Id: USAGE}, - []*RSRField{&RSRField{Id: "field_extr1"}, &RSRField{Id: "field_extr2"}}, true) - if err != nil { - t.Error("Unexpected error received", err) - } - expctSplRatedCdr := &StoredCdr{CgrId: storCdr.CgrId, TOR: VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", CdrSource: UNIT_TEST, ReqType: META_RATED, - Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", - SetupTime: time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), - Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "field_extr2": "valextr2"}, MediationRunId: "sample_run1", Cost: -1} - if !reflect.DeepEqual(expctSplRatedCdr, rtSampleCdrOut) { - t.Errorf("Expected: %v, received: %v", expctSplRatedCdr, rtSampleCdrOut) - } -} - -func TestStoredCdrForkCdrStaticVals(t *testing.T) { - storCdr := StoredCdr{CgrId: Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC).String()), OrderId: 123, TOR: VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", - CdrSource: UNIT_TEST, ReqType: META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", - SetupTime: time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), MediationRunId: DEFAULT_RUNID, - Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, - } - rsrStPostpaid, _ := NewRSRField("^" + META_POSTPAID) - rsrStIn, _ := NewRSRField("^*in") - rsrStCgr, _ := NewRSRField("^cgrates.com") - rsrStPC, _ := NewRSRField("^premium_call") - rsrStFA, _ := NewRSRField("^first_account") - rsrStFS, _ := NewRSRField("^first_subject") - rsrStST, _ := NewRSRField("^2013-12-07T08:42:24Z") - rsrStAT, _ := NewRSRField("^2013-12-07T08:42:26Z") - rsrStDur, _ := NewRSRField("^12s") - rtCdrOut2, err := storCdr.ForkCdr("wholesale_run", rsrStPostpaid, rsrStIn, rsrStCgr, rsrStPC, rsrStFA, rsrStFS, &RSRField{Id: "destination"}, rsrStST, rsrStAT, rsrStDur, - []*RSRField{}, true) - - if err != nil { - t.Error("Unexpected error received", err) - } - expctRatedCdr2 := &StoredCdr{CgrId: storCdr.CgrId, TOR: VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", CdrSource: UNIT_TEST, ReqType: META_POSTPAID, - Direction: "*in", Tenant: "cgrates.com", Category: "premium_call", Account: "first_account", Subject: "first_subject", Destination: "1002", - SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), - AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC), Usage: time.Duration(12) * time.Second, - ExtraFields: map[string]string{}, MediationRunId: "wholesale_run", Cost: -1} - if !reflect.DeepEqual(rtCdrOut2, expctRatedCdr2) { - t.Errorf("Received: %v, expected: %v", rtCdrOut2, expctRatedCdr2) - } - _, err = storCdr.ForkCdr("wholesale_run", &RSRField{Id: "dummy_header"}, &RSRField{Id: "direction"}, &RSRField{Id: "tenant"}, &RSRField{Id: "tor"}, &RSRField{Id: "account"}, - &RSRField{Id: "subject"}, &RSRField{Id: "destination"}, &RSRField{Id: "setup_time"}, &RSRField{Id: "answer_time"}, &RSRField{Id: "duration"}, - []*RSRField{}, true) - if err == nil { - t.Error("Failed to detect missing header") - } -} - -func TestStoredCdrForkCdrFromMetaDefaults(t *testing.T) { - storCdr := StoredCdr{CgrId: Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC).String()), OrderId: 123, TOR: VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", - CdrSource: UNIT_TEST, ReqType: META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", - SetupTime: time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), MediationRunId: DEFAULT_RUNID, - Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, - } - expctCdr := &StoredCdr{CgrId: storCdr.CgrId, TOR: VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", CdrSource: UNIT_TEST, ReqType: META_RATED, - Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", - SetupTime: time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), - Usage: time.Duration(10) * time.Second, - ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, MediationRunId: "wholesale_run", Cost: -1} - cdrOut, err := storCdr.ForkCdr("wholesale_run", &RSRField{Id: META_DEFAULT}, &RSRField{Id: META_DEFAULT}, &RSRField{Id: META_DEFAULT}, &RSRField{Id: META_DEFAULT}, - &RSRField{Id: META_DEFAULT}, &RSRField{Id: META_DEFAULT}, &RSRField{Id: META_DEFAULT}, - &RSRField{Id: META_DEFAULT}, &RSRField{Id: META_DEFAULT}, &RSRField{Id: META_DEFAULT}, []*RSRField{&RSRField{Id: "field_extr1"}, &RSRField{Id: "fieldextr2"}}, true) - if err != nil { - t.Fatal("Unexpected error received", err) - } - - if !reflect.DeepEqual(expctCdr, cdrOut) { - t.Errorf("Expected: %v, received: %v", expctCdr, cdrOut) - } - // Should also accept nil as defaults - if cdrOut, err := storCdr.ForkCdr("wholesale_run", nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - []*RSRField{&RSRField{Id: "field_extr1"}, &RSRField{Id: "fieldextr2"}}, true); err != nil { - t.Fatal("Unexpected error received", err) - } else if !reflect.DeepEqual(expctCdr, cdrOut) { - t.Errorf("Expected: %v, received: %v", expctCdr, cdrOut) - } -} - -func TestStoredCdrAsCgrExtCdr(t *testing.T) { - storCdr := StoredCdr{CgrId: Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC).String()), OrderId: 123, TOR: VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", - CdrSource: UNIT_TEST, ReqType: META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", - SetupTime: time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), MediationRunId: DEFAULT_RUNID, - Usage: time.Duration(10), ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, RatedAccount: "dan", RatedSubject: "dans", - } - expectOutCdr := &CgrExtCdr{CgrId: Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC).String()), OrderId: 123, TOR: VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", - CdrSource: UNIT_TEST, ReqType: META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", - SetupTime: "2013-11-07T08:42:20Z", AnswerTime: "2013-11-07T08:42:26Z", MediationRunId: DEFAULT_RUNID, - Usage: "0.00000001", ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, RatedAccount: "dan", RatedSubject: "dans", - } - if cdrOut := storCdr.AsCgrExtCdr(); !reflect.DeepEqual(expectOutCdr, cdrOut) { - t.Errorf("Expected: %+v, received: %+v", expectOutCdr, cdrOut) - } -} - -func TestStoredCdrEventFields(t *testing.T) { - cdr := &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: "test", ReqType: META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "dan", Subject: "dans", - Destination: "1002", SetupTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 27, 0, time.UTC), - MediationRunId: DEFAULT_RUNID, Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, - Cost: 1.01, RatedAccount: "dan", RatedSubject: "dan"} - if ev := cdr.AsEvent(""); ev != Event(cdr) { - t.Error("Received: ", ev) - } - if res := cdr.GetName(); res != "test" { - t.Error("Received: ", res) - } - if res := cdr.GetCgrId(); res != Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()) { - t.Error("Received: ", res) - } - if res := cdr.GetUUID(); res != "dsafdsaf" { - t.Error("Received: ", res) - } - if res := cdr.GetDirection(META_DEFAULT); res != "*out" { - t.Error("Received: ", res) - } - if res := cdr.GetSubject(META_DEFAULT); res != "dans" { - t.Error("Received: ", res) - } - if res := cdr.GetAccount(META_DEFAULT); res != "dan" { - t.Error("Received: ", res) - } - if res := cdr.GetDestination(META_DEFAULT); res != "1002" { - t.Error("Received: ", res) - } - if res := cdr.GetCallDestNr(META_DEFAULT); res != "1002" { - t.Error("Received: ", res) - } - if res := cdr.GetCategory(META_DEFAULT); res != "call" { - t.Error("Received: ", res) - } - if res := cdr.GetTenant(META_DEFAULT); res != "cgrates.org" { - t.Error("Received: ", res) - } - if res := cdr.GetReqType(META_DEFAULT); res != META_RATED { - t.Error("Received: ", res) - } - if st, _ := cdr.GetSetupTime(META_DEFAULT); st != time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC) { - t.Error("Received: ", st) - } - if at, _ := cdr.GetAnswerTime(META_DEFAULT); at != time.Date(2013, 11, 7, 8, 42, 27, 0, time.UTC) { - t.Error("Received: ", at) - } - if et, _ := cdr.GetEndTime(); et != time.Date(2013, 11, 7, 8, 42, 37, 0, time.UTC) { - t.Error("Received: ", et) - } - if dur, _ := cdr.GetDuration(META_DEFAULT); dur != cdr.Usage { - t.Error("Received: ", dur) - } - if res := cdr.GetOriginatorIP(META_DEFAULT); res != cdr.CdrHost { - t.Error("Received: ", res) - } - if extraFlds := cdr.GetExtraFields(); !reflect.DeepEqual(cdr.ExtraFields, extraFlds) { - t.Error("Received: ", extraFlds) - } -}