From 5ce11a28a372bc7f0d517a7cd7bf4afd94abac6d Mon Sep 17 00:00:00 2001 From: DanB Date: Wed, 29 Apr 2015 19:50:03 +0200 Subject: [PATCH] Action *cdrlog to StorDb, moved GetCallCost and LogCallCost in CdrStorage, local tests for *cdrlog --- apier/v1/accounts.go | 10 +- apier/v1/apier.go | 19 +-- apier/v1/apier_local_test.go | 12 +- apier/v1/cdre.go | 2 +- apier/v1/cdrs.go | 2 +- cdre/cdrexporter.go | 8 +- cdre/cdrexporter_test.go | 3 +- cdre/csv_test.go | 6 +- cdre/fixedwidth_test.go | 6 +- cmd/cgr-engine/cgr-engine.go | 21 +-- console/account_add.go | 6 +- console/action_execute.go | 10 +- data/conf/samples/kamailio_evapi.cfg | 61 --------- .../samples/mediator1/mediator_test1.json | 26 ---- data/conf/samples/tutorial/tutorial.json | 35 ----- engine/action.go | 72 +++++++---- engine/actions_test.go | 5 +- engine/calldesc.go | 8 ++ engine/cdrs.go | 11 +- engine/cdrs_local_test.go | 2 - engine/mediator.go | 44 ------- engine/storage_interface.go | 4 +- general_tests/tutorial_local_test.go | 121 ------------------ sessionmanager/fssessionmanager.go | 10 +- sessionmanager/kamailiosm.go | 10 +- sessionmanager/session.go | 2 +- sessionmanager/sessionmanager.go | 2 +- utils/apitpdata.go | 21 +++ 28 files changed, 138 insertions(+), 401 deletions(-) delete mode 100644 data/conf/samples/kamailio_evapi.cfg delete mode 100644 data/conf/samples/mediator1/mediator_test1.json delete mode 100644 data/conf/samples/tutorial/tutorial.json delete mode 100644 engine/mediator.go delete mode 100644 general_tests/tutorial_local_test.go diff --git a/apier/v1/accounts.go b/apier/v1/accounts.go index 855bd3a24..eb5d2c68d 100644 --- a/apier/v1/accounts.go +++ b/apier/v1/accounts.go @@ -158,16 +158,8 @@ func (self *ApierV1) RemAccountActionTriggers(attrs AttrRemAcntActionTriggers, r return nil } -type AttrSetAccount struct { - Tenant string - Direction string - Account string - ActionPlanId string - AllowNegative bool -} - // Ads a new account into dataDb. If already defined, returns success. -func (self *ApierV1) SetAccount(attr AttrSetAccount, reply *string) error { +func (self *ApierV1) SetAccount(attr utils.AttrSetAccount, reply *string) error { if missing := utils.MissingStructFields(&attr, []string{"Tenant", "Direction", "Account"}); len(missing) != 0 { return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing) } diff --git a/apier/v1/apier.go b/apier/v1/apier.go index 0c64de7ff..6eea693bd 100644 --- a/apier/v1/apier.go +++ b/apier/v1/apier.go @@ -165,20 +165,13 @@ func (self *ApierV1) AddBalance(attr *AttrAddBalance, reply *string) error { return nil } -type AttrExecuteAction struct { - Direction string - Tenant string - Account string - ActionsId string -} - -func (self *ApierV1) ExecuteAction(attr *AttrExecuteAction, reply *string) error { +func (self *ApierV1) ExecuteAction(attr *utils.AttrExecuteAction, reply *string) error { + engine.Logger.Debug(fmt.Sprintf("Executing action, attrs: %+v", attr)) tag := fmt.Sprintf("%s:%s:%s", attr.Direction, attr.Tenant, attr.Account) at := &engine.ActionTiming{ AccountIds: []string{tag}, ActionsId: attr.ActionsId, } - if err := at.Execute(); err != nil { *reply = err.Error() return err @@ -516,13 +509,7 @@ func (self *ApierV1) SetRatingProfile(attrs AttrSetRatingProfile, reply *string) return nil } -type AttrSetActions struct { - ActionsId string // Actions id - Overwrite bool // If previously defined, will be overwritten - Actions []*utils.TPAction // Set of actions this Actions profile will perform -} - -func (self *ApierV1) SetActions(attrs AttrSetActions, reply *string) error { +func (self *ApierV1) SetActions(attrs utils.AttrSetActions, reply *string) error { if missing := utils.MissingStructFields(&attrs, []string{"ActionsId", "Actions"}); len(missing) != 0 { return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing) } diff --git a/apier/v1/apier_local_test.go b/apier/v1/apier_local_test.go index 15455600d..2eb845eb1 100644 --- a/apier/v1/apier_local_test.go +++ b/apier/v1/apier_local_test.go @@ -957,7 +957,7 @@ func TestApierExecuteAction(t *testing.T) { } reply := "" // Add balance to a previously known account - attrs := AttrExecuteAction{Direction: "*out", Tenant: "cgrates.org", Account: "dan2", ActionsId: "PREPAID_10"} + attrs := utils.AttrExecuteAction{Direction: "*out", Tenant: "cgrates.org", Account: "dan2", ActionsId: "PREPAID_10"} if err := rater.Call("ApierV1.ExecuteAction", attrs, &reply); err != nil { t.Error("Got error on ApierV1.ExecuteAction: ", err.Error()) } else if reply != "OK" { @@ -965,7 +965,7 @@ func TestApierExecuteAction(t *testing.T) { } reply2 := "" // Add balance to an account which does n exist - attrs = AttrExecuteAction{Direction: "*out", Tenant: "cgrates.org", Account: "dan2", ActionsId: "DUMMY_ACTION"} + attrs = utils.AttrExecuteAction{Direction: "*out", Tenant: "cgrates.org", Account: "dan2", ActionsId: "DUMMY_ACTION"} if err := rater.Call("ApierV1.ExecuteAction", attrs, &reply2); err == nil || reply2 == "OK" { t.Error("Expecting error on ApierV1.ExecuteAction.", err, reply2) } @@ -976,7 +976,7 @@ func TestApierSetActions(t *testing.T) { return } act1 := &utils.TPAction{Identifier: engine.TOPUP_RESET, BalanceType: utils.MONETARY, Direction: engine.OUTBOUND, Units: 75.0, ExpiryTime: engine.UNLIMITED, Weight: 20.0} - attrs1 := &AttrSetActions{ActionsId: "ACTS_1", Actions: []*utils.TPAction{act1}} + attrs1 := &utils.AttrSetActions{ActionsId: "ACTS_1", Actions: []*utils.TPAction{act1}} reply1 := "" if err := rater.Call("ApierV1.SetActions", attrs1, &reply1); err != nil { t.Error("Got error on ApierV1.SetActions: ", err.Error()) @@ -1093,14 +1093,14 @@ func TestApierSetAccount(t *testing.T) { return } reply := "" - attrs := &AttrSetAccount{Tenant: "cgrates.org", Direction: "*out", Account: "dan7", ActionPlanId: "ATMS_1"} + attrs := &utils.AttrSetAccount{Tenant: "cgrates.org", Direction: "*out", Account: "dan7", ActionPlanId: "ATMS_1"} if err := rater.Call("ApierV1.SetAccount", attrs, &reply); err != nil { t.Error("Got error on ApierV1.SetAccount: ", err.Error()) } else if reply != "OK" { t.Errorf("Calling ApierV1.SetAccount received: %s", reply) } reply2 := "" - attrs2 := new(AttrSetAccount) + attrs2 := new(utils.AttrSetAccount) *attrs2 = *attrs attrs2.ActionPlanId = "DUMMY_DATA" // Does not exist so it should error when adding triggers on it // Add account with actions timing which does not exist @@ -1193,7 +1193,7 @@ func TestApierTriggersExecute(t *testing.T) { return } reply := "" - attrs := &AttrSetAccount{Tenant: "cgrates.org", Direction: "*out", Account: "dan8"} + attrs := &utils.AttrSetAccount{Tenant: "cgrates.org", Direction: "*out", Account: "dan8"} if err := rater.Call("ApierV1.SetAccount", attrs, &reply); err != nil { t.Error("Got error on ApierV1.SetAccount: ", err.Error()) } else if reply != "OK" { diff --git a/apier/v1/cdre.go b/apier/v1/cdre.go index cb0bef28f..5c44950db 100644 --- a/apier/v1/cdre.go +++ b/apier/v1/cdre.go @@ -171,7 +171,7 @@ func (self *ApierV1) ExportCdrsToFile(attr utils.AttrExpFileCdrs, reply *utils.E *reply = utils.ExportedFileCdrs{ExportedFilePath: ""} return nil } - cdrexp, err := cdre.NewCdrExporter(cdrs, self.LogDb, exportTemplate, cdrFormat, fieldSep, exportId, dataUsageMultiplyFactor, smsUsageMultiplyFactor, + cdrexp, err := cdre.NewCdrExporter(cdrs, self.CdrDb, exportTemplate, cdrFormat, fieldSep, exportId, dataUsageMultiplyFactor, smsUsageMultiplyFactor, costMultiplyFactor, costShiftDigits, roundingDecimals, self.Config.RoundingDecimals, maskDestId, maskLen, self.Config.HttpSkipTlsVerify) if err != nil { return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) diff --git a/apier/v1/cdrs.go b/apier/v1/cdrs.go index 4b903831b..b5b79346f 100644 --- a/apier/v1/cdrs.go +++ b/apier/v1/cdrs.go @@ -35,7 +35,7 @@ func (apier *ApierV1) GetCallCostLog(attrs AttrGetCallCost, reply *engine.CallCo if missing := utils.MissingStructFields(&attrs, []string{"CgrId", "RunId"}); len(missing) != 0 { return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing) } - if cc, err := apier.LogDb.GetCallCostLog(attrs.CgrId, "", attrs.RunId); err != nil { + if cc, err := apier.CdrDb.GetCallCostLog(attrs.CgrId, "", attrs.RunId); err != nil { return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) } else if cc == nil { return fmt.Errorf("NOT_FOUND") diff --git a/cdre/cdrexporter.go b/cdre/cdrexporter.go index 952ba0203..9faa5109e 100644 --- a/cdre/cdrexporter.go +++ b/cdre/cdrexporter.go @@ -50,14 +50,14 @@ const ( var err error -func NewCdrExporter(cdrs []*engine.StoredCdr, logDb engine.LogStorage, exportTpl *config.CdreConfig, cdrFormat string, fieldSeparator rune, exportId string, +func NewCdrExporter(cdrs []*engine.StoredCdr, cdrDb engine.CdrStorage, 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 } cdre := &CdrExporter{ cdrs: cdrs, - logDb: logDb, + cdrDb: cdrDb, exportTemplate: exportTpl, cdrFormat: cdrFormat, fieldSeparator: fieldSeparator, @@ -81,7 +81,7 @@ func NewCdrExporter(cdrs []*engine.StoredCdr, logDb engine.LogStorage, exportTpl type CdrExporter struct { cdrs []*engine.StoredCdr - logDb engine.LogStorage // Used to extract cost_details if these are requested + cdrDb engine.CdrStorage // Used to extract cost_details if these are requested exportTemplate *config.CdreConfig cdrFormat string // csv, fwv fieldSeparator rune @@ -108,7 +108,7 @@ type CdrExporter struct { // Return Json marshaled callCost attached to // Keep it separately so we test only this part in local tests func (cdre *CdrExporter) getCdrCostDetails(cgrId, runId string) (string, error) { - cc, err := cdre.logDb.GetCallCostLog(cgrId, "", runId) + cc, err := cdre.cdrDb.GetCallCostLog(cgrId, "", runId) if err != nil { return "", err } else if cc == nil { diff --git a/cdre/cdrexporter_test.go b/cdre/cdrexporter_test.go index caf3604dd..214ea8937 100644 --- a/cdre/cdrexporter_test.go +++ b/cdre/cdrexporter_test.go @@ -28,7 +28,6 @@ import ( ) func TestCdreGetCombimedCdrFieldVal(t *testing.T) { - logDb, _ := engine.NewMapStorage() cfg, _ := config.NewDefaultCGRConfig() 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", @@ -52,7 +51,7 @@ func TestCdreGetCombimedCdrFieldVal(t *testing.T) { 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}, } - cdre, err := NewCdrExporter(cdrs, logDb, cfg.CdreProfiles["*default"], cfg.CdreProfiles["*default"].CdrFormat, cfg.CdreProfiles["*default"].FieldSeparator, + cdre, err := NewCdrExporter(cdrs, nil, cfg.CdreProfiles["*default"], cfg.CdreProfiles["*default"].CdrFormat, cfg.CdreProfiles["*default"].FieldSeparator, "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/csv_test.go b/cdre/csv_test.go index b309d4152..6169b875a 100644 --- a/cdre/csv_test.go +++ b/cdre/csv_test.go @@ -33,14 +33,13 @@ import ( func TestCsvCdrWriter(t *testing.T) { writer := &bytes.Buffer{} cfg, _ := config.NewDefaultCGRConfig() - logDb, _ := engine.NewMapStorage() 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([]*engine.StoredCdr{storedCdr1}, logDb, cfg.CdreProfiles["*default"], utils.CSV, ',', "firstexport", 0.0, 0.0, 0.0, 0, 4, + cdre, err := NewCdrExporter([]*engine.StoredCdr{storedCdr1}, nil, 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) @@ -62,14 +61,13 @@ func TestCsvCdrWriter(t *testing.T) { func TestAlternativeFieldSeparator(t *testing.T) { writer := &bytes.Buffer{} cfg, _ := config.NewDefaultCGRConfig() - logDb, _ := engine.NewMapStorage() 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([]*engine.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}, nil, 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 4336ceb4b..10179b526 100644 --- a/cdre/fixedwidth_test.go +++ b/cdre/fixedwidth_test.go @@ -102,7 +102,6 @@ var hdrCfgFlds, contentCfgFlds, trailerCfgFlds []*config.CfgCdrField func TestWriteCdr(t *testing.T) { var err error wrBuf := &bytes.Buffer{} - logDb, _ := engine.NewMapStorage() cfg, _ := config.NewDefaultCGRConfig() if hdrCfgFlds, err = config.CfgCdrFieldsFromCdrFieldsJsonCfg(hdrJsnCfgFlds); err != nil { t.Error(err) @@ -128,7 +127,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([]*engine.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}, nil, 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) } @@ -170,7 +169,6 @@ func TestWriteCdr(t *testing.T) { func TestWriteCdrs(t *testing.T) { wrBuf := &bytes.Buffer{} - logDb, _ := engine.NewMapStorage() cdreCfg := &config.CdreConfig{ CdrFormat: utils.CDRE_FIXED_WIDTH, HeaderFields: hdrCfgFlds, @@ -203,7 +201,7 @@ func TestWriteCdrs(t *testing.T) { ExtraFields: map[string]string{"productnumber": "12344", "fieldextr2": "valextr2"}, } cfg, _ := config.NewDefaultCGRConfig() - cdre, err := NewCdrExporter([]*engine.StoredCdr{cdr1, cdr2, cdr3, cdr4}, logDb, cdreCfg, utils.CDRE_FIXED_WIDTH, ',', + cdre, err := NewCdrExporter([]*engine.StoredCdr{cdr1, cdr2, cdr3, cdr4}, nil, 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/cmd/cgr-engine/cgr-engine.go b/cmd/cgr-engine/cgr-engine.go index fde8fa7e3..866233225 100644 --- a/cmd/cgr-engine/cgr-engine.go +++ b/cmd/cgr-engine/cgr-engine.go @@ -110,7 +110,7 @@ func startCdrc(cdrsChan chan struct{}, cdrcCfgs map[string]*config.CdrcConfig, h exitChan <- true // If run stopped, something is bad, stop the application } -func startSmFreeSWITCH(responder *engine.Responder, loggerDb engine.LogStorage, cacheChan chan struct{}) { +func startSmFreeSWITCH(responder *engine.Responder, cdrDb engine.CdrStorage, cacheChan chan struct{}) { var raterConn, cdrsConn engine.Connector var client *rpcclient.RpcClient delay := utils.Fib() @@ -154,14 +154,14 @@ func startSmFreeSWITCH(responder *engine.Responder, loggerDb engine.LogStorage, } cdrsConn = &engine.RPCClientConnector{Client: client} } - sm := sessionmanager.NewFSSessionManager(cfg.SmFsConfig, loggerDb, raterConn, cdrsConn) + sm := sessionmanager.NewFSSessionManager(cfg.SmFsConfig, cdrDb, raterConn, cdrsConn) if err = sm.Connect(); err != nil { engine.Logger.Err(fmt.Sprintf(" error: %s!", err)) } exitChan <- true } -func startSmKamailio(responder *engine.Responder, loggerDb engine.LogStorage, cacheChan chan struct{}) { +func startSmKamailio(responder *engine.Responder, cdrDb engine.CdrStorage, cacheChan chan struct{}) { var raterConn, cdrsConn engine.Connector var client *rpcclient.RpcClient if cfg.SmKamConfig.Rater == utils.INTERNAL { @@ -204,14 +204,14 @@ func startSmKamailio(responder *engine.Responder, loggerDb engine.LogStorage, ca } cdrsConn = &engine.RPCClientConnector{Client: client} } - sm, _ := sessionmanager.NewKamailioSessionManager(cfg.SmKamConfig, raterConn, cdrsConn, loggerDb) + sm, _ := sessionmanager.NewKamailioSessionManager(cfg.SmKamConfig, raterConn, cdrsConn, cdrDb) if err = sm.Connect(); err != nil { engine.Logger.Err(fmt.Sprintf(" error: %s!", err)) } exitChan <- true } -func startSmOpenSIPS(responder *engine.Responder, loggerDb engine.LogStorage, cacheChan chan struct{}) { +func startSmOpenSIPS(responder *engine.Responder, cdrDb engine.CdrStorage, cacheChan chan struct{}) { var raterConn, cdrsConn engine.Connector var client *rpcclient.RpcClient if cfg.SmOsipsConfig.Rater == utils.INTERNAL { @@ -310,7 +310,7 @@ func startCDRS(logDb engine.LogStorage, cdrDb engine.CdrStorage, responder *engi } } - cdrServer, _ = engine.NewCdrServer(cfg, logDb, cdrDb, raterConn, statsConn) + cdrServer, _ = engine.NewCdrServer(cfg, cdrDb, raterConn, statsConn) engine.Logger.Info("Registering CDRS HTTP Handlers.") cdrServer.RegisterHanlersToServer(server) engine.Logger.Info("Registering CDRS RPC service.") @@ -476,7 +476,7 @@ func main() { defer accountDb.Close() engine.SetAccountingStorage(accountDb) } - if cfg.RaterEnabled || cfg.CDRSEnabled { // Only connect to storDb if necessary + if cfg.RaterEnabled || cfg.CDRSEnabled || cfg.SchedulerEnabled { // Only connect to storDb if necessary if cfg.StorDBType == SAME { logDb = ratingDb.(engine.LogStorage) } else { @@ -492,6 +492,7 @@ func main() { // loadDb,cdrDb and logDb are all mapped on the same stordb storage loadDb = logDb.(engine.LoadStorage) cdrDb = logDb.(engine.CdrStorage) + engine.SetCdrStorage(cdrDb) } engine.SetRoundingDecimals(cfg.RoundingDecimals) @@ -611,17 +612,17 @@ func main() { if cfg.SmFsConfig.Enabled { engine.Logger.Info("Starting CGRateS SM-FreeSWITCH service.") - go startSmFreeSWITCH(responder, logDb, cacheChan) + go startSmFreeSWITCH(responder, cdrDb, cacheChan) // close all sessions on shutdown go shutdownSessionmanagerSingnalHandler() } if cfg.SmKamConfig.Enabled { engine.Logger.Info("Starting CGRateS SM-Kamailio service.") - go startSmKamailio(responder, logDb, cacheChan) + go startSmKamailio(responder, cdrDb, cacheChan) } if cfg.SmOsipsConfig.Enabled { engine.Logger.Info("Starting CGRateS SM-OpenSIPS service.") - go startSmOpenSIPS(responder, logDb, cacheChan) + go startSmOpenSIPS(responder, cdrDb, cacheChan) } var cdrcEnabled bool for _, cdrcCfgs := range cfg.CdrcProfiles { diff --git a/console/account_add.go b/console/account_add.go index 783de6732..605226e3a 100644 --- a/console/account_add.go +++ b/console/account_add.go @@ -18,7 +18,7 @@ along with this program. If not, see package console -import "github.com/cgrates/cgrates/apier/v1" +import "github.com/cgrates/cgrates/utils" func init() { c := &CmdAddAccount{ @@ -33,7 +33,7 @@ func init() { type CmdAddAccount struct { name string rpcMethod string - rpcParams *v1.AttrSetAccount + rpcParams *utils.AttrSetAccount *CommandExecuter } @@ -47,7 +47,7 @@ func (self *CmdAddAccount) RpcMethod() string { func (self *CmdAddAccount) RpcParams() interface{} { if self.rpcParams == nil { - self.rpcParams = &v1.AttrSetAccount{Direction: "*out"} + self.rpcParams = &utils.AttrSetAccount{Direction: utils.OUT} } return self.rpcParams } diff --git a/console/action_execute.go b/console/action_execute.go index d649e62f6..79dd3b5af 100644 --- a/console/action_execute.go +++ b/console/action_execute.go @@ -18,13 +18,15 @@ along with this program. If not, see package console -import "github.com/cgrates/cgrates/apier/v1" +import ( + "github.com/cgrates/cgrates/utils" +) func init() { c := &CmdExecuteAction{ name: "action_execute", rpcMethod: "ApierV1.ExecuteAction", - rpcParams: &v1.AttrExecuteAction{Direction: "*out"}, + rpcParams: &utils.AttrExecuteAction{Direction: utils.OUT}, } commands[c.Name()] = c c.CommandExecuter = &CommandExecuter{c} @@ -34,7 +36,7 @@ func init() { type CmdExecuteAction struct { name string rpcMethod string - rpcParams *v1.AttrExecuteAction + rpcParams *utils.AttrExecuteAction *CommandExecuter } @@ -48,7 +50,7 @@ func (self *CmdExecuteAction) RpcMethod() string { func (self *CmdExecuteAction) RpcParams() interface{} { if self.rpcParams == nil { - self.rpcParams = &v1.AttrExecuteAction{Direction: "*out"} + self.rpcParams = &utils.AttrExecuteAction{Direction: utils.OUT} } return self.rpcParams } diff --git a/data/conf/samples/kamailio_evapi.cfg b/data/conf/samples/kamailio_evapi.cfg deleted file mode 100644 index 5817cfc55..000000000 --- a/data/conf/samples/kamailio_evapi.cfg +++ /dev/null @@ -1,61 +0,0 @@ -# Real-time Charging System for Telecom & ISP environments -# Copyright (C) ITsysCOM GmbH -# -# This file contains the default configuration hardcoded into CGRateS. -# This is what you get when you load CGRateS with an empty configuration file. - -[global] -rpc_json_listen = :2012 # RPC JSON listening address - -[rater] -enabled = true # Enable RaterCDRSExportPath service: . - -[scheduler] -enabled = true # Starts Scheduler service: . - -[cdrs] -enabled = true # Start the CDR Server service: . -mediator = internal # Address where to reach the Mediator. Empty for disabling mediation. <""|internal> -# cdrstats = # Address where to reach the cdrstats service: - -[mediator] -enabled = true # Starts Mediator service: . -# rater = internal # Address where to reach the Rater: -# cdrstats = internal # Address where to reach the cdrstats service: - -[cdrstats] -enabled = true # Starts the cdrstats service: -#queue_length = 50 # Number of items in the stats buffer -time_window = 1h # Will only keep the CDRs who's call setup time is not older than time.Now()-TimeWindow -# metrics = ASR, ACD, ACC # Stat metric ids to build -# setup_interval = # Filter on CDR SetupTime -# tors = # Filter on CDR TOR fields -# cdr_hosts= # Filter on CDR CdrHost fields -# cdr_sources = # Filter on CDR CdrSource fields -# req_types = # Filter on CDR ReqType fields -# directions = # Filter on CDR Direction fields -# tenants = # Filter on CDR Tenant fields -# categories = # Filter on CDR Category fields -# accounts = # Filter on CDR Account fields -# subjects = # Filter on CDR Subject fields -# destination_prefixes = # Filter on CDR Destination prefixes -# usage_interval = # Filter on CDR Usage -# mediation_run_ids = # Filter on CDR MediationRunId fields -# rated_accounts = # Filter on CDR RatedAccount fields -# rated_subjects = # Filter on CDR RatedSubject fields -# cost_intervals = # Filter on CDR Cost - -[session_manager] -enabled = true # Starts SessionManager service: -switch_type = kamailio # Defines the type of switch behind: -cdrs = internal - -[kamailio] -# evapi_addr = 127.0.0.1:8448 # Address of the kamailio evapi server -# reconnects = 3 # Number of attempts on connect failure. - -[mailer] -# server = localhost # The server to use when sending emails out -# auth_user = cgrates # Authenticate to email server using this user -# auth_passwd = CGRateS.org # Authenticate to email server with this password -# from_address = cgr-mailer@localhost.localdomain # From address used when sending emails out diff --git a/data/conf/samples/mediator1/mediator_test1.json b/data/conf/samples/mediator1/mediator_test1.json deleted file mode 100644 index d02f64603..000000000 --- a/data/conf/samples/mediator1/mediator_test1.json +++ /dev/null @@ -1,26 +0,0 @@ -{ -// CGRateS Configuration file -// -// Used in mediator_local_test -// Starts rater, cdrs and mediator connecting over internal channel - -"rater": { - "enabled": true, // enable Rater service: -}, - -"scheduler": { - "enabled": true, // start Scheduler service: -}, - -"cdrs": { - "enabled": true, // start the CDR Server service: - "rater": "internal", // address where to reach the Rater for cost calculation, empty to disable functionality: <""|internal|x.y.z.y:1234> -}, - -"cdre": { - "*default": { - "export_dir": "/tmp/cgrates/cdr/cdrexport/csv", // path where the exported CDRs will be placed - } -}, - -} \ No newline at end of file diff --git a/data/conf/samples/tutorial/tutorial.json b/data/conf/samples/tutorial/tutorial.json deleted file mode 100644 index 980260c77..000000000 --- a/data/conf/samples/tutorial/tutorial.json +++ /dev/null @@ -1,35 +0,0 @@ -{ -// CGRateS Configuration file -// -// Used in mediator_local_test -// Starts rater, cdrs and mediator connecting over internal channel - -"rater": { - "enabled": true, // enable Rater service: -}, - -"scheduler": { - "enabled": true, // start Scheduler service: -}, - -"cdrs": { - "enabled": true, // start the CDR Server service: - "mediator": "internal", // address where to reach the Mediator. -}, - -"cdre": { - "*default": { - "export_dir": "/tmp", // path where the exported CDRs will be placed - } -}, - -"mediator": { - "enabled": true, // starts Mediator service: . - "cdrstats": "internal", -}, - -"cdrstats": { - "enabled": true, // starts the cdrstats service: -}, - -} \ No newline at end of file diff --git a/engine/action.go b/engine/action.go index 1d942d425..206f3666b 100644 --- a/engine/action.go +++ b/engine/action.go @@ -129,11 +129,10 @@ func logAction(ub *Account, sq *StatsQueueTriggered, a *Action, acs Actions) (er } func cdrLogAction(acc *Account, sq *StatsQueueTriggered, a *Action, acs Actions) (err error) { - tor, _ := utils.NewRSRField("^tor_test") - cdrhost, _ := utils.NewRSRField("^127.0.0.1") defaultTemplate := map[string]*utils.RSRField{ - "TOR": tor, - "CdrHost": cdrhost, + "CdrHost": utils.ParseRSRFieldsMustCompile("^127.0.0.1", utils.INFIELD_SEP)[0], + "ReqType": utils.ParseRSRFieldsMustCompile("^"+utils.META_PREPAID, utils.INFIELD_SEP)[0], + "MediationRunId": utils.ParseRSRFieldsMustCompile("^"+utils.META_DEFAULT, utils.INFIELD_SEP)[0], } template := make(map[string]string) @@ -143,38 +142,61 @@ func cdrLogAction(acc *Account, sq *StatsQueueTriggered, a *Action, acs Actions) return } for field, rsr := range template { - if rsrField, err := utils.NewRSRField(rsr); err == nil { - defaultTemplate[field] = rsrField - } else { + defaultTemplate[field], err = utils.NewRSRField(rsr) + if err != nil { return err } } } - // set sored cdr values + // set stored cdr values var cdrs []*StoredCdr for _, action := range acs { - if action.ActionType == DEBIT || action.ActionType == DEBIT_RESET { - cdr := &StoredCdr{CdrSource: CDRLOG, SetupTime: time.Now(), AnswerTime: time.Now(), AccId: utils.GenUUID()} - cdr.CgrId = utils.Sha1(cdr.AccId, cdr.SetupTime.String()) - elem := reflect.ValueOf(cdr).Elem() - for key, rsr := range defaultTemplate { - field := elem.FieldByName(key) - if field.IsValid() && field.CanSet() { - switch field.Kind() { - case reflect.Float64: - value, err := strconv.ParseFloat(rsr.ParseValue(""), 64) - if err != nil { - continue - } - field.SetFloat(value) - case reflect.String: - field.SetString(rsr.ParseValue("")) + if !utils.IsSliceMember([]string{DEBIT, DEBIT_RESET}, action.ActionType) { + continue // Only log specific actions + } + cdr := &StoredCdr{CdrSource: CDRLOG, SetupTime: time.Now(), AnswerTime: time.Now(), AccId: utils.GenUUID()} + cdr.CgrId = utils.Sha1(cdr.AccId, cdr.SetupTime.String()) + cdr.Usage = time.Duration(1) * time.Second + elem := reflect.ValueOf(cdr).Elem() + for key, rsr := range defaultTemplate { + field := elem.FieldByName(key) + if field.IsValid() && field.CanSet() { + switch field.Kind() { + case reflect.Float64: + value, err := strconv.ParseFloat(rsr.ParseValue(""), 64) + if err != nil { + continue } + field.SetFloat(value) + case reflect.String: + field.SetString(rsr.ParseValue("")) } } - cdrs = append(cdrs, cdr) } + // Hardcode the data for now, expand it with templates later + cdr.TOR = action.BalanceType + cdr.Direction = action.Direction + if action.Balance != nil { + cdr.Cost = action.Balance.Value + } + Logger.Debug(fmt.Sprintf("action: %+v, balance: %+v", action, action.Balance)) + cdrs = append(cdrs, cdr) + if cdrStorage == nil { // Only save if the cdrStorage is defined + continue + } + Logger.Debug(fmt.Sprintf("SetCdr: %+v\n", cdr)) + if err := cdrStorage.SetCdr(cdr); err != nil { + return err + } + if err := cdrStorage.SetRatedCdr(cdr); err != nil { + return err + } + // FixMe + //if err := cdrStorage.LogCallCost(); err != nil { + // return err + //} + } b, _ := json.Marshal(cdrs) diff --git a/engine/actions_test.go b/engine/actions_test.go index 7a4374174..9f3d367b6 100644 --- a/engine/actions_test.go +++ b/engine/actions_test.go @@ -1,5 +1,5 @@ /* -Rating system designed to be used in VoIP Carriers World +Real-time Charging System for Telecom & ISP environments Copyright (C) 2012-2015 ITsysCOM This program is free software: you can redistribute it and/or modify @@ -1126,7 +1126,7 @@ func TestActionCdrlogEmpty(t *testing.T) { } cdrs := make([]*StoredCdr, 0) json.Unmarshal([]byte(cdrlog.ExpirationString), &cdrs) - if len(cdrs) != 1 || cdrs[0].TOR != "tor_test" { + if len(cdrs) != 1 || cdrs[0].CdrSource != CDRLOG { t.Errorf("Wrong cdrlogs: %+v", cdrs[0]) } } @@ -1150,7 +1150,6 @@ func TestActionCdrlogWithParams(t *testing.T) { cdrs := make([]*StoredCdr, 0) json.Unmarshal([]byte(cdrlog.ExpirationString), &cdrs) if len(cdrs) != 2 || - cdrs[0].TOR != "tor_test" || cdrs[0].Subject != "rif" { t.Errorf("Wrong cdrlogs: %+v", cdrs[0]) } diff --git a/engine/calldesc.go b/engine/calldesc.go index 092e797da..0eb6de6e5 100644 --- a/engine/calldesc.go +++ b/engine/calldesc.go @@ -64,6 +64,7 @@ var ( dataStorage RatingStorage accountingStorage AccountingStorage storageLogger LogStorage + cdrStorage CdrStorage debitPeriod = 10 * time.Second globalRoundingDecimals = 10 historyScribe history.Scribe @@ -91,6 +92,13 @@ func SetStorageLogger(sg LogStorage) { storageLogger = sg } +/* +Sets the database for CDR storing, used by *cdrlog in first place +*/ +func SetCdrStorage(cStorage CdrStorage) { + cdrStorage = cStorage +} + // Exported method to set the history scribe. func SetHistoryScribe(scribe history.Scribe) { historyScribe = scribe diff --git a/engine/cdrs.go b/engine/cdrs.go index 4ae360fd0..3f10a6dd0 100644 --- a/engine/cdrs.go +++ b/engine/cdrs.go @@ -53,8 +53,8 @@ func fsCdrHandler(w http.ResponseWriter, r *http.Request) { } } -func NewCdrServer(cgrCfg *config.CGRConfig, logDb LogStorage, cdrDb CdrStorage, rater Connector, stats StatsInterface) (*CdrServer, error) { - return &CdrServer{cgrCfg: cgrCfg, logDb: logDb, cdrDb: cdrDb, rater: rater, stats: stats}, nil +func NewCdrServer(cgrCfg *config.CGRConfig, cdrDb CdrStorage, rater Connector, stats StatsInterface) (*CdrServer, error) { + return &CdrServer{cgrCfg: cgrCfg, cdrDb: cdrDb, rater: rater, stats: stats}, nil /* if cfg.CDRSStats != "" { if cfg.CDRSStats != utils.INTERNAL { @@ -73,7 +73,6 @@ func NewCdrServer(cgrCfg *config.CGRConfig, logDb LogStorage, cdrDb CdrStorage, type CdrServer struct { cgrCfg *config.CGRConfig - logDb LogStorage cdrDb CdrStorage rater Connector stats StatsInterface @@ -150,7 +149,7 @@ func (self *CdrServer) rateStoreStatsReplicate(storedCdr *StoredCdr) (err error) } // Store CostDetails if cdr.Rated || utils.IsSliceMember([]string{utils.RATED, utils.META_RATED}, cdr.ReqType) { // Account related CDRs are saved automatically, so save the others here if requested - if err := self.logDb.LogCallCost(cdr.CgrId, utils.CDRS_SOURCE, cdr.MediationRunId, storedCdr.CostDetails); err != nil { + if err := self.cdrDb.LogCallCost(cdr.CgrId, utils.CDRS_SOURCE, cdr.MediationRunId, storedCdr.CostDetails); err != nil { Logger.Err(fmt.Sprintf(" Storing costs for CDR %+v, costDetails: %+v, got error: %s", cdr, cdr.CostDetails, err.Error())) } } @@ -191,7 +190,7 @@ func (self *CdrServer) deriveAndRateCdr(storedCdr *StoredCdr) ([]*StoredCdr, err // Retrive the cost from logging database, nil in case of no log func (self *CdrServer) getCostsFromDB(cgrid, runId string) (cc *CallCost, err error) { for i := 0; i < 3; i++ { // Mechanism to avoid concurrency between SessionManager writing the costs and mediator picking them up - cc, err = self.logDb.GetCallCostLog(cgrid, SESSION_MANAGER_SOURCE, runId) + cc, err = self.cdrDb.GetCallCostLog(cgrid, SESSION_MANAGER_SOURCE, runId) if cc != nil { break } @@ -221,7 +220,7 @@ func (self *CdrServer) getCostFromRater(storedCdr *StoredCdr) (*CallCost, error) } if utils.IsSliceMember([]string{utils.META_PSEUDOPREPAID, utils.META_POSTPAID, utils.PSEUDOPREPAID, utils.POSTPAID}, storedCdr.ReqType) { if err = self.rater.Debit(cd, cc); err == nil { // Debit has occured, we are forced to write the log, even if CDR store is disabled - self.logDb.LogCallCost(storedCdr.CgrId, MEDIATOR_SOURCE, storedCdr.MediationRunId, cc) + self.cdrDb.LogCallCost(storedCdr.CgrId, MEDIATOR_SOURCE, storedCdr.MediationRunId, cc) } } else { err = self.rater.GetCost(cd, cc) diff --git a/engine/cdrs_local_test.go b/engine/cdrs_local_test.go index a53a4eda9..0f54eddff 100644 --- a/engine/cdrs_local_test.go +++ b/engine/cdrs_local_test.go @@ -19,7 +19,6 @@ along with this program. If not, see package engine import ( - "fmt" "path" "reflect" "testing" @@ -112,7 +111,6 @@ func TestCdrsHttpJsonRpcCdrReplication(t *testing.T) { } else { rcvSetupTime, _ := utils.ParseTimeDetectLayout(rcvedCdrs[0].SetupTime) rcvAnswerTime, _ := utils.ParseTimeDetectLayout(rcvedCdrs[0].AnswerTime) - fmt.Printf("rcv: %+v, answer: %+v", rcvSetupTime, rcvAnswerTime) rcvUsage, _ := utils.ParseDurationWithSecs(rcvedCdrs[0].Usage) if rcvedCdrs[0].CgrId != testCdr1.CgrId || rcvedCdrs[0].TOR != testCdr1.TOR || diff --git a/engine/mediator.go b/engine/mediator.go deleted file mode 100644 index dfcc6bff3..000000000 --- a/engine/mediator.go +++ /dev/null @@ -1,44 +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 engine - -/* -func NewMediator(connector Connector, logDb LogStorage, cdrDb CdrStorage, st StatsInterface, cfg *config.CGRConfig) (m *Mediator, err error) { - m = &Mediator{ - connector: connector, - logDb: logDb, - cdrDb: cdrDb, - stats: st, - cgrCfg: cfg, - } - if m.cgrCfg.MediatorStats != "" { - if m.cgrCfg.MediatorStats != utils.INTERNAL { - if s, err := NewProxyStats(m.cgrCfg.MediatorStats); err == nil { - m.stats = s - } else { - Logger.Err(fmt.Sprintf("Errors connecting to CDRS stats service (mediator): %s", err.Error())) - } - } - } else { - // disable stats for mediator - m.stats = nil - } - return m, nil -} -*/ diff --git a/engine/storage_interface.go b/engine/storage_interface.go index b389436a7..820e8c8d7 100644 --- a/engine/storage_interface.go +++ b/engine/storage_interface.go @@ -114,6 +114,8 @@ type CdrStorage interface { Storage SetCdr(*StoredCdr) error SetRatedCdr(*StoredCdr) error + LogCallCost(cgrid, source, runid string, cc *CallCost) error + GetCallCostLog(cgrid, source, runid string) (*CallCost, error) GetStoredCdrs(*utils.CdrsFilter) ([]*StoredCdr, int64, error) RemStoredCdrs([]string) error } @@ -121,11 +123,9 @@ type CdrStorage interface { type LogStorage interface { Storage //GetAllActionTimingsLogs() (map[string]ActionsTimings, error) - LogCallCost(cgrid, source, runid string, cc *CallCost) error LogError(uuid, source, runid, errstr string) error LogActionTrigger(ubId, source string, at *ActionTrigger, as Actions) error LogActionTiming(source string, at *ActionTiming, as Actions) error - GetCallCostLog(cgrid, source, runid string) (*CallCost, error) } type LoadStorage interface { diff --git a/general_tests/tutorial_local_test.go b/general_tests/tutorial_local_test.go deleted file mode 100644 index 8bb644800..000000000 --- a/general_tests/tutorial_local_test.go +++ /dev/null @@ -1,121 +0,0 @@ -/* -Real-time Charging System for Telecom & ISP environments -Copyright (C) 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 general_tests - -import ( - "net/rpc" - "net/rpc/jsonrpc" - "os/exec" - "path" - "testing" - "time" - - "github.com/cgrates/cgrates/config" - "github.com/cgrates/cgrates/engine" - "github.com/cgrates/cgrates/utils" -) - -var tutCfgPath string -var tutCfg *config.CGRConfig -var tutRpc *rpc.Client - -func TestInitCfg(t *testing.T) { - if !*testLocal { - return - } - // Init config first - tutCfgPath = path.Join(*dataDir, "conf", "samples", "tutorial") - var err error - tutCfg, err = config.NewCGRConfigFromFolder(tutCfgPath) - if err != nil { - t.Error(err) - } - tutCfg.DataFolderPath = *dataDir // Share DataFolderPath through config towards StoreDb for Flush() - config.SetCgrConfig(tutCfg) -} - -func TestTutLclResetDb(t *testing.T) { - if !*testLocal { - return - } - if err := engine.InitStorDb(tutCfg); err != nil { - t.Fatal(err) - } -} - -func TestTutLclResetDataDb(t *testing.T) { - if !*testLocal { - return - } - if err := engine.InitDataDb(tutCfg); err != nil { - t.Fatal(err) - } -} - -func TestTutLclStartEngine(t *testing.T) { - if !*testLocal { - return - } - enginePath, err := exec.LookPath("cgr-engine") - if err != nil { - t.Fatal("Cannot find cgr-engine executable") - } - exec.Command("pkill", "cgr-engine").Run() // Just to make sure another one is not running, bit brutal maybe we can fine tune it - time.Sleep(time.Duration(*waitRater) * time.Millisecond) - engine := exec.Command(enginePath, "-config_dir", tutCfgPath) - if err := engine.Start(); err != nil { - t.Fatal(err) - } - time.Sleep(time.Duration(*waitRater) * time.Millisecond) // Give time to rater to fire up -} - -// Connect rpc client to rater -func TestTutLclRpcConn(t *testing.T) { - if !*testLocal { - return - } - var err error - tutRpc, err = jsonrpc.Dial("tcp", tutCfg.RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed - if err != nil { - t.Fatal(err) - } -} - -func TestTutLclLoadTariffPlanFromFolder(t *testing.T) { - if !*testLocal { - return - } - reply := "" - attrs := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "tutorial")} - if err := tutRpc.Call("ApierV1.LoadTariffPlanFromFolder", attrs, &reply); err != nil { - t.Error(err) - } else if reply != "OK" { - t.Error(reply) - } - time.Sleep(time.Duration(*waitRater) * time.Millisecond) // Give time for scheduler to execute topups - -} - -func TestShutdown(t *testing.T) { - if !*testLocal { - return - } - exec.Command("pkill", "cgr-engine").Run() // Just to make sure another one is not running, bit brutal maybe we can fine tune it - time.Sleep(time.Duration(*waitRater) * time.Millisecond) -} diff --git a/sessionmanager/fssessionmanager.go b/sessionmanager/fssessionmanager.go index 57556d0ea..1d4c532bd 100644 --- a/sessionmanager/fssessionmanager.go +++ b/sessionmanager/fssessionmanager.go @@ -38,11 +38,11 @@ type FSSessionManager struct { sessions []*Session rater engine.Connector cdrs engine.Connector - loggerDB engine.LogStorage + cdrDb engine.CdrStorage } -func NewFSSessionManager(smFsConfig *config.SmFsConfig, storage engine.LogStorage, rater, cdrs engine.Connector) *FSSessionManager { - return &FSSessionManager{cfg: smFsConfig, conns: make(map[string]*fsock.FSock), loggerDB: storage, rater: rater, cdrs: cdrs} +func NewFSSessionManager(smFsConfig *config.SmFsConfig, storage engine.CdrStorage, rater, cdrs engine.Connector) *FSSessionManager { + return &FSSessionManager{cfg: smFsConfig, conns: make(map[string]*fsock.FSock), cdrDb: storage, rater: rater, cdrs: cdrs} } // Connects to the freeswitch mod_event_socket server and starts @@ -264,8 +264,8 @@ func (sm *FSSessionManager) ProcessCdr(storedCdr *engine.StoredCdr) error { func (sm *FSSessionManager) DebitInterval() time.Duration { return sm.cfg.DebitInterval } -func (sm *FSSessionManager) DbLogger() engine.LogStorage { - return sm.loggerDB +func (sm *FSSessionManager) CdrDb() engine.CdrStorage { + return sm.cdrDb } func (sm *FSSessionManager) Rater() engine.Connector { diff --git a/sessionmanager/kamailiosm.go b/sessionmanager/kamailiosm.go index 24d946b13..d2a36654c 100644 --- a/sessionmanager/kamailiosm.go +++ b/sessionmanager/kamailiosm.go @@ -30,8 +30,8 @@ import ( "time" ) -func NewKamailioSessionManager(smKamCfg *config.SmKamConfig, rater, cdrsrv engine.Connector, loggerDb engine.LogStorage) (*KamailioSessionManager, error) { - ksm := &KamailioSessionManager{cfg: smKamCfg, rater: rater, cdrsrv: cdrsrv, loggerDb: loggerDb, conns: make(map[string]*kamevapi.KamEvapi)} +func NewKamailioSessionManager(smKamCfg *config.SmKamConfig, rater, cdrsrv engine.Connector, cdrDb engine.CdrStorage) (*KamailioSessionManager, error) { + ksm := &KamailioSessionManager{cfg: smKamCfg, rater: rater, cdrsrv: cdrsrv, cdrDb: cdrDb, conns: make(map[string]*kamevapi.KamEvapi)} return ksm, nil } @@ -39,7 +39,7 @@ type KamailioSessionManager struct { cfg *config.SmKamConfig rater engine.Connector cdrsrv engine.Connector - loggerDb engine.LogStorage + cdrDb engine.CdrStorage conns map[string]*kamevapi.KamEvapi sessions []*Session } @@ -163,8 +163,8 @@ func (self *KamailioSessionManager) GetSession(uuid string) *Session { func (self *KamailioSessionManager) DebitInterval() time.Duration { return self.cfg.DebitInterval } -func (self *KamailioSessionManager) DbLogger() engine.LogStorage { - return self.loggerDb +func (self *KamailioSessionManager) CdrDb() engine.CdrStorage { + return self.cdrDb } func (self *KamailioSessionManager) Rater() engine.Connector { return self.rater diff --git a/sessionmanager/session.go b/sessionmanager/session.go index d09169cd1..e5b710c12 100644 --- a/sessionmanager/session.go +++ b/sessionmanager/session.go @@ -204,6 +204,6 @@ func (s *Session) SaveOperations() { for _, cc := range sr.CallCosts[1:] { firstCC.Merge(cc) } - s.sessionManager.DbLogger().LogCallCost(s.eventStart.GetCgrId(), engine.SESSION_MANAGER_SOURCE, sr.DerivedCharger.RunId, firstCC) + s.sessionManager.CdrDb().LogCallCost(s.eventStart.GetCgrId(), engine.SESSION_MANAGER_SOURCE, sr.DerivedCharger.RunId, firstCC) } } diff --git a/sessionmanager/sessionmanager.go b/sessionmanager/sessionmanager.go index 7b82e4733..ce101ac72 100644 --- a/sessionmanager/sessionmanager.go +++ b/sessionmanager/sessionmanager.go @@ -25,7 +25,7 @@ import ( ) type SessionManager interface { - DbLogger() engine.LogStorage + CdrDb() engine.CdrStorage Rater() engine.Connector DebitInterval() time.Duration Connect() error diff --git a/utils/apitpdata.go b/utils/apitpdata.go index 0d7c15d05..f39c6e538 100644 --- a/utils/apitpdata.go +++ b/utils/apitpdata.go @@ -1115,3 +1115,24 @@ func (self *RpcCdrsFilter) AsCdrsFilter() (*CdrsFilter, error) { } return cdrFltr, nil } + +type AttrSetActions struct { + ActionsId string // Actions id + Overwrite bool // If previously defined, will be overwritten + Actions []*TPAction // Set of actions this Actions profile will perform +} + +type AttrExecuteAction struct { + Direction string + Tenant string + Account string + ActionsId string +} + +type AttrSetAccount struct { + Tenant string + Direction string + Account string + ActionPlanId string + AllowNegative bool +}