diff --git a/apier/v2/cdrs_it_test.go b/apier/v2/cdrs_it_test.go
index 59e423669..745a0f9f6 100644
--- a/apier/v2/cdrs_it_test.go
+++ b/apier/v2/cdrs_it_test.go
@@ -41,18 +41,12 @@ var sTestsCDRsIT = []func(t *testing.T){
testV2CDRsInitConfig,
testV2CDRsInitDataDb,
testV2CDRsInitCdrDb,
- testV2CDRsInjectUnratedCdr,
testV2CDRsStartEngine,
testV2CDRsRpcConn,
- testV2CDRsProcessCdrRated,
- testV2CDRsProcessCdrRaw,
- testV2CDRsGetCdrs,
- testV2CDRsCountCdrs,
- testV2CDRsProcessPrepaidCdr,
- testV2CDRsRateWithoutTP,
testV2CDRsLoadTariffPlanFromFolder,
- testV2CDRsRateWithTP,
- // ToDo: test engine shutdown
+ testV2CDRsProcessCDR,
+ testV2CDRsGetCdrs,
+ testV2CDRsKillEngine,
}
// Tests starting here
@@ -98,34 +92,6 @@ func testV2CDRsInitCdrDb(t *testing.T) {
}
}
-func testV2CDRsInjectUnratedCdr(t *testing.T) {
- var db engine.CdrStorage
- switch cdrsConfDIR {
- case "cdrsv2mysql":
- db, err = engine.NewMySQLStorage(cdrsCfg.StorDBHost, cdrsCfg.StorDBPort, cdrsCfg.StorDBName, cdrsCfg.StorDBUser, cdrsCfg.StorDBPass,
- cdrsCfg.StorDBMaxOpenConns, cdrsCfg.StorDBMaxIdleConns, cdrsCfg.StorDBConnMaxLifetime)
- case "cdrsv2psql":
- db, err = engine.NewPostgresStorage(cdrsCfg.StorDBHost, cdrsCfg.StorDBPort, cdrsCfg.StorDBName, cdrsCfg.StorDBUser, cdrsCfg.StorDBPass,
- cdrsCfg.StorDBMaxOpenConns, cdrsCfg.StorDBMaxIdleConns, cdrsCfg.StorDBConnMaxLifetime)
- case "cdrsv2mongo":
- db, err = engine.NewMongoStorage(cdrsCfg.StorDBHost, cdrsCfg.StorDBPort, cdrsCfg.StorDBName,
- cdrsCfg.StorDBUser, cdrsCfg.StorDBPass, utils.StorDB, cdrsCfg.StorDBCDRSIndexes, nil, 10)
- }
- if err != nil {
- t.Error("Error on opening database connection: ", err)
- return
- }
- strCdr1 := &engine.CDR{CGRID: utils.Sha1("bbb1", time.Date(2015, 11, 21, 10, 47, 24, 0, time.UTC).String()), RunID: utils.MetaRaw,
- ToR: utils.VOICE, OriginID: "bbb1", OriginHost: "192.168.1.1", Source: "TestV2CdrsMongoInjectUnratedCdr", RequestType: utils.META_RATED,
- Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002",
- SetupTime: time.Date(2015, 11, 21, 10, 47, 24, 0, time.UTC), AnswerTime: time.Date(2015, 11, 21, 10, 47, 26, 0, time.UTC),
- Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"},
- Cost: -1}
- if err := db.SetCDR(strCdr1, false); err != nil {
- t.Error(err.Error())
- }
-}
-
func testV2CDRsStartEngine(t *testing.T) {
if _, err := engine.StopStartEngine(cdrsCfgPath, *waitRater); err != nil {
t.Fatal(err)
@@ -140,178 +106,85 @@ func testV2CDRsRpcConn(t *testing.T) {
}
}
-func testV2CDRsProcessCdrRated(t *testing.T) {
- cdr := &engine.CDR{
- CGRID: utils.Sha1("dsafdsaf", time.Date(2015, 12, 13, 18, 15, 26, 0, time.UTC).String()), RunID: utils.DEFAULT_RUNID,
- OrderID: 123, ToR: utils.VOICE, OriginID: "dsafdsaf",
- OriginHost: "192.168.1.1", Source: "TestV2CdrsMongoProcessCdrRated", RequestType: utils.META_RATED, Tenant: "cgrates.org", Category: "call",
- Account: "1001", Subject: "1001", Destination: "1002",
- SetupTime: time.Date(2015, 12, 13, 18, 15, 26, 0, time.UTC), AnswerTime: time.Date(2015, 12, 13, 18, 15, 26, 0, time.UTC),
- Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"},
- Cost: 1.01, CostSource: "TestV2CdrsMongoProcessCdrRated", PreRated: true,
- }
- var reply string
- if err := cdrsRpc.Call("CdrsV2.ProcessCdr", cdr, &reply); err != nil {
- t.Error("Unexpected error: ", err.Error())
- } else if reply != utils.OK {
- t.Error("Unexpected reply received: ", reply)
- }
-}
-
-func testV2CDRsProcessCdrRaw(t *testing.T) {
- cdr := &engine.CDR{
- CGRID: utils.Sha1("abcdeftg", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderID: 123, RunID: utils.MetaRaw,
- ToR: utils.VOICE, OriginID: "abcdeftg",
- OriginHost: "192.168.1.1", Source: "TestV2CdrsMongoProcessCdrRaw", RequestType: utils.META_RATED, 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),
- Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"},
- }
- var reply string
- if err := cdrsRpc.Call("CdrsV2.ProcessCdr", cdr, &reply); err != nil {
- t.Error("Unexpected error: ", err.Error())
- } else if reply != utils.OK {
- t.Error("Unexpected reply received: ", reply)
- }
- time.Sleep(time.Duration(*waitRater) * time.Millisecond)
-}
-
-func testV2CDRsGetCdrs(t *testing.T) {
- var reply []*engine.ExternalCDR
- req := utils.RPCCDRsFilter{}
- if err := cdrsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil {
- t.Error("Unexpected error: ", err.Error())
- } else if len(reply) != 4 { // 1 injected, 1 rated, 1 *raw and it's pair in *default run
- t.Error("Unexpected number of CDRs returned: ", len(reply))
- }
- // CDRs with rating errors
- req = utils.RPCCDRsFilter{RunIDs: []string{utils.META_DEFAULT}, MinCost: utils.Float64Pointer(-1.0), MaxCost: utils.Float64Pointer(0.0)}
- if err := cdrsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil {
- t.Error("Unexpected error: ", err.Error())
- } else if len(reply) != 1 {
- t.Error("Unexpected number of CDRs returned: ", reply)
- }
- // CDRs Rated
- req = utils.RPCCDRsFilter{RunIDs: []string{utils.META_DEFAULT}}
- if err := cdrsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil {
- t.Error("Unexpected error: ", err.Error())
- } else if len(reply) != 2 {
- t.Error("Unexpected number of CDRs returned: ", reply)
- }
- // Raw CDRs
- req = utils.RPCCDRsFilter{RunIDs: []string{utils.MetaRaw}}
- if err := cdrsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil {
- t.Error("Unexpected error: ", err.Error())
- } else if len(reply) != 2 {
- t.Error("Unexpected number of CDRs returned: ", reply)
- }
- // Skip Errors
- req = utils.RPCCDRsFilter{RunIDs: []string{utils.META_DEFAULT}, MinCost: utils.Float64Pointer(0.0), MaxCost: utils.Float64Pointer(-1.0)}
- if err := cdrsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil {
- t.Error("Unexpected error: ", err.Error())
- } else if len(reply) != 1 {
- t.Error("Unexpected number of CDRs returned: ", reply)
- }
-}
-
-func testV2CDRsCountCdrs(t *testing.T) {
- var reply int64
- req := utils.AttrGetCdrs{}
- if err := cdrsRpc.Call("ApierV2.CountCdrs", req, &reply); err != nil {
- t.Error("Unexpected error: ", err.Error())
- } else if reply != 4 {
- t.Error("Unexpected number of CDRs returned: ", reply)
- }
-}
-
-// Make sure *prepaid does not block until finding previous costs
-func testV2CDRsProcessPrepaidCdr(t *testing.T) {
- var reply string
- cdrs := []*engine.CDR{
- &engine.CDR{CGRID: utils.Sha1("dsafdsaf2", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderID: 123, ToR: utils.VOICE, OriginID: "dsafdsaf",
- OriginHost: "192.168.1.1", Source: "TestV2CdrsMongoProcessPrepaidCdr1", RequestType: utils.META_PREPAID, 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), RunID: utils.DEFAULT_RUNID,
- Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, PreRated: true,
- },
- &engine.CDR{CGRID: utils.Sha1("abcdeftg2", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderID: 123, ToR: utils.VOICE, OriginID: "dsafdsaf",
- OriginHost: "192.168.1.1", Source: "TestV2CdrsMongoProcessPrepaidCdr2", RequestType: utils.META_PREPAID, 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), RunID: utils.DEFAULT_RUNID,
- Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01,
- },
- &engine.CDR{CGRID: utils.Sha1("aererfddf2", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderID: 123, ToR: utils.VOICE, OriginID: "dsafdsaf",
- OriginHost: "192.168.1.1", Source: "TestV2CdrsMongoProcessPrepaidCdr3", RequestType: utils.META_PREPAID, 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), RunID: utils.DEFAULT_RUNID,
- Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01,
- },
- }
- tStart := time.Now()
- for _, cdr := range cdrs {
- if err := cdrsRpc.Call("CdrsV2.ProcessCdr", cdr, &reply); err != nil {
- t.Error("Unexpected error: ", err.Error())
- } else if reply != utils.OK {
- t.Error("Unexpected reply received: ", reply)
- }
- }
- if processDur := time.Now().Sub(tStart); processDur > 1*time.Second {
- t.Error("Unexpected processing time", processDur)
- }
-}
-
-func testV2CDRsRateWithoutTP(t *testing.T) {
- rawCdrCGRID := utils.Sha1("bbb1", time.Date(2015, 11, 21, 10, 47, 24, 0, time.UTC).String())
- // Rate the injected CDR, should not rate it since we have no TP loaded
- attrs := utils.AttrRateCdrs{CgrIds: []string{rawCdrCGRID}}
- var reply string
- if err := cdrsRpc.Call("CdrsV2.RateCdrs", attrs, &reply); err != nil {
- t.Error("Unexpected error: ", err.Error())
- } else if reply != utils.OK {
- t.Error("Unexpected reply received: ", reply)
- }
- time.Sleep(time.Duration(*waitRater) * time.Millisecond)
- var cdrs []*engine.ExternalCDR
- req := utils.RPCCDRsFilter{CGRIDs: []string{rawCdrCGRID}, RunIDs: []string{utils.META_DEFAULT}}
- if err := cdrsRpc.Call("ApierV2.GetCdrs", req, &cdrs); err != nil {
- t.Error("Unexpected error: ", err.Error())
- } else if len(cdrs) != 1 { // Injected CDR did not have a charging run
- t.Error("Unexpected number of CDRs returned: ", len(cdrs))
- } else {
- if cdrs[0].Cost != -1 {
- t.Errorf("Unexpected CDR returned: %+v", cdrs[0])
- }
- }
-}
-
func testV2CDRsLoadTariffPlanFromFolder(t *testing.T) {
var loadInst utils.LoadInstance
- attrs := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "oldtutorial")}
- if err := cdrsRpc.Call("ApierV2.LoadTariffPlanFromFolder", attrs, &loadInst); err != nil {
+ if err := cdrsRpc.Call("ApierV2.LoadTariffPlanFromFolder",
+ &utils.AttrLoadTpFromFolder{FolderPath: path.Join(
+ *dataDir, "tariffplans", "testit")}, &loadInst); err != nil {
t.Error(err)
}
time.Sleep(time.Duration(*waitRater) * time.Millisecond) // Give time for scheduler to execute topups
}
-func testV2CDRsRateWithTP(t *testing.T) {
- rawCdrCGRID := utils.Sha1("bbb1", time.Date(2015, 11, 21, 10, 47, 24, 0, time.UTC).String())
- attrs := utils.AttrRateCdrs{CgrIds: []string{rawCdrCGRID}}
+func testV2CDRsProcessCDR(t *testing.T) {
+ cgrEv := &utils.CGREvent{
+ Tenant: "cgrates.org",
+ Event: map[string]interface{}{
+ utils.OriginID: "testV2CDRsProcessCDR1",
+ utils.OriginHost: "192.168.1.1",
+ utils.Source: "testV2CDRsProcessCDR",
+ utils.RequestType: utils.META_RATED,
+ utils.Category: "customers",
+ utils.Account: "testV2CDRsProcessCDR",
+ utils.Destination: "+4986517174963",
+ utils.AnswerTime: time.Date(2018, 8, 24, 16, 00, 26, 0, time.UTC),
+ utils.Usage: time.Duration(1) * time.Minute,
+ "field_extr1": "val_extr1",
+ "fieldextr2": "valextr2",
+ },
+ }
var reply string
- if err := cdrsRpc.Call("CdrsV2.RateCdrs", attrs, &reply); err != nil {
+ if err := cdrsRpc.Call(utils.CdrsV2ProcessCDR, cgrEv, &reply); err != nil {
t.Error("Unexpected error: ", err.Error())
} else if reply != utils.OK {
t.Error("Unexpected reply received: ", reply)
}
- time.Sleep(time.Duration(*waitRater) * time.Millisecond)
+ time.Sleep(time.Duration(2000) * time.Millisecond) // Give time for CDR to be rated
+}
+
+func testV2CDRsGetCdrs(t *testing.T) {
+ var cdrCnt int64
+ req := utils.AttrGetCdrs{}
+ if err := cdrsRpc.Call("ApierV2.CountCdrs", req, &cdrCnt); err != nil {
+ t.Error("Unexpected error: ", err.Error())
+ } else if cdrCnt != 3 {
+ t.Error("Unexpected number of CDRs returned: ", cdrCnt)
+ }
var cdrs []*engine.ExternalCDR
- req := utils.RPCCDRsFilter{CGRIDs: []string{rawCdrCGRID}, RunIDs: []string{utils.META_DEFAULT}}
- if err := cdrsRpc.Call("ApierV2.GetCdrs", req, &cdrs); err != nil {
+ args := utils.RPCCDRsFilter{RunIDs: []string{utils.MetaRaw}}
+ if err := cdrsRpc.Call("ApierV2.GetCdrs", args, &cdrs); err != nil {
t.Error("Unexpected error: ", err.Error())
} else if len(cdrs) != 1 {
t.Error("Unexpected number of CDRs returned: ", len(cdrs))
} else {
- if cdrs[0].Cost != 0.3 {
- t.Errorf("Unexpected CDR returned: %+v", cdrs[0])
+ if cdrs[0].Cost != -1.0 {
+ t.Errorf("Unexpected cost for CDR: %f", cdrs[0].Cost)
+ }
+ }
+ args = utils.RPCCDRsFilter{RunIDs: []string{"CustomerCharges"}}
+ if err := cdrsRpc.Call("ApierV2.GetCdrs", args, &cdrs); err != nil {
+ t.Error("Unexpected error: ", err.Error())
+ } else if len(cdrs) != 1 {
+ t.Error("Unexpected number of CDRs returned: ", len(cdrs))
+ } else {
+ if cdrs[0].Cost != 0.0198 {
+ t.Errorf("Unexpected cost for CDR: %f", cdrs[0].Cost)
+ }
+ }
+ args = utils.RPCCDRsFilter{RunIDs: []string{"SupplierCharges"}}
+ if err := cdrsRpc.Call("ApierV2.GetCdrs", args, &cdrs); err != nil {
+ t.Error("Unexpected error: ", err.Error())
+ } else if len(cdrs) != 1 {
+ t.Error("Unexpected number of CDRs returned: ", len(cdrs))
+ } else {
+ if cdrs[0].Cost != 0.0102 {
+ t.Errorf("Unexpected cost for CDR: %f", cdrs[0].Cost)
}
}
}
+
+func testV2CDRsKillEngine(t *testing.T) {
+ if err := engine.KillEngine(100); err != nil {
+ t.Error(err)
+ }
+}
diff --git a/apier/v2/cdrsold_it_test.go b/apier/v2/cdrsold_it_test.go
new file mode 100644
index 000000000..851a006cd
--- /dev/null
+++ b/apier/v2/cdrsold_it_test.go
@@ -0,0 +1,317 @@
+// +build integration
+
+/*
+Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments
+Copyright (C) ITsysCOM GmbH
+
+This program is free software: you can redistribute 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 WITHOUT 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 v2
+
+import (
+ "net/rpc"
+ "net/rpc/jsonrpc"
+ "path"
+ "testing"
+ "time"
+
+ "github.com/cgrates/cgrates/config"
+ "github.com/cgrates/cgrates/engine"
+ "github.com/cgrates/cgrates/utils"
+)
+
+var cdrsOldCfgPath string
+var cdrsOldCfg *config.CGRConfig
+var cdrsOldRpc *rpc.Client
+var cdrsOldConfDIR string // run the tests for specific configuration
+
+// subtests to be executed for each confDIR
+var sOldTestsCDRsIT = []func(t *testing.T){
+ testV2CDRsOldInitConfig,
+ testV2CDRsOldInitDataDb,
+ testV2CDRsOldInitCdrDb,
+ testV2CDRsOldInjectUnratedCdr,
+ testV2CDRsOldStartEngine,
+ testV2CDRsOldOldRpcConn,
+ testV2CDRsOldProcessCdrRated,
+ testV2CDRsOldProcessCdrRaw,
+ testV2CDRsOldGetCdrs,
+ testV2CDRsOldCountCdrs,
+ testV2CDRsOldProcessPrepaidCdr,
+ testV2CDRsOldRateWithoutTP,
+ testV2CDRsOldLoadTariffPlanFromFolder,
+ testV2CDRsOldRateWithTP,
+ // ToDo: test engine shutdown
+}
+
+// Tests starting here
+func TestCDRsOldITMySQL(t *testing.T) {
+ cdrsOldConfDIR = "cdrsv2mysql"
+ for _, stest := range sOldTestsCDRsIT {
+ t.Run(cdrsOldConfDIR, stest)
+ }
+}
+
+func TestCDRsOldITpg(t *testing.T) {
+ cdrsOldConfDIR = "cdrsv2psql"
+ for _, stest := range sOldTestsCDRsIT {
+ t.Run(cdrsOldConfDIR, stest)
+ }
+}
+
+func TestCDRsOldITMongo(t *testing.T) {
+ cdrsOldConfDIR = "cdrsv2mongo"
+ for _, stest := range sOldTestsCDRsIT {
+ t.Run(cdrsOldConfDIR, stest)
+ }
+}
+
+func testV2CDRsOldInitConfig(t *testing.T) {
+ var err error
+ cdrsOldCfgPath = path.Join(*dataDir, "conf", "samples", cdrsOldConfDIR)
+ if cdrsOldCfg, err = config.NewCGRConfigFromFolder(cdrsOldCfgPath); err != nil {
+ t.Fatal("Got config error: ", err.Error())
+ }
+}
+
+func testV2CDRsOldInitDataDb(t *testing.T) {
+ if err := engine.InitDataDb(cdrsOldCfg); err != nil {
+ t.Fatal(err)
+ }
+}
+
+// InitDb so we can rely on count
+func testV2CDRsOldInitCdrDb(t *testing.T) {
+ if err := engine.InitStorDb(cdrsOldCfg); err != nil {
+ t.Fatal(err)
+ }
+}
+
+func testV2CDRsOldInjectUnratedCdr(t *testing.T) {
+ var db engine.CdrStorage
+ switch cdrsOldConfDIR {
+ case "cdrsv2mysql":
+ db, err = engine.NewMySQLStorage(cdrsOldCfg.StorDBHost, cdrsOldCfg.StorDBPort, cdrsOldCfg.StorDBName, cdrsOldCfg.StorDBUser, cdrsOldCfg.StorDBPass,
+ cdrsOldCfg.StorDBMaxOpenConns, cdrsOldCfg.StorDBMaxIdleConns, cdrsOldCfg.StorDBConnMaxLifetime)
+ case "cdrsv2psql":
+ db, err = engine.NewPostgresStorage(cdrsOldCfg.StorDBHost, cdrsOldCfg.StorDBPort, cdrsOldCfg.StorDBName, cdrsOldCfg.StorDBUser, cdrsOldCfg.StorDBPass,
+ cdrsOldCfg.StorDBMaxOpenConns, cdrsOldCfg.StorDBMaxIdleConns, cdrsOldCfg.StorDBConnMaxLifetime)
+ case "cdrsv2mongo":
+ db, err = engine.NewMongoStorage(cdrsOldCfg.StorDBHost, cdrsOldCfg.StorDBPort, cdrsOldCfg.StorDBName,
+ cdrsOldCfg.StorDBUser, cdrsOldCfg.StorDBPass, utils.StorDB, cdrsOldCfg.StorDBCDRSIndexes, nil, 10)
+ }
+ if err != nil {
+ t.Error("Error on opening database connection: ", err)
+ return
+ }
+ strCdr1 := &engine.CDR{CGRID: utils.Sha1("bbb1", time.Date(2015, 11, 21, 10, 47, 24, 0, time.UTC).String()), RunID: utils.MetaRaw,
+ ToR: utils.VOICE, OriginID: "bbb1", OriginHost: "192.168.1.1", Source: "testV2CDRsOldMongoInjectUnratedCdr", RequestType: utils.META_RATED,
+ Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002",
+ SetupTime: time.Date(2015, 11, 21, 10, 47, 24, 0, time.UTC), AnswerTime: time.Date(2015, 11, 21, 10, 47, 26, 0, time.UTC),
+ Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"},
+ Cost: -1}
+ if err := db.SetCDR(strCdr1, false); err != nil {
+ t.Error(err.Error())
+ }
+}
+
+func testV2CDRsOldStartEngine(t *testing.T) {
+ if _, err := engine.StopStartEngine(cdrsOldCfgPath, *waitRater); err != nil {
+ t.Fatal(err)
+ }
+}
+
+// Connect rpc client to rater
+func testV2CDRsOldOldRpcConn(t *testing.T) {
+ cdrsOldRpc, err = jsonrpc.Dial("tcp", cdrsOldCfg.RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed
+ if err != nil {
+ t.Fatal("Could not connect to rater: ", err.Error())
+ }
+}
+
+func testV2CDRsOldProcessCdrRated(t *testing.T) {
+ cdr := &engine.CDR{
+ CGRID: utils.Sha1("dsafdsaf", time.Date(2015, 12, 13, 18, 15, 26, 0, time.UTC).String()), RunID: utils.DEFAULT_RUNID,
+ OrderID: 123, ToR: utils.VOICE, OriginID: "dsafdsaf",
+ OriginHost: "192.168.1.1", Source: "testV2CDRsOldMongoProcessCdrRated", RequestType: utils.META_RATED, Tenant: "cgrates.org", Category: "call",
+ Account: "1001", Subject: "1001", Destination: "1002",
+ SetupTime: time.Date(2015, 12, 13, 18, 15, 26, 0, time.UTC), AnswerTime: time.Date(2015, 12, 13, 18, 15, 26, 0, time.UTC),
+ Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"},
+ Cost: 1.01, CostSource: "testV2CDRsOldMongoProcessCdrRated", PreRated: true,
+ }
+ var reply string
+ if err := cdrsOldRpc.Call("CdrsV2.ProcessCdr", cdr, &reply); err != nil {
+ t.Error("Unexpected error: ", err.Error())
+ } else if reply != utils.OK {
+ t.Error("Unexpected reply received: ", reply)
+ }
+}
+
+func testV2CDRsOldProcessCdrRaw(t *testing.T) {
+ cdr := &engine.CDR{
+ CGRID: utils.Sha1("abcdeftg", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderID: 123, RunID: utils.MetaRaw,
+ ToR: utils.VOICE, OriginID: "abcdeftg",
+ OriginHost: "192.168.1.1", Source: "testV2CDRsOldMongoProcessCdrRaw", RequestType: utils.META_RATED, 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),
+ Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"},
+ }
+ var reply string
+ if err := cdrsOldRpc.Call("CdrsV2.ProcessCdr", cdr, &reply); err != nil {
+ t.Error("Unexpected error: ", err.Error())
+ } else if reply != utils.OK {
+ t.Error("Unexpected reply received: ", reply)
+ }
+ time.Sleep(time.Duration(*waitRater) * time.Millisecond)
+}
+
+func testV2CDRsOldGetCdrs(t *testing.T) {
+ var reply []*engine.ExternalCDR
+ req := utils.RPCCDRsFilter{}
+ if err := cdrsOldRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil {
+ t.Error("Unexpected error: ", err.Error())
+ } else if len(reply) != 4 { // 1 injected, 1 rated, 1 *raw and it's pair in *default run
+ t.Error("Unexpected number of CDRs returned: ", len(reply))
+ }
+ // CDRs with rating errors
+ req = utils.RPCCDRsFilter{RunIDs: []string{utils.META_DEFAULT}, MinCost: utils.Float64Pointer(-1.0), MaxCost: utils.Float64Pointer(0.0)}
+ if err := cdrsOldRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil {
+ t.Error("Unexpected error: ", err.Error())
+ } else if len(reply) != 1 {
+ t.Error("Unexpected number of CDRs returned: ", reply)
+ }
+ // CDRs Rated
+ req = utils.RPCCDRsFilter{RunIDs: []string{utils.META_DEFAULT}}
+ if err := cdrsOldRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil {
+ t.Error("Unexpected error: ", err.Error())
+ } else if len(reply) != 2 {
+ t.Error("Unexpected number of CDRs returned: ", reply)
+ }
+ // Raw CDRs
+ req = utils.RPCCDRsFilter{RunIDs: []string{utils.MetaRaw}}
+ if err := cdrsOldRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil {
+ t.Error("Unexpected error: ", err.Error())
+ } else if len(reply) != 2 {
+ t.Error("Unexpected number of CDRs returned: ", reply)
+ }
+ // Skip Errors
+ req = utils.RPCCDRsFilter{RunIDs: []string{utils.META_DEFAULT}, MinCost: utils.Float64Pointer(0.0), MaxCost: utils.Float64Pointer(-1.0)}
+ if err := cdrsOldRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil {
+ t.Error("Unexpected error: ", err.Error())
+ } else if len(reply) != 1 {
+ t.Error("Unexpected number of CDRs returned: ", reply)
+ }
+}
+
+func testV2CDRsOldCountCdrs(t *testing.T) {
+ var reply int64
+ req := utils.AttrGetCdrs{}
+ if err := cdrsOldRpc.Call("ApierV2.CountCdrs", req, &reply); err != nil {
+ t.Error("Unexpected error: ", err.Error())
+ } else if reply != 4 {
+ t.Error("Unexpected number of CDRs returned: ", reply)
+ }
+}
+
+// Make sure *prepaid does not block until finding previous costs
+func testV2CDRsOldProcessPrepaidCdr(t *testing.T) {
+ var reply string
+ cdrs := []*engine.CDR{
+ &engine.CDR{CGRID: utils.Sha1("dsafdsaf2", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderID: 123, ToR: utils.VOICE, OriginID: "dsafdsaf",
+ OriginHost: "192.168.1.1", Source: "testV2CDRsOldMongoProcessPrepaidCdr1", RequestType: utils.META_PREPAID, 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), RunID: utils.DEFAULT_RUNID,
+ Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, PreRated: true,
+ },
+ &engine.CDR{CGRID: utils.Sha1("abcdeftg2", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderID: 123, ToR: utils.VOICE, OriginID: "dsafdsaf",
+ OriginHost: "192.168.1.1", Source: "testV2CDRsOldMongoProcessPrepaidCdr2", RequestType: utils.META_PREPAID, 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), RunID: utils.DEFAULT_RUNID,
+ Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01,
+ },
+ &engine.CDR{CGRID: utils.Sha1("aererfddf2", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderID: 123, ToR: utils.VOICE, OriginID: "dsafdsaf",
+ OriginHost: "192.168.1.1", Source: "testV2CDRsOldMongoProcessPrepaidCdr3", RequestType: utils.META_PREPAID, 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), RunID: utils.DEFAULT_RUNID,
+ Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01,
+ },
+ }
+ tStart := time.Now()
+ for _, cdr := range cdrs {
+ if err := cdrsOldRpc.Call("CdrsV2.ProcessCdr", cdr, &reply); err != nil {
+ t.Error("Unexpected error: ", err.Error())
+ } else if reply != utils.OK {
+ t.Error("Unexpected reply received: ", reply)
+ }
+ }
+ if processDur := time.Now().Sub(tStart); processDur > 1*time.Second {
+ t.Error("Unexpected processing time", processDur)
+ }
+}
+
+func testV2CDRsOldRateWithoutTP(t *testing.T) {
+ rawCdrCGRID := utils.Sha1("bbb1", time.Date(2015, 11, 21, 10, 47, 24, 0, time.UTC).String())
+ // Rate the injected CDR, should not rate it since we have no TP loaded
+ attrs := utils.AttrRateCdrs{CgrIds: []string{rawCdrCGRID}}
+ var reply string
+ if err := cdrsOldRpc.Call("CdrsV2.RateCdrs", attrs, &reply); err != nil {
+ t.Error("Unexpected error: ", err.Error())
+ } else if reply != utils.OK {
+ t.Error("Unexpected reply received: ", reply)
+ }
+ time.Sleep(time.Duration(*waitRater) * time.Millisecond)
+ var cdrs []*engine.ExternalCDR
+ req := utils.RPCCDRsFilter{CGRIDs: []string{rawCdrCGRID}, RunIDs: []string{utils.META_DEFAULT}}
+ if err := cdrsOldRpc.Call("ApierV2.GetCdrs", req, &cdrs); err != nil {
+ t.Error("Unexpected error: ", err.Error())
+ } else if len(cdrs) != 1 { // Injected CDR did not have a charging run
+ t.Error("Unexpected number of CDRs returned: ", len(cdrs))
+ } else {
+ if cdrs[0].Cost != -1 {
+ t.Errorf("Unexpected CDR returned: %+v", cdrs[0])
+ }
+ }
+}
+
+func testV2CDRsOldLoadTariffPlanFromFolder(t *testing.T) {
+ var loadInst utils.LoadInstance
+ attrs := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "oldtutorial")}
+ if err := cdrsOldRpc.Call("ApierV2.LoadTariffPlanFromFolder", attrs, &loadInst); err != nil {
+ t.Error(err)
+ }
+ time.Sleep(time.Duration(*waitRater) * time.Millisecond) // Give time for scheduler to execute topups
+}
+
+func testV2CDRsOldRateWithTP(t *testing.T) {
+ rawCdrCGRID := utils.Sha1("bbb1", time.Date(2015, 11, 21, 10, 47, 24, 0, time.UTC).String())
+ attrs := utils.AttrRateCdrs{CgrIds: []string{rawCdrCGRID}}
+ var reply string
+ if err := cdrsOldRpc.Call("CdrsV2.RateCdrs", attrs, &reply); err != nil {
+ t.Error("Unexpected error: ", err.Error())
+ } else if reply != utils.OK {
+ t.Error("Unexpected reply received: ", reply)
+ }
+ time.Sleep(time.Duration(*waitRater) * time.Millisecond)
+ var cdrs []*engine.ExternalCDR
+ req := utils.RPCCDRsFilter{CGRIDs: []string{rawCdrCGRID}, RunIDs: []string{utils.META_DEFAULT}}
+ if err := cdrsOldRpc.Call("ApierV2.GetCdrs", req, &cdrs); err != nil {
+ t.Error("Unexpected error: ", err.Error())
+ } else if len(cdrs) != 1 {
+ t.Error("Unexpected number of CDRs returned: ", len(cdrs))
+ } else {
+ if cdrs[0].Cost != 0.3 {
+ t.Errorf("Unexpected CDR returned: %+v", cdrs[0])
+ }
+ }
+}
diff --git a/cdrc/csv.go b/cdrc/csv.go
index 748f4a7de..8cb4f55cc 100644
--- a/cdrc/csv.go
+++ b/cdrc/csv.go
@@ -102,7 +102,6 @@ func (self *CsvRecordsProcessor) processFlatstoreRecord(record []string) ([]stri
// Takes the record from a slice and turns it into StoredCdrs, posting them to the cdrServer
func (self *CsvRecordsProcessor) processRecord(record []string) ([]*engine.CDR, error) {
- utils.Logger.Debug(fmt.Sprintf("Record from CSV : %+v \n", record))
recordCdrs := make([]*engine.CDR, 0) // More CDRs based on the number of filters and field templates
for _, cdrcCfg := range self.cdrcCfgs { // cdrFields coming from more templates will produce individual storCdr records
// Make sure filters are matching
diff --git a/config/config_test.go b/config/config_test.go
index 76cd395cd..c0f4c985d 100755
--- a/config/config_test.go
+++ b/config/config_test.go
@@ -534,6 +534,37 @@ func TestCgrCfgJSONDefaultsCDRS(t *testing.T) {
}
}
+func TestCgrCfgJSONLoadCDRS(t *testing.T) {
+ JSN_RAW_CFG := `
+{
+"cdrs": {
+ "enabled": true,
+ "chargers_conns": [
+ {"address": "*internal"}
+ ],
+ "rals_conns": [
+ {"address": "*internal"} // address where to reach the Rater for cost calculation, empty to disable functionality: <""|*internal|x.y.z.y:1234>
+ ],
+},
+}
+ `
+ cgrCfg, err := NewCGRConfigFromJsonStringWithDefaults(JSN_RAW_CFG)
+ if err != nil {
+ t.Error(err)
+ }
+ if !cgrCfg.CDRSEnabled {
+ t.Error(cgrCfg.CDRSEnabled)
+ }
+ if !reflect.DeepEqual(cgrCfg.CDRSChargerSConns,
+ []*HaPoolConfig{&HaPoolConfig{Address: utils.MetaInternal}}) {
+ t.Error(cgrCfg.CDRSChargerSConns)
+ }
+ if !reflect.DeepEqual(cgrCfg.CDRSRaterConns,
+ []*HaPoolConfig{&HaPoolConfig{Address: utils.MetaInternal}}) {
+ t.Error(cgrCfg.CDRSRaterConns)
+ }
+}
+
func TestCgrCfgJSONDefaultsCDRStats(t *testing.T) {
if cgrCfg.CDRStatsEnabled != false {
t.Error(cgrCfg.CDRStatsEnabled)
diff --git a/data/conf/samples/cdrsv2mysql/cdrsv2mysql.json b/data/conf/samples/cdrsv2mysql/cdrsv2mysql.json
index 55c24bcbd..48491fdd9 100644
--- a/data/conf/samples/cdrsv2mysql/cdrsv2mysql.json
+++ b/data/conf/samples/cdrsv2mysql/cdrsv2mysql.json
@@ -9,19 +9,33 @@
},
-"stor_db": { // database used to store offline tariff plans and CDRs
- "db_password": "CGRateS.org", // password to use when connecting to stordb
+"stor_db": {
+ "db_password": "CGRateS.org",
},
"rals": {
- "enabled": true, // enable Rater service:
+ "enabled": true,
},
"cdrs": {
- "enabled": true, // start the CDR Server service:
+ "enabled": true,
+ "chargers_conns":[
+ {"address": "127.0.0.1:2012", "transport":"*json"},
+ ],
"rals_conns": [
- {"address": "*internal"} // address where to reach the Rater for cost calculation, empty to disable functionality: <""|*internal|x.y.z.y:1234>
+ {"address": "*internal"}
+ ],
+},
+
+"attributes": {
+ "enabled": true,
+},
+
+"chargers": {
+ "enabled": true,
+ "attributes_conns": [
+ {"address": "127.0.0.1:2012", "transport":"*json"},
],
},
diff --git a/data/conf/samples/tutmysql/cgrates.json b/data/conf/samples/tutmysql/cgrates.json
index 8273f91a3..96ba17479 100644
--- a/data/conf/samples/tutmysql/cgrates.json
+++ b/data/conf/samples/tutmysql/cgrates.json
@@ -74,6 +74,9 @@
"cdrs": {
"enabled": true,
+ "chargers_conns":[
+ {"address": "127.0.0.1:2012", "transport":"*json"},
+ ],
},
@@ -226,7 +229,7 @@
"chargers": {
"enabled": true,
"attributes_conns": [
- {"address": "*internal"}
+ {"address": "127.0.0.1:2012", "transport":"*json"},
],
},
diff --git a/data/tariffplans/testit/Attributes.csv b/data/tariffplans/testit/Attributes.csv
index 4070be620..21db47b7a 100644
--- a/data/tariffplans/testit/Attributes.csv
+++ b/data/tariffplans/testit/Attributes.csv
@@ -1,2 +1,4 @@
#Tenant,ID,Context,FilterIDs,ActivationInterval,FieldName,Initial,Substitute,Append,Blocker,Weight
cgrates.org,ATTR_ACNT_1001,*sessions,FLTR_ACCOUNT_1001,,OfficeGroup,*any,Marketing,true,false,10
+cgrates.org,ATTR_SUPPLIER1,*chargers,*string:Category:customers,,Subject,*any,supplier1,false,false,10
+cgrates.org,ATTR_SUPPLIER1,,,,Category,*any,call,false,false,10
diff --git a/data/tariffplans/testit/Chargers.csv b/data/tariffplans/testit/Chargers.csv
new file mode 100644
index 000000000..c8fb8e16c
--- /dev/null
+++ b/data/tariffplans/testit/Chargers.csv
@@ -0,0 +1,3 @@
+#Tenant,ID,FilterIDs,ActivationInterval,RunID,AttributeIDs,Weight
+cgrates.org,CustomerCharges,,,CustomerCharges,,20
+cgrates.org,SupplierCharges,,,SupplierCharges,ATTR_SUPPLIER1,10
\ No newline at end of file
diff --git a/data/tariffplans/testit/DestinationRates.csv b/data/tariffplans/testit/DestinationRates.csv
index 397bbdc3a..aa5d84c08 100644
--- a/data/tariffplans/testit/DestinationRates.csv
+++ b/data/tariffplans/testit/DestinationRates.csv
@@ -1,4 +1,5 @@
#Id,DestinationId,RatesTag,RoundingMethod,RoundingDecimals,MaxCost,MaxCostStrategy
DR_ANY_1CNT,*any,RT_1CNT,*up,5,0,
+DR_ANY_2CNT,*any,RT_2CNT,*up,5,0,
DR_SPECIAL_1002,DST_1002,RT_1CNT,*up,4,0,
DR_FS_40CNT,DST_FS,RT_40CNT,*up,4,0,
\ No newline at end of file
diff --git a/data/tariffplans/testit/Rates.csv b/data/tariffplans/testit/Rates.csv
index 318fe8358..e55963098 100644
--- a/data/tariffplans/testit/Rates.csv
+++ b/data/tariffplans/testit/Rates.csv
@@ -1,4 +1,5 @@
#Id,ConnectFee,Rate,RateUnit,RateIncrement,GroupIntervalStart
RT_1CNT,0,0.01,60s,1s,0s
+RT_2CNT,0,0.02,60s,1s,0s
RT_40CNT,0.8,0.4,60s,30s,0s
RT_40CNT,0,0.2,60s,10s,60s
diff --git a/data/tariffplans/testit/RatingPlans.csv b/data/tariffplans/testit/RatingPlans.csv
index 46ef7883d..cf5c4be97 100644
--- a/data/tariffplans/testit/RatingPlans.csv
+++ b/data/tariffplans/testit/RatingPlans.csv
@@ -1,4 +1,6 @@
#Id,DestinationRatesId,TimingTag,Weight
RP_TESTIT1,DR_ANY_1CNT,*any,10
RP_SPECIAL_1002,DR_SPECIAL_1002,*any,10
-RP_RETAIL1,DR_FS_40CNT,*any,10
\ No newline at end of file
+RP_RETAIL1,DR_FS_40CNT,*any,10
+RP_ANY2CNT,DR_ANY_2CNT,*any,10
+RP_ANY1CNT,DR_ANY_1CNT,*any,10
\ No newline at end of file
diff --git a/data/tariffplans/testit/RatingProfiles.csv b/data/tariffplans/testit/RatingProfiles.csv
index 55e587416..102f97f27 100644
--- a/data/tariffplans/testit/RatingProfiles.csv
+++ b/data/tariffplans/testit/RatingProfiles.csv
@@ -1,3 +1,6 @@
#Direction,Tenant,Category,Subject,ActivationTime,RatingPlanId,RatesFallbackSubject,CdrStatQueueIds
*out,cgrates.org,call,*any,2018-01-01T00:00:00Z,RP_TESTIT1,,
*out,cgrates.org,call,SPECIAL_1002,2014-01-14T00:00:00Z,RP_SPECIAL_1002,,
+*out,cgrates.org,customers,*any,2018-01-01T00:00:00Z,RP_ANY2CNT,,
+*out,cgrates.org,call,supplier1,2018-01-01T00:00:00Z,RP_ANY1CNT,,
+
diff --git a/engine/cdr.go b/engine/cdr.go
index 85ec3dd60..e1bdbcc27 100644
--- a/engine/cdr.go
+++ b/engine/cdr.go
@@ -105,6 +105,9 @@ func (cdr *CDR) AddDefaults(cfg *config.CGRConfig) {
if cdr.CGRID == "" {
cdr.ComputeCGRID()
}
+ if cdr.RunID == "" {
+ cdr.RunID = utils.MetaRaw
+ }
if cdr.ToR == "" {
cdr.ToR = utils.VOICE
}
@@ -117,6 +120,9 @@ func (cdr *CDR) AddDefaults(cfg *config.CGRConfig) {
if cdr.Category == "" {
cdr.Category = cfg.DefaultCategory
}
+ if cdr.Subject == "" {
+ cdr.Subject = cdr.Account
+ }
}
func (cdr *CDR) CostDetailsJson() string {
diff --git a/engine/cdrs.go b/engine/cdrs.go
index 9c1b2ad68..816f7a54d 100644
--- a/engine/cdrs.go
+++ b/engine/cdrs.go
@@ -468,7 +468,8 @@ func (self *CdrServer) getCostFromRater(cdr *CDR) (*CallCost, error) {
DurationIndex: cdr.Usage,
PerformRounding: true,
}
- if utils.IsSliceMember([]string{utils.META_PSEUDOPREPAID, utils.META_POSTPAID, utils.META_PREPAID, utils.PSEUDOPREPAID, utils.POSTPAID, utils.PREPAID}, cdr.RequestType) { // Prepaid - Cost can be recalculated in case of missing records from SM
+ if utils.IsSliceMember([]string{utils.META_PSEUDOPREPAID, utils.META_POSTPAID, utils.META_PREPAID,
+ utils.PSEUDOPREPAID, utils.POSTPAID, utils.PREPAID}, cdr.RequestType) { // Prepaid - Cost can be recalculated in case of missing records from SM
err = self.rals.Call("Responder.Debit", cd, cc)
} else {
err = self.rals.Call("Responder.GetCost", cd, cc)
@@ -694,7 +695,7 @@ func (cdrS *CdrServer) chrgrSProcessEvent(cgrEv *utils.CGREvent) {
return
}
var chrgrs []*ChrgSProcessEventReply
- if err := cdrS.chargerS.Call(utils.ChargerSv1ProcessEvent, cgrEv, &chrgrs); err == nil ||
+ if err := cdrS.chargerS.Call(utils.ChargerSv1ProcessEvent, cgrEv, &chrgrs); err != nil &&
err.Error() != utils.ErrNotFound.Error() {
utils.Logger.Warning(
fmt.Sprintf("<%s> error: %s processing CGR event %+v with %s.",
@@ -723,13 +724,13 @@ func (cdrS *CdrServer) chrgrSProcessEvent(cgrEv *utils.CGREvent) {
}
for _, cdr := range processedCDRs {
if cdrS.cgrCfg.CDRSStoreCdrs { // Store CDR
- go func() {
+ go func(cdr *CDR) {
if err := cdrS.cdrDb.SetCDR(cdr, true); err != nil {
utils.Logger.Warning(
fmt.Sprintf("<%s> error: %s storing CDR %+v.",
utils.CDRs, err.Error(), cdr))
}
- }()
+ }(cdr)
}
go cdrS.replicateCDRs([]*CDR{cdr}) // Replicate CDR
cgrEv := cdr.AsCGREvent()
@@ -753,6 +754,7 @@ func (cdrS *CdrServer) V2ProcessCDR(cgrEv *utils.CGREvent, reply *string) (err e
go cdrS.thdSProcessEvent(cgrEv)
go cdrS.statSProcessEvent(cgrEv)
+
go cdrS.chrgrSProcessEvent(cgrEv)
*reply = utils.OK
diff --git a/utils/consts.go b/utils/consts.go
index 9ae76681a..378898c3e 100755
--- a/utils/consts.go
+++ b/utils/consts.go
@@ -764,6 +764,11 @@ const (
CacheSv1Clear = "CacheSv1.Clear"
)
+// CdrsV2 APIs
+const (
+ CdrsV2ProcessCDR = "CdrsV2.ProcessCDR"
+)
+
// Scheduler
const (
SchedulerPing = "Scheduler.Ping"